openvibers/openvibe.contracts Commits
Watch contracts, events, capabilities and placeholder service manifest (planned); document runtime:<class>; release 0.102.0 (#47)
Changes
@@@ -4,6 +4,28 @@ All notable changes to `openvibe-contracts`. Releases are git tags (`vX.Y.Z`) thfrom `https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/<tag>`. Before v0.30.0,the notes were in the tag and commit messages (`git tag -n1`).++## 0.102.0 — 2026-10-05++++**The Watch contracts** (plan T18). Additive: eight new planned contracts, four planned capabilities and the Watch placeholder manifest, no existing schema changed.++- `watch.watch@1` (new, owner `watch`, first-party, **planned**): a user-defined persistent observation — a source (a push event, a++ webhook, a conditional HTTP URL, a feed or API, a local Node probe, or a Run check), how a value is extracted, how it is compared with++ the last observation, the condition that fires, the actions it wakes (notification, event, webhook, Actor task, Codes run, Run job),++ its budget and retention. Valid and invalid fixtures in `fixtures/watch.watch/`.++- `watch.watch-request@1` (the create/patch body), `watch.watch-result@1` (the list/watch and pause/resume/delete answers),++ `watch.observation@1` (one recorded value, immutable) and `watch.check-run@1` (one check execution, immutable, with the twelve++ terminal states the service's `check_runs.state` CHECK allows), each with fixtures. The request reuses `watch.watch@1`'s `$defs`++ rather than restating the source and condition shapes.++- Events: `watch.observation.recorded` (subject `watch`, internal, low), `watch.watch.triggered` (internal, important; Network turns++ it into a `WATCH_TRIGGERED` notification for `payload.recipient`) and `watch.check.failed` (internal, normal, with++ `consecutive_failures`). **The dossier's `watch.triggered` is named `watch.watch.triggered` here**: the repo's event-type pattern++ (`test/run.js:123`) requires at least three dot-separated segments, as every existing type has.++- Capabilities `watch.watch.read`, `watch.watch.manage`, `watch.observation.read` and `watch.check.run` (all planned, first-party),++ and `manifests/services/watch.json`, a placeholder like Run's: the OpenVibe.Watch repository does not exist yet, so nothing is++ built. `manifests/products/openvibe.watch.json` now names `watch` as its service, as `openvibe.run` names `run`.++- `contracts/platform/resource-offer.v1.json`: the `capabilities` description now documents `runtime:<class>` for a kind harness++ beside the reserved `worker:<class>` names (a docs-only change; Codes already advertises them). `lib/ids.js` already carried++ `watch`/`observation`/`check`, so it is untouched.++## 0.101.0 — 2026-10-05**The task contract** (plan T17, ADR-044). Additive: one new planned contract and its ADR, no existing schema changed.@@@ -3,11 +3,13 @@"stage": "alpha","code": true,"wave": "W1",-- "dependsOn": ["OpenVibe.Network"],++ "dependsOn": [++ "OpenVibe.Network"++ ],"plan": "OpenVibe Development Roadmap (combined), Wave 1; implementation plan rev 3 section 3.1","deployed": false,"deployment": "none of its own: a library and artifact repository published as release tags; services pin a tag and deploy it with their own releases",-- "contracts": "openvibe-contracts v0.101.0 (this package; the newest tag)",++ "contracts": "openvibe-contracts v0.102.0 (this package; the newest tag)","features": ["589 JSON Schemas with valid and invalid fixtures","31 service manifests with lifecycle declarations",@@@ -20,7 +22,8 @@"documentation-currency check (scripts/docs-currency.js)","generated estate: docs/ESTATE.md and manifests/repositories/ from the checkouts (scripts/estate.js; --check fails on drift)","chat.ticket-conversation@1 and the planned chat.ticket.write capability: a per-ticket conversation keyed by ticket id and calling service, with author_kind person|agent|staff",-- "platform.task@1 (planned, owner network) and ADR-044: one task at OpenVibe.Actor's router with a mode, a per-task and per-day budget, result, cost and explanation, SSE progress, cancel and webhooks"++ "platform.task@1 (planned, owner network) and ADR-044: one task at OpenVibe.Actor's router with a mode, a per-task and per-day budget, result, cost and explanation, SSE progress, cancel and webhooks",++ "watch.watch@1 and the other Watch contracts (plan T18, planned), three watch events, four capabilities and the placeholder service manifest: user-defined persistent observations over pages, feeds, APIs, events and devices"],"updated": "2026-10-05"}@@@ -4186,6 +4186,78 @@"compatibility": "backward","status": "active"},++ {++ "id": "watch.watch",++ "version": "1.0.0",++ "owner": "watch",++ "schema": "watch/watch.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "planned"++ },++ {++ "id": "watch.watch-request",++ "version": "1.0.0",++ "owner": "watch",++ "schema": "watch/watch-request.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "planned"++ },++ {++ "id": "watch.watch-result",++ "version": "1.0.0",++ "owner": "watch",++ "schema": "watch/watch-result.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "planned"++ },++ {++ "id": "watch.observation",++ "version": "1.0.0",++ "owner": "watch",++ "schema": "watch/observation.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "planned"++ },++ {++ "id": "watch.check-run",++ "version": "1.0.0",++ "owner": "watch",++ "schema": "watch/check-run.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "planned"++ },++ {++ "id": "watch.observation.recorded",++ "version": "1.0.0",++ "owner": "watch",++ "schema": "events/payloads/watch.observation.recorded.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "planned"++ },++ {++ "id": "watch.watch.triggered",++ "version": "1.0.0",++ "owner": "watch",++ "schema": "events/payloads/watch.watch.triggered.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "planned"++ },++ {++ "id": "watch.check.failed",++ "version": "1.0.0",++ "owner": "watch",++ "schema": "events/payloads/watch.check.failed.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "planned"++ },{"id": "games.player.joined","version": "1.0.0",nnew file mode 100644@@@ -0,0 +1,17 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/events/payloads/watch.check.failed.v1.json",++ "title": "WatchCheckFailedPayload",++ "description": "watch.check.failed v1 (OpenVibe.Watch, plan T18): a check ended in a failure state. consecutive_failures is how many runs in a row have failed, so a consumer can tell a blip from a watch that is down. Envelope: subject { type: watch, id: <watch_id> }, visibility internal, priority normal, actor service:watch.",++ "type": "object",++ "additionalProperties": false,++ "required": ["watch_id", "state", "carrier", "http_status", "error_code", "consecutive_failures"],++ "properties": {++ "watch_id": { "type": "string", "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$" },++ "state": { "enum": ["http_error", "timeout", "parse_error", "rate_limited", "budget_exceeded", "skipped", "disabled"] },++ "carrier": { "type": ["string", "null"], "enum": ["event", "webhook", "http", "feed", "api", "node", "run", null] },++ "http_status": { "type": ["integer", "null"] },++ "error_code": { "type": ["string", "null"] },++ "consecutive_failures": { "type": "integer", "minimum": 1 }++ }++}nnew file mode 100644@@@ -0,0 +1,18 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/events/payloads/watch.observation.recorded.v1.json",++ "title": "WatchObservationRecordedPayload",++ "description": "watch.observation.recorded v1 (OpenVibe.Watch, plan T18): a check recorded an observation for a watch. It carries the extracted value as the source stated it and its hash, never the raw body. Envelope: subject { type: watch, id: <watch_id> }, visibility internal, priority low, actor service:watch. Watch's own records are the full observation (watch.observation@1); this event is the notification that one exists.",++ "type": "object",++ "additionalProperties": false,++ "required": ["watch_id", "owner", "observed_at", "value", "value_hash", "changed", "condition_met"],++ "properties": {++ "watch_id": { "type": "string", "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$" },++ "owner": { "type": "string", "pattern": "^(usr|agt)_[0-9A-HJKMNP-TV-Z]{26}$", "description": "The watch owner's subject id: who this observation is for." },++ "observed_at": { "type": "string", "format": "date-time" },++ "value": { "description": "The extracted value as the source stated it; null when it stated none." },++ "value_hash": { "type": "string", "pattern": "^[0-9a-f]{64}$", "description": "SHA-256 hex of the canonical value." },++ "changed": { "type": "boolean" },++ "condition_met": { "type": "boolean" }++ }++}nnew file mode 100644@@@ -0,0 +1,28 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/events/payloads/watch.watch.triggered.v1.json",++ "title": "WatchTriggeredPayload",++ "description": "watch.watch.triggered v1 (OpenVibe.Watch, plan T18; the dossier's watch.triggered, named with three segments as every event type is here — the repo's event-type pattern requires at least three): a watch's condition fired. OpenVibe.Network turns it into a WATCH_TRIGGERED notification for payload.recipient (mirrors deals.watch.matched). Envelope: subject { type: watch, id: <watch_id> }, visibility internal, priority important, actor service:watch.",++ "type": "object",++ "additionalProperties": false,++ "required": ["watch_id", "recipient", "project_id", "name", "condition", "observation", "fired_at"],++ "properties": {++ "watch_id": { "type": "string", "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$" },++ "recipient": { "type": "string", "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$", "description": "The watch owner's user subject id: who is notified." },++ "project_id": { "type": ["string", "null"], "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$" },++ "name": { "type": "string", "minLength": 1, "maxLength": 120 },++ "condition": { "$ref": "../../watch/watch.v1.json#/$defs/condition" },++ "observation": {++ "type": "object",++ "additionalProperties": false,++ "required": ["id", "observed_at", "value", "previous_value"],++ "properties": {++ "id": { "type": "string", "pattern": "^wco_[0-9A-HJKMNP-TV-Z]{26}$" },++ "observed_at": { "type": "string", "format": "date-time" },++ "value": { "description": "The value that fired the condition." },++ "previous_value": { "description": "The previous observation's value; null when there was none." }++ }++ },++ "fired_at": { "type": "string", "format": "date-time" }++ }++}@@@ -66,7 +66,7 @@"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. Kind harness: task:edit, task:review, task:browse, task:run, task:test and task:plan for the task kinds it takes (its detail's task_capabilities), and harness:mcp, harness:resume, harness:host-access and harness:long-autonomy for its detail's capabilities that are true. The `worker:<class>` names that map to platform.runtime-class@1 values are reserved for OpenVibe.Node's job worker, one per class: worker:function, worker:code, worker:browser, worker:linux, worker:desktop and worker:gpu ($defs.reservedWorkerCapabilities). A node advertises the name of each class it runs (Node's status.capabilities.worker); every other `worker:` name (worker:ffmpeg, worker:ai-gpu) is an ordinary capability name."++ "description": "e.g. node:http, worker:browser, worker:ffmpeg, worker:ai-gpu, events:gateway, events:durable, object:r2. Kind harness: task:edit, task:review, task:browse, task:run, task:test and task:plan for the task kinds it takes (its detail's task_capabilities), and harness:mcp, harness:resume, harness:host-access and harness:long-autonomy for its detail's capabilities that are true. The `worker:<class>` names that map to platform.runtime-class@1 values are reserved for OpenVibe.Node's job worker, one per class: worker:function, worker:code, worker:browser, worker:linux, worker:desktop and worker:gpu ($defs.reservedWorkerCapabilities). A node advertises the name of each class it runs (Node's status.capabilities.worker); every other `worker:` name (worker:ffmpeg, worker:ai-gpu) is an ordinary capability name. Beside them, a kind harness names `runtime:<class>` for each platform.runtime-class@1 class it can run (runtime:function, runtime:code, runtime:browser, runtime:linux, runtime:desktop, runtime:gpu); these are ordinary capability names, not reserved, and OpenVibe.Codes already advertises the classes it offers."},"capacity": {"type": "object",nnew file mode 100644@@@ -0,0 +1,23 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/watch/check-run.v1.json",++ "title": "WatchCheckRun",++ "description": "watch.check-run@1: one execution of a watch's check (plan T18), by schedule, manually, or from a delivered event or webhook. carrier names the mechanism that carried it; state is the terminal state (the same values the service's check_runs.state CHECK allows). observations is how many observations the run recorded and triggers how many conditions it fired; cost_usd is what the run cost. Rows are immutable.",++ "type": "object",++ "additionalProperties": false,++ "required": ["id", "watch_id", "trigger", "carrier", "started_at", "finished_at", "state", "http_status", "observations", "triggers", "cost_usd", "detail"],++ "properties": {++ "id": { "type": "string", "pattern": "^ckr_[0-9A-HJKMNP-TV-Z]{26}$" },++ "watch_id": { "type": "string", "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$" },++ "trigger": { "enum": ["schedule", "manual", "event", "webhook"] },++ "carrier": { "type": ["string", "null"], "enum": ["event", "webhook", "http", "feed", "api", "node", "run", null] },++ "started_at": { "type": "string", "format": "date-time" },++ "finished_at": { "type": "string", "format": "date-time" },++ "state": { "enum": ["ok", "not_modified", "no_change", "changed", "condition_met", "http_error", "timeout", "parse_error", "rate_limited", "budget_exceeded", "skipped", "disabled"] },++ "http_status": { "type": ["integer", "null"] },++ "observations": { "type": "integer", "minimum": 0 },++ "triggers": { "type": "integer", "minimum": 0 },++ "cost_usd": { "type": "number", "minimum": 0 },++ "detail": { "type": ["string", "null"] }++ }++}nnew file mode 100644@@@ -0,0 +1,21 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/watch/observation.v1.json",++ "title": "WatchObservation",++ "description": "watch.observation@1: one value a check recorded for a watch (plan T18): what was extracted, when, from which check run, and whether it changed or met the condition. value is the extracted value exactly as the source stated it, never inferred; snapshot is a capped copy of the raw body kept according to the watch's retention. Rows are immutable.",++ "type": "object",++ "additionalProperties": false,++ "required": ["id", "watch_id", "check_run_id", "observed_at", "value", "value_hash", "previous_hash", "changed", "condition_met", "snapshot"],++ "properties": {++ "id": { "type": "string", "pattern": "^wco_[0-9A-HJKMNP-TV-Z]{26}$" },++ "watch_id": { "type": "string", "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$" },++ "check_run_id": { "type": "string", "pattern": "^ckr_[0-9A-HJKMNP-TV-Z]{26}$" },++ "observed_at": { "type": "string", "format": "date-time" },++ "value": { "description": "The extracted value as the source stated it: text, a decimal number, a structured object." },++ "value_hash": { "type": "string", "pattern": "^[0-9a-f]{64}$", "description": "SHA-256 hex of the canonical value." },++ "previous_hash": { "type": ["string", "null"], "pattern": "^[0-9a-f]{64}$", "description": "SHA-256 of the previous observation's value; null for the first observation." },++ "changed": { "type": "boolean" },++ "condition_met": { "type": "boolean" },++ "snapshot": { "type": ["string", "null"] }++ }++}nnew file mode 100644@@@ -0,0 +1,21 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/watch/watch-request.v1.json",++ "title": "WatchRequest",++ "description": "watch.watch-request@1: the body of POST /api/v1/watches and PATCH /api/v1/watches/:id on OpenVibe.Watch (watch.watch.manage; the acting person). Every field is optional on a patch; a create requires source, extraction, condition and action, which the service enforces in code (422 watch.invalid).",++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "name": { "type": "string", "minLength": 1, "maxLength": 120 },++ "labels": { "type": "object", "additionalProperties": { "type": "string", "maxLength": 60 } },++ "source": { "$ref": "watch.v1.json#/$defs/source" },++ "cadence": { "$ref": "watch.v1.json#/$defs/cadence" },++ "extraction": { "$ref": "watch.v1.json#/$defs/extraction" },++ "comparison": { "$ref": "watch.v1.json#/$defs/comparison" },++ "condition": { "$ref": "watch.v1.json#/$defs/condition" },++ "action": { "type": "array", "minItems": 1, "maxItems": 8, "items": { "$ref": "watch.v1.json#/$defs/action" } },++ "budget": { "$ref": "watch.v1.json#/$defs/budget" },++ "retention": { "$ref": "watch.v1.json#/$defs/retention" },++ "status": { "enum": ["active", "paused", "disabled", "failed"] }++ }++}nnew file mode 100644@@@ -0,0 +1,38 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/watch/watch-result.v1.json",++ "title": "WatchResult",++ "description": "watch.watch-result@1: answers of the watch routes on OpenVibe.Watch. GET /api/v1/watches → { watches } and POST /api/v1/watches → 201 { watch } (watch.watch.read, watch.watch.manage); PATCH → { watch }; POST /:id/pause and /:id/resume → { id, status }; DELETE /api/v1/watches/:id → { id, deleted: true }.",++ "anyOf": [++ {++ "type": "object",++ "required": ["watches"],++ "additionalProperties": false,++ "properties": { "watches": { "type": "array", "items": { "$ref": "watch.v1.json" } } }++ },++ {++ "type": "object",++ "required": ["watch"],++ "additionalProperties": false,++ "properties": { "watch": { "$ref": "watch.v1.json" } }++ },++ {++ "type": "object",++ "required": ["id", "status"],++ "additionalProperties": false,++ "properties": {++ "id": { "type": "string", "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$" },++ "status": { "enum": ["active", "paused", "disabled", "failed"] }++ }++ },++ {++ "type": "object",++ "required": ["id", "deleted"],++ "additionalProperties": false,++ "properties": {++ "id": { "type": "string", "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$" },++ "deleted": { "const": true }++ }++ }++ ]++}nnew file mode 100644@@@ -0,0 +1,102 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/watch/watch.v1.json",++ "title": "Watch",++ "description": "watch.watch@1: a user-defined persistent observation (plan T18). It names a source (a push event, a webhook, a conditional HTTP URL, a feed or API, a local Node probe, or an expensive Run check), how a value is extracted, how it is compared with the last observation, the condition that fires, the actions it wakes, its budget and its retention. Carrier preference is binding: an event or webhook source is used when one exists, then ETag/Last-Modified, then a feed, then an API, and browser polling through Run only when none works. A price or stock is 'as of' the observation, null when it stated none.",++ "type": "object",++ "additionalProperties": false,++ "required": ["id", "owner", "status", "source", "extraction", "condition", "action", "created_at", "updated_at"],++ "properties": {++ "id": { "type": "string", "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$" },++ "project_id": { "type": ["string", "null"], "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$" },++ "owner": { "type": "string", "description": "The acting person or agent the watch belongs to: usr_…, agt_… or svc:…." },++ "name": { "type": "string", "minLength": 1, "maxLength": 120 },++ "labels": { "type": "object", "additionalProperties": { "type": "string", "maxLength": 60 } },++ "status": { "enum": ["active", "paused", "disabled", "failed"] },++ "source": { "$ref": "#/$defs/source" },++ "cadence": { "$ref": "#/$defs/cadence" },++ "extraction": { "$ref": "#/$defs/extraction" },++ "comparison": { "$ref": "#/$defs/comparison" },++ "condition": { "$ref": "#/$defs/condition" },++ "action": { "type": "array", "minItems": 1, "maxItems": 8, "items": { "$ref": "#/$defs/action" } },++ "budget": { "$ref": "#/$defs/budget" },++ "retention": { "$ref": "#/$defs/retention" },++ "health": { "type": ["object", "null"], "additionalProperties": true },++ "created_at": { "type": "string", "format": "date-time" },++ "updated_at": { "type": "string", "format": "date-time" }++ },++ "$defs": {++ "auth": {++ "type": "object",++ "required": ["mode"],++ "additionalProperties": false,++ "properties": {++ "mode": { "enum": ["none", "header", "bearer", "query"] },++ "env": { "type": ["string", "null"], "pattern": "^WATCH_CRED_[A-Z0-9_]{2,60}$", "description": "The name of the environment variable holding the credential; Watch reads it by name at fetch time and never stores the value." },++ "header": { "type": ["string", "null"] },++ "param": { "type": ["string", "null"] }++ }++ },++ "source": {++ "oneOf": [++ { "type": "object", "required": ["kind"], "additionalProperties": false,++ "properties": { "kind": { "const": "webhook" }, "endpoint": { "type": "string", "pattern": "^/internal/hooks/" } } },++ { "type": "object", "required": ["kind", "pattern"], "additionalProperties": false,++ "properties": { "kind": { "const": "event" }, "pattern": { "type": "string", "pattern": "^[a-z][a-z0-9_-]*(\\.[a-z0-9_*]+){1,}$" },++ "filter": { "type": ["object", "null"], "additionalProperties": { "type": ["string", "number", "boolean", "null"] } } } },++ { "type": "object", "required": ["kind", "url"], "additionalProperties": false,++ "properties": { "kind": { "enum": ["http", "feed", "api"] }, "url": { "type": "string", "format": "uri", "pattern": "^https?://" },++ "method": { "enum": ["GET", "HEAD"] }, "format": { "enum": ["rss", "atom", "json", null] },++ "items_path": { "type": ["string", "null"] }, "fields": { "type": ["object", "null"], "additionalProperties": { "type": "string" } },++ "auth": { "$ref": "#/$defs/auth" }, "headers": { "type": "object", "additionalProperties": { "type": "string" } },++ "conditional": { "type": "boolean", "description": "Send If-None-Match / If-Modified-Since from the stored ETag/Last-Modified when the server gave one." } } },++ { "type": "object", "required": ["kind", "node_id", "probe"], "additionalProperties": false,++ "properties": { "kind": { "const": "node" }, "node_id": { "type": "string" }, "probe": { "type": "object", "additionalProperties": true } } },++ { "type": "object", "required": ["kind", "runtime", "steps"], "additionalProperties": false,++ "properties": { "kind": { "const": "run" }, "runtime": { "enum": ["browser", "code", "desktop"] },++ "url": { "type": ["string", "null"], "format": "uri" }, "steps": { "type": "array", "minItems": 1, "items": { "type": "object", "additionalProperties": true } },++ "workload": { "$ref": "../platform/workload-requirements.v1.json" } } }++ ]++ },++ "cadence": {++ "type": ["object", "null"], "additionalProperties": false,++ "description": "Required for http/feed/api/node sources; null for event/webhook sources (they never poll).",++ "properties": { "every_sec": { "type": "integer", "minimum": 30, "maximum": 2592000 }, "jitter_sec": { "type": "integer", "minimum": 0, "maximum": 3600 }, "timezone": { "type": ["string", "null"] } }++ },++ "extraction": {++ "type": "object", "additionalProperties": false,++ "properties": { "kind": { "enum": ["text", "html", "json", "regex", "css", "jsonpath", "ai"] },++ "selector": { "type": ["string", "null"] }, "fields": { "type": ["object", "null"], "additionalProperties": { "type": "string" } },++ "value_path": { "type": ["string", "null"] }, "ai": { "type": ["object", "null"], "additionalProperties": true } }++ },++ "comparison": {++ "type": ["object", "null"], "additionalProperties": false,++ "properties": { "mode": { "enum": ["changed", "threshold", "none"] }, "tolerance": { "type": ["number", "null"] }, "percent": { "type": ["number", "null"] } }++ },++ "condition": {++ "type": "object", "additionalProperties": false,++ "properties": { "op": { "enum": ["changed", "gt", "gte", "lt", "lte", "eq", "ne", "contains", "matches", "exists", "absent"] },++ "value": { "type": ["string", "number", "null"] }, "for_sec": { "type": ["integer", "null"], "minimum": 0 } }++ },++ "action": { "oneOf": [++ { "type": "object", "required": ["kind"], "additionalProperties": false,++ "properties": { "kind": { "const": "notification" }, "category": { "enum": ["service", "social", "system"] }, "priority": { "enum": ["low", "normal", "high", "critical"] } } },++ { "type": "object", "required": ["kind", "event_type"], "additionalProperties": false,++ "properties": { "kind": { "const": "event" }, "event_type": { "type": "string" }, "payload": { "type": ["object", "null"], "additionalProperties": true } } },++ { "type": "object", "required": ["kind", "url", "secret_env"], "additionalProperties": false,++ "properties": { "kind": { "const": "webhook" }, "url": { "type": "string", "format": "uri", "pattern": "^https://" }, "secret_env": { "type": "string", "pattern": "^WATCH_HOOK_[A-Z0-9_]{2,60}$" } } },++ { "type": "object", "required": ["kind", "brief"], "additionalProperties": false,++ "properties": { "kind": { "const": "actor-task" }, "brief": { "type": "string", "maxLength": 8000 }, "budget_usd": { "type": ["number", "null"] } } },++ { "type": "object", "required": ["kind", "repo", "brief"], "additionalProperties": false,++ "properties": { "kind": { "const": "codes-run" }, "repo": { "type": "string" }, "brief": { "type": "string", "maxLength": 8000 } } },++ { "type": "object", "required": ["kind", "runtime", "command"], "additionalProperties": false,++ "properties": { "kind": { "const": "run-job" }, "runtime": { "enum": ["function", "code", "browser", "linux"] }, "command": { "type": "string" }, "workload": { "type": ["object", "null"], "additionalProperties": true } } } ] },++ "budget": {++ "type": "object", "additionalProperties": false,++ "properties": { "checks_per_day": { "type": ["integer", "null"], "minimum": 1 }, "usd_per_month": { "type": ["number", "null"], "minimum": 0 },++ "max_runtime_ms": { "type": ["integer", "null"], "minimum": 100 }, "max_bytes": { "type": ["integer", "null"], "minimum": 1024 } }++ },++ "retention": { "type": "object", "additionalProperties": false,++ "properties": { "observations_days": { "type": ["integer", "null"], "minimum": 1 }, "keep_snapshots": { "type": "boolean" } } }++ }++}nnew file mode 100644@@@ -0,0 +1,14 @@++{++ "id": "ckr_01JAB2C3D4E5F6G7H8J9K0MNPT",++ "watch_id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",++ "trigger": "schedule",++ "carrier": "http",++ "started_at": "2026-10-05T09:00:00.000Z",++ "finished_at": "2026-10-05T09:00:01.250Z",++ "state": "exploded",++ "http_status": 200,++ "observations": 1,++ "triggers": 0,++ "cost_usd": 0,++ "detail": null++}nnew file mode 100644@@@ -0,0 +1,14 @@++{++ "id": "ckr_01JAB2C3D4E5F6G7H8J9K0MNPT",++ "watch_id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",++ "trigger": "schedule",++ "carrier": "http",++ "started_at": "2026-10-05T09:00:00.000Z",++ "finished_at": "2026-10-05T09:00:01.250Z",++ "state": "changed",++ "http_status": 200,++ "observations": 1,++ "triggers": 0,++ "cost_usd": 0,++ "detail": null++}nnew file mode 100644@@@ -0,0 +1,8 @@++{++ "watch_id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",++ "state": "timeout",++ "carrier": "api",++ "http_status": null,++ "error_code": "deadline_exceeded",++ "consecutive_failures": 0++}nnew file mode 100644@@@ -0,0 +1,8 @@++{++ "watch_id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",++ "state": "http_error",++ "carrier": "http",++ "http_status": 503,++ "error_code": "upstream_unavailable",++ "consecutive_failures": 2++}nnew file mode 100644@@@ -0,0 +1,8 @@++{++ "watch_id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",++ "observed_at": "2026-10-05T09:00:00.000Z",++ "value": 189.99,++ "value_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",++ "changed": true,++ "condition_met": true++}nnew file mode 100644@@@ -0,0 +1,9 @@++{++ "watch_id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",++ "owner": "usr_01JAB2C3D4E5F6G7H8J9K0MNPR",++ "observed_at": "2026-10-05T09:00:00.000Z",++ "value": 189.99,++ "value_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",++ "changed": true,++ "condition_met": true++}nnew file mode 100644@@@ -0,0 +1,11 @@++{++ "id": "wco_01JAB2C3D4E5F6G7H8J9K0MNPS",++ "watch_id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",++ "observed_at": "2026-10-05T09:00:00.000Z",++ "value": 189.99,++ "value_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",++ "previous_hash": null,++ "changed": true,++ "condition_met": true,++ "snapshot": null++}nnew file mode 100644@@@ -0,0 +1,12 @@++{++ "id": "wco_01JAB2C3D4E5F6G7H8J9K0MNPS",++ "watch_id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",++ "check_run_id": "ckr_01JAB2C3D4E5F6G7H8J9K0MNPT",++ "observed_at": "2026-10-05T09:00:00.000Z",++ "value": 189.99,++ "value_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",++ "previous_hash": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",++ "changed": true,++ "condition_met": true,++ "snapshot": "{\"price\":189.99,\"currency\":\"USD\"}"++}nnew file mode 100644@@@ -0,0 +1,7 @@++{++ "name": "Release 0.102.0 published",++ "source": { "kind": "event", "pattern": "host.release.published" },++ "condition": { "op": "changed" },++ "action": [ { "kind": "notification" } ],++ "status": "archived"++}nnew file mode 100644@@@ -0,0 +1,12 @@++{++ "name": "Release 0.102.0 published",++ "source": { "kind": "event", "pattern": "host.release.published", "filter": null },++ "cadence": null,++ "extraction": { "kind": "json", "selector": null, "fields": null, "value_path": "$.release", "ai": null },++ "comparison": { "mode": "changed", "tolerance": null, "percent": null },++ "condition": { "op": "changed", "value": null, "for_sec": null },++ "action": [ { "kind": "notification", "category": "service", "priority": "normal" } ],++ "budget": { "checks_per_day": 100, "usd_per_month": 0, "max_runtime_ms": 5000, "max_bytes": 1048576 },++ "retention": { "observations_days": 30, "keep_snapshots": false },++ "status": "active"++}nnew file mode 100644@@@ -0,0 +1 @@++{ "id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ", "deleted": false }nnew file mode 100644@@@ -0,0 +1 @@++{ "id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ", "status": "paused" }nnew file mode 100644@@@ -0,0 +1,8 @@++{++ "watch_id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",++ "recipient": "usr_01JAB2C3D4E5F6G7H8J9K0MNPR",++ "project_id": null,++ "name": "Steam Deck OLED price",++ "condition": { "op": "lt", "value": 199, "for_sec": null },++ "fired_at": "2026-10-05T09:00:01.250Z"++}nnew file mode 100644@@@ -0,0 +1,14 @@++{++ "watch_id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",++ "recipient": "usr_01JAB2C3D4E5F6G7H8J9K0MNPR",++ "project_id": null,++ "name": "Steam Deck OLED price",++ "condition": { "op": "lt", "value": 199, "for_sec": null },++ "observation": {++ "id": "wco_01JAB2C3D4E5F6G7H8J9K0MNPS",++ "observed_at": "2026-10-05T09:00:00.000Z",++ "value": 189.99,++ "previous_value": 209.99++ },++ "fired_at": "2026-10-05T09:00:01.250Z"++}nnew file mode 100644@@@ -0,0 +1,11 @@++{++ "id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",++ "name": "Steam Deck OLED price",++ "status": "active",++ "source": { "kind": "api", "url": "https://openvibe.deals/api/offers/steam-deck-oled" },++ "extraction": { "kind": "jsonpath", "value_path": "$.price" },++ "condition": { "op": "lt", "value": 199 },++ "action": [ { "kind": "notification" } ],++ "created_at": "2026-10-05T08:00:00.000Z",++ "updated_at": "2026-10-05T08:00:00.000Z"++}nnew file mode 100644@@@ -0,0 +1,29 @@++{++ "id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",++ "project_id": null,++ "owner": "usr_01JAB2C3D4E5F6G7H8J9K0MNPR",++ "name": "Steam Deck OLED price",++ "labels": { "topic": "hardware" },++ "status": "active",++ "source": {++ "kind": "api",++ "url": "https://openvibe.deals/api/offers/steam-deck-oled",++ "method": "GET",++ "format": "json",++ "items_path": "offers",++ "fields": { "price": "price", "currency": "currency" },++ "auth": { "mode": "none" },++ "headers": {},++ "conditional": true++ },++ "cadence": { "every_sec": 3600, "jitter_sec": 60, "timezone": null },++ "extraction": { "kind": "jsonpath", "selector": null, "fields": null, "value_path": "$.offers[0].price", "ai": null },++ "comparison": { "mode": "threshold", "tolerance": 0.01, "percent": null },++ "condition": { "op": "lt", "value": 199, "for_sec": null },++ "action": [ { "kind": "notification", "category": "service", "priority": "high" } ],++ "budget": { "checks_per_day": 100, "usd_per_month": 0, "max_runtime_ms": 20000, "max_bytes": 5242880 },++ "retention": { "observations_days": 90, "keep_snapshots": false },++ "health": null,++ "created_at": "2026-10-05T08:00:00.000Z",++ "updated_at": "2026-10-05T08:00:00.000Z"++}@@@ -46078,6 +46078,1184 @@}}},++ "watch.watch": {++ "version": "1.0.0",++ "owner": "watch",++ "status": "planned",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/watch/watch.v1.json",++ "title": "Watch",++ "description": "watch.watch@1: a user-defined persistent observation (plan T18). It names a source (a push event, a webhook, a conditional HTTP URL, a feed or API, a local Node probe, or an expensive Run check), how a value is extracted, how it is compared with the last observation, the condition that fires, the actions it wakes, its budget and its retention. Carrier preference is binding: an event or webhook source is used when one exists, then ETag/Last-Modified, then a feed, then an API, and browser polling through Run only when none works. A price or stock is 'as of' the observation, null when it stated none.",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "id",++ "owner",++ "status",++ "source",++ "extraction",++ "condition",++ "action",++ "created_at",++ "updated_at"++ ],++ "properties": {++ "id": {++ "type": "string",++ "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "project_id": {++ "type": [++ "string",++ "null"++ ],++ "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "owner": {++ "type": "string",++ "description": "The acting person or agent the watch belongs to: usr_…, agt_… or svc:…."++ },++ "name": {++ "type": "string",++ "minLength": 1,++ "maxLength": 120++ },++ "labels": {++ "type": "object",++ "additionalProperties": {++ "type": "string",++ "maxLength": 60++ }++ },++ "status": {++ "enum": [++ "active",++ "paused",++ "disabled",++ "failed"++ ]++ },++ "source": {++ "$ref": "#/$defs/source"++ },++ "cadence": {++ "$ref": "#/$defs/cadence"++ },++ "extraction": {++ "$ref": "#/$defs/extraction"++ },++ "comparison": {++ "$ref": "#/$defs/comparison"++ },++ "condition": {++ "$ref": "#/$defs/condition"++ },++ "action": {++ "type": "array",++ "minItems": 1,++ "maxItems": 8,++ "items": {++ "$ref": "#/$defs/action"++ }++ },++ "budget": {++ "$ref": "#/$defs/budget"++ },++ "retention": {++ "$ref": "#/$defs/retention"++ },++ "health": {++ "type": [++ "object",++ "null"++ ],++ "additionalProperties": true++ },++ "created_at": {++ "type": "string",++ "format": "date-time"++ },++ "updated_at": {++ "type": "string",++ "format": "date-time"++ }++ },++ "$defs": {++ "auth": {++ "type": "object",++ "required": [++ "mode"++ ],++ "additionalProperties": false,++ "properties": {++ "mode": {++ "enum": [++ "none",++ "header",++ "bearer",++ "query"++ ]++ },++ "env": {++ "type": [++ "string",++ "null"++ ],++ "pattern": "^WATCH_CRED_[A-Z0-9_]{2,60}$",++ "description": "The name of the environment variable holding the credential; Watch reads it by name at fetch time and never stores the value."++ },++ "header": {++ "type": [++ "string",++ "null"++ ]++ },++ "param": {++ "type": [++ "string",++ "null"++ ]++ }++ }++ },++ "source": {++ "oneOf": [++ {++ "type": "object",++ "required": [++ "kind"++ ],++ "additionalProperties": false,++ "properties": {++ "kind": {++ "const": "webhook"++ },++ "endpoint": {++ "type": "string",++ "pattern": "^/internal/hooks/"++ }++ }++ },++ {++ "type": "object",++ "required": [++ "kind",++ "pattern"++ ],++ "additionalProperties": false,++ "properties": {++ "kind": {++ "const": "event"++ },++ "pattern": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9_-]*(\\.[a-z0-9_*]+){1,}$"++ },++ "filter": {++ "type": [++ "object",++ "null"++ ],++ "additionalProperties": {++ "type": [++ "string",++ "number",++ "boolean",++ "null"++ ]++ }++ }++ }++ },++ {++ "type": "object",++ "required": [++ "kind",++ "url"++ ],++ "additionalProperties": false,++ "properties": {++ "kind": {++ "enum": [++ "http",++ "feed",++ "api"++ ]++ },++ "url": {++ "type": "string",++ "format": "uri",++ "pattern": "^https?://"++ },++ "method": {++ "enum": [++ "GET",++ "HEAD"++ ]++ },++ "format": {++ "enum": [++ "rss",++ "atom",++ "json",++ null++ ]++ },++ "items_path": {++ "type": [++ "string",++ "null"++ ]++ },++ "fields": {++ "type": [++ "object",++ "null"++ ],++ "additionalProperties": {++ "type": "string"++ }++ },++ "auth": {++ "$ref": "#/$defs/auth"++ },++ "headers": {++ "type": "object",++ "additionalProperties": {++ "type": "string"++ }++ },++ "conditional": {++ "type": "boolean",++ "description": "Send If-None-Match / If-Modified-Since from the stored ETag/Last-Modified when the server gave one."++ }++ }++ },++ {++ "type": "object",++ "required": [++ "kind",++ "node_id",++ "probe"++ ],++ "additionalProperties": false,++ "properties": {++ "kind": {++ "const": "node"++ },++ "node_id": {++ "type": "string"++ },++ "probe": {++ "type": "object",++ "additionalProperties": true++ }++ }++ },++ {++ "type": "object",++ "required": [++ "kind",++ "runtime",++ "steps"++ ],++ "additionalProperties": false,++ "properties": {++ "kind": {++ "const": "run"++ },++ "runtime": {++ "enum": [++ "browser",++ "code",++ "desktop"++ ]++ },++ "url": {++ "type": [++ "string",++ "null"++ ],++ "format": "uri"++ },++ "steps": {++ "type": "array",++ "minItems": 1,++ "items": {++ "type": "object",++ "additionalProperties": true++ }++ },++ "workload": {++ "$ref": "../platform/workload-requirements.v1.json"++ }++ }++ }++ ]++ },++ "cadence": {++ "type": [++ "object",++ "null"++ ],++ "additionalProperties": false,++ "description": "Required for http/feed/api/node sources; null for event/webhook sources (they never poll).",++ "properties": {++ "every_sec": {++ "type": "integer",++ "minimum": 30,++ "maximum": 2592000++ },++ "jitter_sec": {++ "type": "integer",++ "minimum": 0,++ "maximum": 3600++ },++ "timezone": {++ "type": [++ "string",++ "null"++ ]++ }++ }++ },++ "extraction": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "kind": {++ "enum": [++ "text",++ "html",++ "json",++ "regex",++ "css",++ "jsonpath",++ "ai"++ ]++ },++ "selector": {++ "type": [++ "string",++ "null"++ ]++ },++ "fields": {++ "type": [++ "object",++ "null"++ ],++ "additionalProperties": {++ "type": "string"++ }++ },++ "value_path": {++ "type": [++ "string",++ "null"++ ]++ },++ "ai": {++ "type": [++ "object",++ "null"++ ],++ "additionalProperties": true++ }++ }++ },++ "comparison": {++ "type": [++ "object",++ "null"++ ],++ "additionalProperties": false,++ "properties": {++ "mode": {++ "enum": [++ "changed",++ "threshold",++ "none"++ ]++ },++ "tolerance": {++ "type": [++ "number",++ "null"++ ]++ },++ "percent": {++ "type": [++ "number",++ "null"++ ]++ }++ }++ },++ "condition": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "op": {++ "enum": [++ "changed",++ "gt",++ "gte",++ "lt",++ "lte",++ "eq",++ "ne",++ "contains",++ "matches",++ "exists",++ "absent"++ ]++ },++ "value": {++ "type": [++ "string",++ "number",++ "null"++ ]++ },++ "for_sec": {++ "type": [++ "integer",++ "null"++ ],++ "minimum": 0++ }++ }++ },++ "action": {++ "oneOf": [++ {++ "type": "object",++ "required": [++ "kind"++ ],++ "additionalProperties": false,++ "properties": {++ "kind": {++ "const": "notification"++ },++ "category": {++ "enum": [++ "service",++ "social",++ "system"++ ]++ },++ "priority": {++ "enum": [++ "low",++ "normal",++ "high",++ "critical"++ ]++ }++ }++ },++ {++ "type": "object",++ "required": [++ "kind",++ "event_type"++ ],++ "additionalProperties": false,++ "properties": {++ "kind": {++ "const": "event"++ },++ "event_type": {++ "type": "string"++ },++ "payload": {++ "type": [++ "object",++ "null"++ ],++ "additionalProperties": true++ }++ }++ },++ {++ "type": "object",++ "required": [++ "kind",++ "url",++ "secret_env"++ ],++ "additionalProperties": false,++ "properties": {++ "kind": {++ "const": "webhook"++ },++ "url": {++ "type": "string",++ "format": "uri",++ "pattern": "^https://"++ },++ "secret_env": {++ "type": "string",++ "pattern": "^WATCH_HOOK_[A-Z0-9_]{2,60}$"++ }++ }++ },++ {++ "type": "object",++ "required": [++ "kind",++ "brief"++ ],++ "additionalProperties": false,++ "properties": {++ "kind": {++ "const": "actor-task"++ },++ "brief": {++ "type": "string",++ "maxLength": 8000++ },++ "budget_usd": {++ "type": [++ "number",++ "null"++ ]++ }++ }++ },++ {++ "type": "object",++ "required": [++ "kind",++ "repo",++ "brief"++ ],++ "additionalProperties": false,++ "properties": {++ "kind": {++ "const": "codes-run"++ },++ "repo": {++ "type": "string"++ },++ "brief": {++ "type": "string",++ "maxLength": 8000++ }++ }++ },++ {++ "type": "object",++ "required": [++ "kind",++ "runtime",++ "command"++ ],++ "additionalProperties": false,++ "properties": {++ "kind": {++ "const": "run-job"++ },++ "runtime": {++ "enum": [++ "function",++ "code",++ "browser",++ "linux"++ ]++ },++ "command": {++ "type": "string"++ },++ "workload": {++ "type": [++ "object",++ "null"++ ],++ "additionalProperties": true++ }++ }++ }++ ]++ },++ "budget": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "checks_per_day": {++ "type": [++ "integer",++ "null"++ ],++ "minimum": 1++ },++ "usd_per_month": {++ "type": [++ "number",++ "null"++ ],++ "minimum": 0++ },++ "max_runtime_ms": {++ "type": [++ "integer",++ "null"++ ],++ "minimum": 100++ },++ "max_bytes": {++ "type": [++ "integer",++ "null"++ ],++ "minimum": 1024++ }++ }++ },++ "retention": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "observations_days": {++ "type": [++ "integer",++ "null"++ ],++ "minimum": 1++ },++ "keep_snapshots": {++ "type": "boolean"++ }++ }++ }++ }++ }++ },++ "watch.watch-request": {++ "version": "1.0.0",++ "owner": "watch",++ "status": "planned",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/watch/watch-request.v1.json",++ "title": "WatchRequest",++ "description": "watch.watch-request@1: the body of POST /api/v1/watches and PATCH /api/v1/watches/:id on OpenVibe.Watch (watch.watch.manage; the acting person). Every field is optional on a patch; a create requires source, extraction, condition and action, which the service enforces in code (422 watch.invalid).",++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "name": {++ "type": "string",++ "minLength": 1,++ "maxLength": 120++ },++ "labels": {++ "type": "object",++ "additionalProperties": {++ "type": "string",++ "maxLength": 60++ }++ },++ "source": {++ "$ref": "watch.v1.json#/$defs/source"++ },++ "cadence": {++ "$ref": "watch.v1.json#/$defs/cadence"++ },++ "extraction": {++ "$ref": "watch.v1.json#/$defs/extraction"++ },++ "comparison": {++ "$ref": "watch.v1.json#/$defs/comparison"++ },++ "condition": {++ "$ref": "watch.v1.json#/$defs/condition"++ },++ "action": {++ "type": "array",++ "minItems": 1,++ "maxItems": 8,++ "items": {++ "$ref": "watch.v1.json#/$defs/action"++ }++ },++ "budget": {++ "$ref": "watch.v1.json#/$defs/budget"++ },++ "retention": {++ "$ref": "watch.v1.json#/$defs/retention"++ },++ "status": {++ "enum": [++ "active",++ "paused",++ "disabled",++ "failed"++ ]++ }++ }++ }++ },++ "watch.watch-result": {++ "version": "1.0.0",++ "owner": "watch",++ "status": "planned",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/watch/watch-result.v1.json",++ "title": "WatchResult",++ "description": "watch.watch-result@1: answers of the watch routes on OpenVibe.Watch. GET /api/v1/watches → { watches } and POST /api/v1/watches → 201 { watch } (watch.watch.read, watch.watch.manage); PATCH → { watch }; POST /:id/pause and /:id/resume → { id, status }; DELETE /api/v1/watches/:id → { id, deleted: true }.",++ "anyOf": [++ {++ "type": "object",++ "required": [++ "watches"++ ],++ "additionalProperties": false,++ "properties": {++ "watches": {++ "type": "array",++ "items": {++ "$ref": "watch.v1.json"++ }++ }++ }++ },++ {++ "type": "object",++ "required": [++ "watch"++ ],++ "additionalProperties": false,++ "properties": {++ "watch": {++ "$ref": "watch.v1.json"++ }++ }++ },++ {++ "type": "object",++ "required": [++ "id",++ "status"++ ],++ "additionalProperties": false,++ "properties": {++ "id": {++ "type": "string",++ "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "status": {++ "enum": [++ "active",++ "paused",++ "disabled",++ "failed"++ ]++ }++ }++ },++ {++ "type": "object",++ "required": [++ "id",++ "deleted"++ ],++ "additionalProperties": false,++ "properties": {++ "id": {++ "type": "string",++ "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "deleted": {++ "const": true++ }++ }++ }++ ]++ }++ },++ "watch.observation": {++ "version": "1.0.0",++ "owner": "watch",++ "status": "planned",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/watch/observation.v1.json",++ "title": "WatchObservation",++ "description": "watch.observation@1: one value a check recorded for a watch (plan T18): what was extracted, when, from which check run, and whether it changed or met the condition. value is the extracted value exactly as the source stated it, never inferred; snapshot is a capped copy of the raw body kept according to the watch's retention. Rows are immutable.",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "id",++ "watch_id",++ "check_run_id",++ "observed_at",++ "value",++ "value_hash",++ "previous_hash",++ "changed",++ "condition_met",++ "snapshot"++ ],++ "properties": {++ "id": {++ "type": "string",++ "pattern": "^wco_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "watch_id": {++ "type": "string",++ "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "check_run_id": {++ "type": "string",++ "pattern": "^ckr_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "observed_at": {++ "type": "string",++ "format": "date-time"++ },++ "value": {++ "description": "The extracted value as the source stated it: text, a decimal number, a structured object."++ },++ "value_hash": {++ "type": "string",++ "pattern": "^[0-9a-f]{64}$",++ "description": "SHA-256 hex of the canonical value."++ },++ "previous_hash": {++ "type": [++ "string",++ "null"++ ],++ "pattern": "^[0-9a-f]{64}$",++ "description": "SHA-256 of the previous observation's value; null for the first observation."++ },++ "changed": {++ "type": "boolean"++ },++ "condition_met": {++ "type": "boolean"++ },++ "snapshot": {++ "type": [++ "string",++ "null"++ ]++ }++ }++ }++ },++ "watch.check-run": {++ "version": "1.0.0",++ "owner": "watch",++ "status": "planned",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/watch/check-run.v1.json",++ "title": "WatchCheckRun",++ "description": "watch.check-run@1: one execution of a watch's check (plan T18), by schedule, manually, or from a delivered event or webhook. carrier names the mechanism that carried it; state is the terminal state (the same values the service's check_runs.state CHECK allows). observations is how many observations the run recorded and triggers how many conditions it fired; cost_usd is what the run cost. Rows are immutable.",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "id",++ "watch_id",++ "trigger",++ "carrier",++ "started_at",++ "finished_at",++ "state",++ "http_status",++ "observations",++ "triggers",++ "cost_usd",++ "detail"++ ],++ "properties": {++ "id": {++ "type": "string",++ "pattern": "^ckr_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "watch_id": {++ "type": "string",++ "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "trigger": {++ "enum": [++ "schedule",++ "manual",++ "event",++ "webhook"++ ]++ },++ "carrier": {++ "type": [++ "string",++ "null"++ ],++ "enum": [++ "event",++ "webhook",++ "http",++ "feed",++ "api",++ "node",++ "run",++ null++ ]++ },++ "started_at": {++ "type": "string",++ "format": "date-time"++ },++ "finished_at": {++ "type": "string",++ "format": "date-time"++ },++ "state": {++ "enum": [++ "ok",++ "not_modified",++ "no_change",++ "changed",++ "condition_met",++ "http_error",++ "timeout",++ "parse_error",++ "rate_limited",++ "budget_exceeded",++ "skipped",++ "disabled"++ ]++ },++ "http_status": {++ "type": [++ "integer",++ "null"++ ]++ },++ "observations": {++ "type": "integer",++ "minimum": 0++ },++ "triggers": {++ "type": "integer",++ "minimum": 0++ },++ "cost_usd": {++ "type": "number",++ "minimum": 0++ },++ "detail": {++ "type": [++ "string",++ "null"++ ]++ }++ }++ }++ },++ "watch.observation.recorded": {++ "version": "1.0.0",++ "owner": "watch",++ "status": "planned",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/events/payloads/watch.observation.recorded.v1.json",++ "title": "WatchObservationRecordedPayload",++ "description": "watch.observation.recorded v1 (OpenVibe.Watch, plan T18): a check recorded an observation for a watch. It carries the extracted value as the source stated it and its hash, never the raw body. Envelope: subject { type: watch, id: <watch_id> }, visibility internal, priority low, actor service:watch. Watch's own records are the full observation (watch.observation@1); this event is the notification that one exists.",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "watch_id",++ "owner",++ "observed_at",++ "value",++ "value_hash",++ "changed",++ "condition_met"++ ],++ "properties": {++ "watch_id": {++ "type": "string",++ "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "owner": {++ "type": "string",++ "pattern": "^(usr|agt)_[0-9A-HJKMNP-TV-Z]{26}$",++ "description": "The watch owner's subject id: who this observation is for."++ },++ "observed_at": {++ "type": "string",++ "format": "date-time"++ },++ "value": {++ "description": "The extracted value as the source stated it; null when it stated none."++ },++ "value_hash": {++ "type": "string",++ "pattern": "^[0-9a-f]{64}$",++ "description": "SHA-256 hex of the canonical value."++ },++ "changed": {++ "type": "boolean"++ },++ "condition_met": {++ "type": "boolean"++ }++ }++ }++ },++ "watch.watch.triggered": {++ "version": "1.0.0",++ "owner": "watch",++ "status": "planned",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/events/payloads/watch.watch.triggered.v1.json",++ "title": "WatchTriggeredPayload",++ "description": "watch.watch.triggered v1 (OpenVibe.Watch, plan T18; the dossier's watch.triggered, named with three segments as every event type is here — the repo's event-type pattern requires at least three): a watch's condition fired. OpenVibe.Network turns it into a WATCH_TRIGGERED notification for payload.recipient (mirrors deals.watch.matched). Envelope: subject { type: watch, id: <watch_id> }, visibility internal, priority important, actor service:watch.",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "watch_id",++ "recipient",++ "project_id",++ "name",++ "condition",++ "observation",++ "fired_at"++ ],++ "properties": {++ "watch_id": {++ "type": "string",++ "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "recipient": {++ "type": "string",++ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$",++ "description": "The watch owner's user subject id: who is notified."++ },++ "project_id": {++ "type": [++ "string",++ "null"++ ],++ "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "name": {++ "type": "string",++ "minLength": 1,++ "maxLength": 120++ },++ "condition": {++ "$ref": "../../watch/watch.v1.json#/$defs/condition"++ },++ "observation": {++ "type": "object",++ "additionalProperties": false,++ "required": [++ "id",++ "observed_at",++ "value",++ "previous_value"++ ],++ "properties": {++ "id": {++ "type": "string",++ "pattern": "^wco_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "observed_at": {++ "type": "string",++ "format": "date-time"++ },++ "value": {++ "description": "The value that fired the condition."++ },++ "previous_value": {++ "description": "The previous observation's value; null when there was none."++ }++ }++ },++ "fired_at": {++ "type": "string",++ "format": "date-time"++ }++ }++ }++ },++ "watch.check.failed": {++ "version": "1.0.0",++ "owner": "watch",++ "status": "planned",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/events/payloads/watch.check.failed.v1.json",++ "title": "WatchCheckFailedPayload",++ "description": "watch.check.failed v1 (OpenVibe.Watch, plan T18): a check ended in a failure state. consecutive_failures is how many runs in a row have failed, so a consumer can tell a blip from a watch that is down. Envelope: subject { type: watch, id: <watch_id> }, visibility internal, priority normal, actor service:watch.",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "watch_id",++ "state",++ "carrier",++ "http_status",++ "error_code",++ "consecutive_failures"++ ],++ "properties": {++ "watch_id": {++ "type": "string",++ "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "state": {++ "enum": [++ "http_error",++ "timeout",++ "parse_error",++ "rate_limited",++ "budget_exceeded",++ "skipped",++ "disabled"++ ]++ },++ "carrier": {++ "type": [++ "string",++ "null"++ ],++ "enum": [++ "event",++ "webhook",++ "http",++ "feed",++ "api",++ "node",++ "run",++ null++ ]++ },++ "http_status": {++ "type": [++ "integer",++ "null"++ ]++ },++ "error_code": {++ "type": [++ "string",++ "null"++ ]++ },++ "consecutive_failures": {++ "type": "integer",++ "minimum": 1++ }++ }++ }++ },"games.player.joined": {"version": "1.0.0","owner": "games",@@@ -61560,7 +62738,7 @@"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. Kind harness: task:edit, task:review, task:browse, task:run, task:test and task:plan for the task kinds it takes (its detail's task_capabilities), and harness:mcp, harness:resume, harness:host-access and harness:long-autonomy for its detail's capabilities that are true. The `worker:<class>` names that map to platform.runtime-class@1 values are reserved for OpenVibe.Node's job worker, one per class: worker:function, worker:code, worker:browser, worker:linux, worker:desktop and worker:gpu ($defs.reservedWorkerCapabilities). A node advertises the name of each class it runs (Node's status.capabilities.worker); every other `worker:` name (worker:ffmpeg, worker:ai-gpu) is an ordinary capability name."++ "description": "e.g. node:http, worker:browser, worker:ffmpeg, worker:ai-gpu, events:gateway, events:durable, object:r2. Kind harness: task:edit, task:review, task:browse, task:run, task:test and task:plan for the task kinds it takes (its detail's task_capabilities), and harness:mcp, harness:resume, harness:host-access and harness:long-autonomy for its detail's capabilities that are true. The `worker:<class>` names that map to platform.runtime-class@1 values are reserved for OpenVibe.Node's job worker, one per class: worker:function, worker:code, worker:browser, worker:linux, worker:desktop and worker:gpu ($defs.reservedWorkerCapabilities). A node advertises the name of each class it runs (Node's status.capabilities.worker); every other `worker:` name (worker:ffmpeg, worker:ai-gpu) is an ordinary capability name. Beside them, a kind harness names `runtime:<class>` for each platform.runtime-class@1 class it can run (runtime:function, runtime:code, runtime:browser, runtime:linux, runtime:desktop, runtime:gpu); these are ordinary capability names, not reserved, and OpenVibe.Codes already advertises the classes it offers."},"capacity": {"type": "object",@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.AI API",-- "version": "0.101.0",-- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.102.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Billing API",-- "version": "0.101.0",-- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.102.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Blog API",-- "version": "0.101.0",-- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.Bot API",-- "version": "0.101.0",-- "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",-- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",-- "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.102.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Community API",-- "version": "0.101.0",-- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",-- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",-- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",-- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.102.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Games API",-- "version": "0.101.0",-- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.102.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Host API",-- "version": "0.101.0",-- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",-- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",-- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",-- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.News API",-- "version": "0.101.0",-- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",-- "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.102.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Reviews API",-- "version": "0.101.0",-- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",-- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",-- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.Space API",-- "version": "0.101.0",-- "description": "Routes of OpenVibe.Space as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.Space as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",-- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.102.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Tools API",-- "version": "0.101.0",-- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",-- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",-- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.102.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Wiki API",-- "version": "0.101.0",-- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",++ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.102.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"@@@ -46238,6 +46238,3098 @@ export interface TradeWatchlist {}[];}++/** [email protected] (owner: watch) */++/**++ * watch.watch@1: a user-defined persistent observation (plan T18). It names a source (a push event, a webhook, a conditional HTTP URL, a feed or API, a local Node probe, or an expensive Run check), how a value is extracted, how it is compared with the last observation, the condition that fires, the actions it wakes, its budget and its retention. Carrier preference is binding: an event or webhook source is used when one exists, then ETag/Last-Modified, then a feed, then an API, and browser polling through Run only when none works. A price or stock is 'as of' the observation, null when it stated none.++ */++export interface Watch {++ id: string;++ project_id?: string | null;++ /**++ * The acting person or agent the watch belongs to: usr_…, agt_… or svc:….++ */++ owner: string;++ name?: string;++ labels?: {++ [k: string]: string | undefined;++ };++ status: "active" | "paused" | "disabled" | "failed";++ source:++ | {++ kind: "webhook";++ endpoint?: string;++ }++ | {++ kind: "event";++ pattern: string;++ filter?: {++ [k: string]: (string | number | boolean | null) | undefined;++ } | null;++ }++ | {++ kind: "http" | "feed" | "api";++ url: string;++ method?: "GET" | "HEAD";++ format?: "rss" | "atom" | "json" | null;++ items_path?: string | null;++ fields?: {++ [k: string]: string | undefined;++ } | null;++ auth?: {++ mode: "none" | "header" | "bearer" | "query";++ /**++ * The name of the environment variable holding the credential; Watch reads it by name at fetch time and never stores the value.++ */++ env?: string | null;++ header?: string | null;++ param?: string | null;++ };++ headers?: {++ [k: string]: string | undefined;++ };++ /**++ * Send If-None-Match / If-Modified-Since from the stored ETag/Last-Modified when the server gave one.++ */++ conditional?: boolean;++ }++ | {++ kind: "node";++ node_id: string;++ probe: {++ [k: string]: unknown | undefined;++ };++ }++ | {++ kind: "run";++ runtime: "browser" | "code" | "desktop";++ url?: string | null;++ /**++ * @minItems 1++ */++ steps: [++ {++ [k: string]: unknown | undefined;++ },++ ...{++ [k: string]: unknown | undefined;++ }[]++ ];++ workload?: WorkloadRequirements;++ };++ /**++ * Required for http/feed/api/node sources; null for event/webhook sources (they never poll).++ */++ cadence?: {++ every_sec?: number;++ jitter_sec?: number;++ timezone?: string | null;++ } | null;++ extraction: {++ kind?: "text" | "html" | "json" | "regex" | "css" | "jsonpath" | "ai";++ selector?: string | null;++ fields?: {++ [k: string]: string | undefined;++ } | null;++ value_path?: string | null;++ ai?: {++ [k: string]: unknown | undefined;++ } | null;++ };++ comparison?: {++ mode?: "changed" | "threshold" | "none";++ tolerance?: number | null;++ percent?: number | null;++ } | null;++ condition: {++ op?: "changed" | "gt" | "gte" | "lt" | "lte" | "eq" | "ne" | "contains" | "matches" | "exists" | "absent";++ value?: string | number | null;++ for_sec?: number | null;++ };++ /**++ * @minItems 1++ * @maxItems 8++ */++ action:++ | [++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ]++ | [++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ )++ ]++ | [++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ )++ ]++ | [++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ )++ ]++ | [++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ )++ ]++ | [++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ )++ ]++ | [++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ )++ ]++ | [++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ )++ ];++ budget?: {++ checks_per_day?: number | null;++ usd_per_month?: number | null;++ max_runtime_ms?: number | null;++ max_bytes?: number | null;++ };++ retention?: {++ observations_days?: number | null;++ keep_snapshots?: boolean;++ };++ health?: {++ [k: string]: unknown | undefined;++ } | null;++ created_at: string;++ updated_at: string;++}++++/** [email protected] (owner: watch) */++/**++ * watch.watch-request@1: the body of POST /api/v1/watches and PATCH /api/v1/watches/:id on OpenVibe.Watch (watch.watch.manage; the acting person). Every field is optional on a patch; a create requires source, extraction, condition and action, which the service enforces in code (422 watch.invalid).++ */++export interface WatchRequest {++ name?: string;++ labels?: {++ [k: string]: string | undefined;++ };++ source?:++ | {++ kind: "webhook";++ endpoint?: string;++ }++ | {++ kind: "event";++ pattern: string;++ filter?: {++ [k: string]: (string | number | boolean | null) | undefined;++ } | null;++ }++ | {++ kind: "http" | "feed" | "api";++ url: string;++ method?: "GET" | "HEAD";++ format?: "rss" | "atom" | "json" | null;++ items_path?: string | null;++ fields?: {++ [k: string]: string | undefined;++ } | null;++ auth?: {++ mode: "none" | "header" | "bearer" | "query";++ /**++ * The name of the environment variable holding the credential; Watch reads it by name at fetch time and never stores the value.++ */++ env?: string | null;++ header?: string | null;++ param?: string | null;++ };++ headers?: {++ [k: string]: string | undefined;++ };++ /**++ * Send If-None-Match / If-Modified-Since from the stored ETag/Last-Modified when the server gave one.++ */++ conditional?: boolean;++ }++ | {++ kind: "node";++ node_id: string;++ probe: {++ [k: string]: unknown | undefined;++ };++ }++ | {++ kind: "run";++ runtime: "browser" | "code" | "desktop";++ url?: string | null;++ /**++ * @minItems 1++ */++ steps: [++ {++ [k: string]: unknown | undefined;++ },++ ...{++ [k: string]: unknown | undefined;++ }[]++ ];++ workload?: WorkloadRequirements;++ };++ /**++ * Required for http/feed/api/node sources; null for event/webhook sources (they never poll).++ */++ cadence?: {++ every_sec?: number;++ jitter_sec?: number;++ timezone?: string | null;++ } | null;++ extraction?: {++ kind?: "text" | "html" | "json" | "regex" | "css" | "jsonpath" | "ai";++ selector?: string | null;++ fields?: {++ [k: string]: string | undefined;++ } | null;++ value_path?: string | null;++ ai?: {++ [k: string]: unknown | undefined;++ } | null;++ };++ comparison?: {++ mode?: "changed" | "threshold" | "none";++ tolerance?: number | null;++ percent?: number | null;++ } | null;++ condition?: {++ op?: "changed" | "gt" | "gte" | "lt" | "lte" | "eq" | "ne" | "contains" | "matches" | "exists" | "absent";++ value?: string | number | null;++ for_sec?: number | null;++ };++ /**++ * @minItems 1++ * @maxItems 8++ */++ action?:++ | [++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ]++ | [++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ )++ ]++ | [++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ )++ ]++ | [++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ )++ ]++ | [++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ )++ ]++ | [++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ )++ ]++ | [++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ )++ ]++ | [++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ ),++ (++ | {++ kind: "notification";++ category?: "service" | "social" | "system";++ priority?: "low" | "normal" | "high" | "critical";++ }++ | {++ kind: "event";++ event_type: string;++ payload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ | {++ kind: "webhook";++ url: string;++ secret_env: string;++ }++ | {++ kind: "actor-task";++ brief: string;++ budget_usd?: number | null;++ }++ | {++ kind: "codes-run";++ repo: string;++ brief: string;++ }++ | {++ kind: "run-job";++ runtime: "function" | "code" | "browser" | "linux";++ command: string;++ workload?: {++ [k: string]: unknown | undefined;++ } | null;++ }++ )++ ];++ budget?: {++ checks_per_day?: number | null;++ usd_per_month?: number | null;++ max_runtime_ms?: number | null;++ max_bytes?: number | null;++ };++ retention?: {++ observations_days?: number | null;++ keep_snapshots?: boolean;++ };++ status?: "active" | "paused" | "disabled" | "failed";++}++++/** [email protected] (owner: watch) */++/**++ * watch.watch-result@1: answers of the watch routes on OpenVibe.Watch. GET /api/v1/watches → { watches } and POST /api/v1/watches → 201 { watch } (watch.watch.read, watch.watch.manage); PATCH → { watch }; POST /:id/pause and /:id/resume → { id, status }; DELETE /api/v1/watches/:id → { id, deleted: true }.++ */++export type WatchResult =++ | {++ watches: Watch[];++ }++ | {++ watch: Watch;++ }++ | {++ id: string;++ status: "active" | "paused" | "disabled" | "failed";++ }++ | {++ id: string;++ deleted: true;++ };++++/** [email protected] (owner: watch) */++/**++ * watch.observation@1: one value a check recorded for a watch (plan T18): what was extracted, when, from which check run, and whether it changed or met the condition. value is the extracted value exactly as the source stated it, never inferred; snapshot is a capped copy of the raw body kept according to the watch's retention. Rows are immutable.++ */++export interface WatchObservation {++ id: string;++ watch_id: string;++ check_run_id: string;++ observed_at: string;++ /**++ * The extracted value as the source stated it: text, a decimal number, a structured object.++ */++ value: {++ [k: string]: unknown | undefined;++ };++ /**++ * SHA-256 hex of the canonical value.++ */++ value_hash: string;++ /**++ * SHA-256 of the previous observation's value; null for the first observation.++ */++ previous_hash: string | null;++ changed: boolean;++ condition_met: boolean;++ snapshot: string | null;++}++++/** [email protected] (owner: watch) */++/**++ * watch.check-run@1: one execution of a watch's check (plan T18), by schedule, manually, or from a delivered event or webhook. carrier names the mechanism that carried it; state is the terminal state (the same values the service's check_runs.state CHECK allows). observations is how many observations the run recorded and triggers how many conditions it fired; cost_usd is what the run cost. Rows are immutable.++ */++export interface WatchCheckRun {++ id: string;++ watch_id: string;++ trigger: "schedule" | "manual" | "event" | "webhook";++ carrier: "event" | "webhook" | "http" | "feed" | "api" | "node" | "run" | null;++ started_at: string;++ finished_at: string;++ state:++ | "ok"++ | "not_modified"++ | "no_change"++ | "changed"++ | "condition_met"++ | "http_error"++ | "timeout"++ | "parse_error"++ | "rate_limited"++ | "budget_exceeded"++ | "skipped"++ | "disabled";++ http_status: number | null;++ observations: number;++ triggers: number;++ cost_usd: number;++ detail: string | null;++}++++/** [email protected] (owner: watch) */++/**++ * watch.observation.recorded v1 (OpenVibe.Watch, plan T18): a check recorded an observation for a watch. It carries the extracted value as the source stated it and its hash, never the raw body. Envelope: subject { type: watch, id: <watch_id> }, visibility internal, priority low, actor service:watch. Watch's own records are the full observation (watch.observation@1); this event is the notification that one exists.++ */++export interface WatchObservationRecordedPayload {++ watch_id: string;++ /**++ * The watch owner's subject id: who this observation is for.++ */++ owner: string;++ observed_at: string;++ /**++ * The extracted value as the source stated it; null when it stated none.++ */++ value: {++ [k: string]: unknown | undefined;++ };++ /**++ * SHA-256 hex of the canonical value.++ */++ value_hash: string;++ changed: boolean;++ condition_met: boolean;++}++++/** [email protected] (owner: watch) */++/**++ * watch.watch.triggered v1 (OpenVibe.Watch, plan T18; the dossier's watch.triggered, named with three segments as every event type is here — the repo's event-type pattern requires at least three): a watch's condition fired. OpenVibe.Network turns it into a WATCH_TRIGGERED notification for payload.recipient (mirrors deals.watch.matched). Envelope: subject { type: watch, id: <watch_id> }, visibility internal, priority important, actor service:watch.++ */++export interface WatchTriggeredPayload {++ watch_id: string;++ /**++ * The watch owner's user subject id: who is notified.++ */++ recipient: string;++ project_id: string | null;++ name: string;++ condition: {++ op?: "changed" | "gt" | "gte" | "lt" | "lte" | "eq" | "ne" | "contains" | "matches" | "exists" | "absent";++ value?: string | number | null;++ for_sec?: number | null;++ };++ observation: {++ id: string;++ observed_at: string;++ /**++ * The value that fired the condition.++ */++ value: {++ [k: string]: unknown | undefined;++ };++ /**++ * The previous observation's value; null when there was none.++ */++ previous_value: {++ [k: string]: unknown | undefined;++ };++ };++ fired_at: string;++}++++/** [email protected] (owner: watch) */++/**++ * watch.check.failed v1 (OpenVibe.Watch, plan T18): a check ended in a failure state. consecutive_failures is how many runs in a row have failed, so a consumer can tell a blip from a watch that is down. Envelope: subject { type: watch, id: <watch_id> }, visibility internal, priority normal, actor service:watch.++ */++export interface WatchCheckFailedPayload {++ watch_id: string;++ state: "http_error" | "timeout" | "parse_error" | "rate_limited" | "budget_exceeded" | "skipped" | "disabled";++ carrier: "event" | "webhook" | "http" | "feed" | "api" | "node" | "run" | null;++ http_status: number | null;++ error_code: string | null;++ consecutive_failures: number;++}++/** [email protected] (owner: games) *//*** games.player.joined v1 (OpenVibe.Games apps/server/src/platform/gameEvents.ts playerJoinedEvent, via GameEventRecorder.recordJoin from game/gameServer.ts handleHello). A character entered the world: written to Games' event_outbox in a transaction of its own once the session exists and the welcome was sent (a new character's row is first written by its next save). restored is true when the character already existed in the database, false for a new one. Only emitted while Events publishing is configured. No position, appearance, inventory, rank or connection data. Envelope: subject { type: player, id: <player.id> }, visibility subject when the player has a Network subject and internal otherwise, priority low, actor user:<usr_...> or guest:<gst_...> from player.subject, else service:games. No consumer yet.@@@ -51677,7 +54769,7 @@ export type ResourceOffer = {*/trust: "first-party" | "user-owned" | "partner" | "community" | "external";/**-- * e.g. node:http, worker:browser, worker:ffmpeg, worker:ai-gpu, events:gateway, events:durable, object:r2. Kind harness: task:edit, task:review, task:browse, task:run, task:test and task:plan for the task kinds it takes (its detail's task_capabilities), and harness:mcp, harness:resume, harness:host-access and harness:long-autonomy for its detail's capabilities that are true. The `worker:<class>` names that map to platform.runtime-class@1 values are reserved for OpenVibe.Node's job worker, one per class: worker:function, worker:code, worker:browser, worker:linux, worker:desktop and worker:gpu ($defs.reservedWorkerCapabilities). A node advertises the name of each class it runs (Node's status.capabilities.worker); every other `worker:` name (worker:ffmpeg, worker:ai-gpu) is an ordinary capability name.++ * e.g. node:http, worker:browser, worker:ffmpeg, worker:ai-gpu, events:gateway, events:durable, object:r2. Kind harness: task:edit, task:review, task:browse, task:run, task:test and task:plan for the task kinds it takes (its detail's task_capabilities), and harness:mcp, harness:resume, harness:host-access and harness:long-autonomy for its detail's capabilities that are true. The `worker:<class>` names that map to platform.runtime-class@1 values are reserved for OpenVibe.Node's job worker, one per class: worker:function, worker:code, worker:browser, worker:linux, worker:desktop and worker:gpu ($defs.reservedWorkerCapabilities). A node advertises the name of each class it runs (Node's status.capabilities.worker); every other `worker:` name (worker:ffmpeg, worker:ai-gpu) is an ordinary capability name. Beside them, a kind harness names `runtime:<class>` for each platform.runtime-class@1 class it can run (runtime:function, runtime:code, runtime:browser, runtime:linux, runtime:desktop, runtime:gpu); these are ordinary capability names, not reserved, and OpenVibe.Codes already advertises the classes it offers.*/capabilities: string[];capacity?: {nnew file mode 100644@@@ -0,0 +1,19 @@++{++ "id": "watch.check.run",++ "version": "1.0",++ "owner": "watch",++ "status": "planned",++ "visibility": "first-party",++ "description": "PLANNED (plan T18; OpenVibe.Watch is not built yet): Run one check of a watch now, outside its cadence: POST /api/v1/watches/:id/check (409 watch.busy when one is already running). It becomes active, and enters generated/openapi/watch.json, when OpenVibe.Watch implements the route.",++ "permissions": [++ "watch:run"++ ],++ "resourceConstraints": [++ "owner"++ ],++ "quotaClass": "watch-run",++ "events": [],++ "implementedBy": [],++ "inputSchema": "common.no-body@1",++ "outputSchema": "watch.check-run@1"++}nnew file mode 100644@@@ -0,0 +1,19 @@++{++ "id": "watch.observation.read",++ "version": "1.0",++ "owner": "watch",++ "status": "planned",++ "visibility": "first-party",++ "description": "PLANNED (plan T18; OpenVibe.Watch is not built yet): Read a watch's observations and check runs: GET /api/v1/watches/:id/observations and GET /api/v1/watches/:id/checks. It becomes active, and enters generated/openapi/watch.json, when OpenVibe.Watch implements the routes.",++ "permissions": [++ "watch:read"++ ],++ "resourceConstraints": [++ "owner"++ ],++ "quotaClass": "watch-read",++ "events": [],++ "implementedBy": [],++ "inputSchema": "common.no-body@1",++ "outputSchema": "watch.observation@1"++}nnew file mode 100644@@@ -0,0 +1,24 @@++{++ "id": "watch.watch.manage",++ "version": "1.0",++ "owner": "watch",++ "status": "planned",++ "visibility": "first-party",++ "description": "PLANNED (plan T18; OpenVibe.Watch is not built yet): Create, change, pause, resume and delete a watch: POST /api/v1/watches, PATCH /api/v1/watches/:id, POST /api/v1/watches/:id/pause, POST /api/v1/watches/:id/resume and DELETE /api/v1/watches/:id. It becomes active, and enters generated/openapi/watch.json, when OpenVibe.Watch implements the routes.",++ "permissions": [++ "watch:manage"++ ],++ "resourceConstraints": [++ "owner"++ ],++ "quotaClass": "watch-write",++ "events": [++ "watch.watch.created",++ "watch.watch.updated",++ "watch.watch.paused",++ "watch.watch.removed"++ ],++ "implementedBy": [],++ "inputSchema": "watch.watch-request@1",++ "outputSchema": "watch.watch-result@1"++}nnew file mode 100644@@@ -0,0 +1,19 @@++{++ "id": "watch.watch.read",++ "version": "1.0",++ "owner": "watch",++ "status": "planned",++ "visibility": "first-party",++ "description": "PLANNED (plan T18; OpenVibe.Watch is not built yet): List and read the acting person's or project's watches: GET /api/v1/watches and GET /api/v1/watches/:id. It becomes active, and enters generated/openapi/watch.json, when OpenVibe.Watch implements the routes.",++ "permissions": [++ "watch:read"++ ],++ "resourceConstraints": [++ "owner"++ ],++ "quotaClass": "watch-read",++ "events": [],++ "implementedBy": [],++ "inputSchema": "common.no-body@1",++ "outputSchema": "watch.watch-result@1"++}@@@ -27,6 +27,7 @@"keywords": "website change monitoring, uptime monitoring api, price drop alerts, restock alerts, release monitoring, youtube video analysis, security camera alerts","launch": "the watch service on the shared queue and workers","relationships": {++ "service": "watch","noRepo": true,"meanwhile": [{nnew file mode 100644@@@ -0,0 +1,57 @@++{++ "version": "0.0.0",++ "contractRanges": {++ "openvibe-contracts": ">=0.102.0 <1.0.0"++ },++ "id": "watch",++ "name": "OpenVibe.Watch",++ "status": "placeholder",++ "repository": "OpenVibers/OpenVibe.Watch",++ "domains": [++ "openvibe.watch"++ ],++ "publicOrigin": "https://openvibe.watch",++ "exposure": {++ "state": "placeholder",++ "publicSite": null,++ "note": "planned (plan T18); the OpenVibe.Watch repository does not exist yet, and nothing serves openvibe.watch"++ },++ "capabilities": [++ "watch.watch.read",++ "watch.watch.manage",++ "watch.observation.read",++ "watch.check.run"++ ],++ "eventsProduced": [++ "watch.watch.created",++ "watch.watch.updated",++ "watch.watch.paused",++ "watch.watch.removed",++ "watch.observation.recorded",++ "watch.watch.triggered",++ "watch.check.failed"++ ],++ "eventsConsumed": [],++ "namespacesOwned": [],++ "lifecycle": {++ "liveness": {++ "none": "not built yet; nothing listens on a loopback address"++ },++ "shutdown": {++ "none": "not built yet; nothing runs or drains"++ },++ "startupRecovery": {++ "none": "not built yet; nothing starts"++ },++ "rollback": {++ "none": "not built yet; nothing is released or rolled back"++ },++ "contracts": {++ "range": ">=0.102.0 <1.0.0"++ },++ "leases": {++ "none": "not built yet; nothing runs"++ }++ },++ "notes": "The watch service of the network (plan T18): a user defines persistent observations and conditions over pages, feeds, APIs, events, releases, streams and local devices, and is told when they change or wakes an Actor task, a Codes run, a Run job or a webhook. Sources ingests structured sources, Run runs expensive browser/code checks, Node observes local/LAN things, Events transports the trigger. Planned: nothing is built; the OpenVibe.Watch repository does not exist yet."++}@@@ -1,12 +1,12 @@{"name": "openvibe-contracts",-- "version": "0.101.0",++ "version": "0.102.0","lockfileVersion": 3,"requires": true,"packages": {"": {"name": "openvibe-contracts",-- "version": "0.101.0",++ "version": "0.102.0","license": "AGPL-3.0-only","dependencies": {"ajv": "^8.17.1",@@@ -1,6 +1,6 @@{"name": "openvibe-contracts",-- "version": "0.101.0",++ "version": "0.102.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",
@@ -4,6 +4,28 @@ All notable changes to `openvibe-contracts`. Releases are git tags (`vX.Y.Z`) th
@@ -4,6 +4,28 @@ All notable changes to `openvibe-contracts`. Releases are git tags (`vX.Y.Z`) th
from `https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/<tag>`. Before v0.30.0,
from `https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/<tag>`. Before v0.30.0,
the notes were in the tag and commit messages (`git tag -n1`).
the notes were in the tag and commit messages (`git tag -n1`).
+## 0.102.0 — 2026-10-05
+
+**The Watch contracts** (plan T18). Additive: eight new planned contracts, four planned capabilities and the Watch placeholder manifest, no existing schema changed.
+- `watch.watch@1` (new, owner `watch`, first-party, **planned**): a user-defined persistent observation — a source (a push event, a
+ webhook, a conditional HTTP URL, a feed or API, a local Node probe, or a Run check), how a value is extracted, how it is compared with
+ the last observation, the condition that fires, the actions it wakes (notification, event, webhook, Actor task, Codes run, Run job),
+ its budget and retention. Valid and invalid fixtures in `fixtures/watch.watch/`.
+- `watch.watch-request@1` (the create/patch body), `watch.watch-result@1` (the list/watch and pause/resume/delete answers),
+ `watch.observation@1` (one recorded value, immutable) and `watch.check-run@1` (one check execution, immutable, with the twelve
+ terminal states the service's `check_runs.state` CHECK allows), each with fixtures. The request reuses `watch.watch@1`'s `$defs`
+ rather than restating the source and condition shapes.
+- Events: `watch.observation.recorded` (subject `watch`, internal, low), `watch.watch.triggered` (internal, important; Network turns
+ it into a `WATCH_TRIGGERED` notification for `payload.recipient`) and `watch.check.failed` (internal, normal, with
+ `consecutive_failures`). **The dossier's `watch.triggered` is named `watch.watch.triggered` here**: the repo's event-type pattern
+ (`test/run.js:123`) requires at least three dot-separated segments, as every existing type has.
+- Capabilities `watch.watch.read`, `watch.watch.manage`, `watch.observation.read` and `watch.check.run` (all planned, first-party),
+ and `manifests/services/watch.json`, a placeholder like Run's: the OpenVibe.Watch repository does not exist yet, so nothing is
+ built. `manifests/products/openvibe.watch.json` now names `watch` as its service, as `openvibe.run` names `run`.
+- `contracts/platform/resource-offer.v1.json`: the `capabilities` description now documents `runtime:<class>` for a kind harness
+ beside the reserved `worker:<class>` names (a docs-only change; Codes already advertises them). `lib/ids.js` already carried
+ `watch`/`observation`/`check`, so it is untouched.
+
## 0.101.0 — 2026-10-05
## 0.101.0 — 2026-10-05
**The task contract** (plan T17, ADR-044). Additive: one new planned contract and its ADR, no existing schema changed.
**The task contract** (plan T17, ADR-044). Additive: one new planned contract and its ADR, no existing schema changed.
@@ -3,11 +3,13 @@
@@ -3,11 +3,13 @@
"stage": "alpha",
"stage": "alpha",
"code": true,
"code": true,
"wave": "W1",
"wave": "W1",
- "dependsOn": ["OpenVibe.Network"],
+ "dependsOn": [
+ "OpenVibe.Network"
+ ],
"plan": "OpenVibe Development Roadmap (combined), Wave 1; implementation plan rev 3 section 3.1",
"plan": "OpenVibe Development Roadmap (combined), Wave 1; implementation plan rev 3 section 3.1",
"deployed": false,
"deployed": false,
"deployment": "none of its own: a library and artifact repository published as release tags; services pin a tag and deploy it with their own releases",
"deployment": "none of its own: a library and artifact repository published as release tags; services pin a tag and deploy it with their own releases",
- "contracts": "openvibe-contracts v0.101.0 (this package; the newest tag)",
+ "contracts": "openvibe-contracts v0.102.0 (this package; the newest tag)",
"features": [
"features": [
"589 JSON Schemas with valid and invalid fixtures",
"589 JSON Schemas with valid and invalid fixtures",
"31 service manifests with lifecycle declarations",
"31 service manifests with lifecycle declarations",
@@ -20,7 +22,8 @@
@@ -20,7 +22,8 @@
"documentation-currency check (scripts/docs-currency.js)",
"documentation-currency check (scripts/docs-currency.js)",
"generated estate: docs/ESTATE.md and manifests/repositories/ from the checkouts (scripts/estate.js; --check fails on drift)",
"generated estate: docs/ESTATE.md and manifests/repositories/ from the checkouts (scripts/estate.js; --check fails on drift)",
"chat.ticket-conversation@1 and the planned chat.ticket.write capability: a per-ticket conversation keyed by ticket id and calling service, with author_kind person|agent|staff",
"chat.ticket-conversation@1 and the planned chat.ticket.write capability: a per-ticket conversation keyed by ticket id and calling service, with author_kind person|agent|staff",
- "platform.task@1 (planned, owner network) and ADR-044: one task at OpenVibe.Actor's router with a mode, a per-task and per-day budget, result, cost and explanation, SSE progress, cancel and webhooks"
+ "platform.task@1 (planned, owner network) and ADR-044: one task at OpenVibe.Actor's router with a mode, a per-task and per-day budget, result, cost and explanation, SSE progress, cancel and webhooks",
+ "watch.watch@1 and the other Watch contracts (plan T18, planned), three watch events, four capabilities and the placeholder service manifest: user-defined persistent observations over pages, feeds, APIs, events and devices"
],
],
"updated": "2026-10-05"
"updated": "2026-10-05"
}
}
@@ -4186,6 +4186,78 @@
@@ -4186,6 +4186,78 @@
"compatibility": "backward",
"compatibility": "backward",
"status": "active"
"status": "active"
},
},
+ {
+ "id": "watch.watch",
+ "version": "1.0.0",
+ "owner": "watch",
+ "schema": "watch/watch.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "planned"
+ },
+ {
+ "id": "watch.watch-request",
+ "version": "1.0.0",
+ "owner": "watch",
+ "schema": "watch/watch-request.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "planned"
+ },
+ {
+ "id": "watch.watch-result",
+ "version": "1.0.0",
+ "owner": "watch",
+ "schema": "watch/watch-result.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "planned"
+ },
+ {
+ "id": "watch.observation",
+ "version": "1.0.0",
+ "owner": "watch",
+ "schema": "watch/observation.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "planned"
+ },
+ {
+ "id": "watch.check-run",
+ "version": "1.0.0",
+ "owner": "watch",
+ "schema": "watch/check-run.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "planned"
+ },
+ {
+ "id": "watch.observation.recorded",
+ "version": "1.0.0",
+ "owner": "watch",
+ "schema": "events/payloads/watch.observation.recorded.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "planned"
+ },
+ {
+ "id": "watch.watch.triggered",
+ "version": "1.0.0",
+ "owner": "watch",
+ "schema": "events/payloads/watch.watch.triggered.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "planned"
+ },
+ {
+ "id": "watch.check.failed",
+ "version": "1.0.0",
+ "owner": "watch",
+ "schema": "events/payloads/watch.check.failed.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "planned"
+ },
{
{
"id": "games.player.joined",
"id": "games.player.joined",
"version": "1.0.0",
"version": "1.0.0",
new file mode 100644
new file mode 100644
@@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/events/payloads/watch.check.failed.v1.json",
+ "title": "WatchCheckFailedPayload",
+ "description": "watch.check.failed v1 (OpenVibe.Watch, plan T18): a check ended in a failure state. consecutive_failures is how many runs in a row have failed, so a consumer can tell a blip from a watch that is down. Envelope: subject { type: watch, id: <watch_id> }, visibility internal, priority normal, actor service:watch.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["watch_id", "state", "carrier", "http_status", "error_code", "consecutive_failures"],
+ "properties": {
+ "watch_id": { "type": "string", "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$" },
+ "state": { "enum": ["http_error", "timeout", "parse_error", "rate_limited", "budget_exceeded", "skipped", "disabled"] },
+ "carrier": { "type": ["string", "null"], "enum": ["event", "webhook", "http", "feed", "api", "node", "run", null] },
+ "http_status": { "type": ["integer", "null"] },
+ "error_code": { "type": ["string", "null"] },
+ "consecutive_failures": { "type": "integer", "minimum": 1 }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/events/payloads/watch.observation.recorded.v1.json",
+ "title": "WatchObservationRecordedPayload",
+ "description": "watch.observation.recorded v1 (OpenVibe.Watch, plan T18): a check recorded an observation for a watch. It carries the extracted value as the source stated it and its hash, never the raw body. Envelope: subject { type: watch, id: <watch_id> }, visibility internal, priority low, actor service:watch. Watch's own records are the full observation (watch.observation@1); this event is the notification that one exists.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["watch_id", "owner", "observed_at", "value", "value_hash", "changed", "condition_met"],
+ "properties": {
+ "watch_id": { "type": "string", "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$" },
+ "owner": { "type": "string", "pattern": "^(usr|agt)_[0-9A-HJKMNP-TV-Z]{26}$", "description": "The watch owner's subject id: who this observation is for." },
+ "observed_at": { "type": "string", "format": "date-time" },
+ "value": { "description": "The extracted value as the source stated it; null when it stated none." },
+ "value_hash": { "type": "string", "pattern": "^[0-9a-f]{64}$", "description": "SHA-256 hex of the canonical value." },
+ "changed": { "type": "boolean" },
+ "condition_met": { "type": "boolean" }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/events/payloads/watch.watch.triggered.v1.json",
+ "title": "WatchTriggeredPayload",
+ "description": "watch.watch.triggered v1 (OpenVibe.Watch, plan T18; the dossier's watch.triggered, named with three segments as every event type is here — the repo's event-type pattern requires at least three): a watch's condition fired. OpenVibe.Network turns it into a WATCH_TRIGGERED notification for payload.recipient (mirrors deals.watch.matched). Envelope: subject { type: watch, id: <watch_id> }, visibility internal, priority important, actor service:watch.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["watch_id", "recipient", "project_id", "name", "condition", "observation", "fired_at"],
+ "properties": {
+ "watch_id": { "type": "string", "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$" },
+ "recipient": { "type": "string", "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$", "description": "The watch owner's user subject id: who is notified." },
+ "project_id": { "type": ["string", "null"], "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$" },
+ "name": { "type": "string", "minLength": 1, "maxLength": 120 },
+ "condition": { "$ref": "../../watch/watch.v1.json#/$defs/condition" },
+ "observation": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["id", "observed_at", "value", "previous_value"],
+ "properties": {
+ "id": { "type": "string", "pattern": "^wco_[0-9A-HJKMNP-TV-Z]{26}$" },
+ "observed_at": { "type": "string", "format": "date-time" },
+ "value": { "description": "The value that fired the condition." },
+ "previous_value": { "description": "The previous observation's value; null when there was none." }
+ }
+ },
+ "fired_at": { "type": "string", "format": "date-time" }
+ }
+}
@@ -66,7 +66,7 @@
@@ -66,7 +66,7 @@
"type": "string",
"type": "string",
"pattern": "^[a-z][a-z0-9-]*:[a-z0-9.-]+$"
"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. Kind harness: task:edit, task:review, task:browse, task:run, task:test and task:plan for the task kinds it takes (its detail's task_capabilities), and harness:mcp, harness:resume, harness:host-access and harness:long-autonomy for its detail's capabilities that are true. The `worker:<class>` names that map to platform.runtime-class@1 values are reserved for OpenVibe.Node's job worker, one per class: worker:function, worker:code, worker:browser, worker:linux, worker:desktop and worker:gpu ($defs.reservedWorkerCapabilities). A node advertises the name of each class it runs (Node's status.capabilities.worker); every other `worker:` name (worker:ffmpeg, worker:ai-gpu) is an ordinary capability name."
+ "description": "e.g. node:http, worker:browser, worker:ffmpeg, worker:ai-gpu, events:gateway, events:durable, object:r2. Kind harness: task:edit, task:review, task:browse, task:run, task:test and task:plan for the task kinds it takes (its detail's task_capabilities), and harness:mcp, harness:resume, harness:host-access and harness:long-autonomy for its detail's capabilities that are true. The `worker:<class>` names that map to platform.runtime-class@1 values are reserved for OpenVibe.Node's job worker, one per class: worker:function, worker:code, worker:browser, worker:linux, worker:desktop and worker:gpu ($defs.reservedWorkerCapabilities). A node advertises the name of each class it runs (Node's status.capabilities.worker); every other `worker:` name (worker:ffmpeg, worker:ai-gpu) is an ordinary capability name. Beside them, a kind harness names `runtime:<class>` for each platform.runtime-class@1 class it can run (runtime:function, runtime:code, runtime:browser, runtime:linux, runtime:desktop, runtime:gpu); these are ordinary capability names, not reserved, and OpenVibe.Codes already advertises the classes it offers."
},
},
"capacity": {
"capacity": {
"type": "object",
"type": "object",
new file mode 100644
new file mode 100644
@@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/watch/check-run.v1.json",
+ "title": "WatchCheckRun",
+ "description": "watch.check-run@1: one execution of a watch's check (plan T18), by schedule, manually, or from a delivered event or webhook. carrier names the mechanism that carried it; state is the terminal state (the same values the service's check_runs.state CHECK allows). observations is how many observations the run recorded and triggers how many conditions it fired; cost_usd is what the run cost. Rows are immutable.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["id", "watch_id", "trigger", "carrier", "started_at", "finished_at", "state", "http_status", "observations", "triggers", "cost_usd", "detail"],
+ "properties": {
+ "id": { "type": "string", "pattern": "^ckr_[0-9A-HJKMNP-TV-Z]{26}$" },
+ "watch_id": { "type": "string", "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$" },
+ "trigger": { "enum": ["schedule", "manual", "event", "webhook"] },
+ "carrier": { "type": ["string", "null"], "enum": ["event", "webhook", "http", "feed", "api", "node", "run", null] },
+ "started_at": { "type": "string", "format": "date-time" },
+ "finished_at": { "type": "string", "format": "date-time" },
+ "state": { "enum": ["ok", "not_modified", "no_change", "changed", "condition_met", "http_error", "timeout", "parse_error", "rate_limited", "budget_exceeded", "skipped", "disabled"] },
+ "http_status": { "type": ["integer", "null"] },
+ "observations": { "type": "integer", "minimum": 0 },
+ "triggers": { "type": "integer", "minimum": 0 },
+ "cost_usd": { "type": "number", "minimum": 0 },
+ "detail": { "type": ["string", "null"] }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/watch/observation.v1.json",
+ "title": "WatchObservation",
+ "description": "watch.observation@1: one value a check recorded for a watch (plan T18): what was extracted, when, from which check run, and whether it changed or met the condition. value is the extracted value exactly as the source stated it, never inferred; snapshot is a capped copy of the raw body kept according to the watch's retention. Rows are immutable.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["id", "watch_id", "check_run_id", "observed_at", "value", "value_hash", "previous_hash", "changed", "condition_met", "snapshot"],
+ "properties": {
+ "id": { "type": "string", "pattern": "^wco_[0-9A-HJKMNP-TV-Z]{26}$" },
+ "watch_id": { "type": "string", "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$" },
+ "check_run_id": { "type": "string", "pattern": "^ckr_[0-9A-HJKMNP-TV-Z]{26}$" },
+ "observed_at": { "type": "string", "format": "date-time" },
+ "value": { "description": "The extracted value as the source stated it: text, a decimal number, a structured object." },
+ "value_hash": { "type": "string", "pattern": "^[0-9a-f]{64}$", "description": "SHA-256 hex of the canonical value." },
+ "previous_hash": { "type": ["string", "null"], "pattern": "^[0-9a-f]{64}$", "description": "SHA-256 of the previous observation's value; null for the first observation." },
+ "changed": { "type": "boolean" },
+ "condition_met": { "type": "boolean" },
+ "snapshot": { "type": ["string", "null"] }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/watch/watch-request.v1.json",
+ "title": "WatchRequest",
+ "description": "watch.watch-request@1: the body of POST /api/v1/watches and PATCH /api/v1/watches/:id on OpenVibe.Watch (watch.watch.manage; the acting person). Every field is optional on a patch; a create requires source, extraction, condition and action, which the service enforces in code (422 watch.invalid).",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": { "type": "string", "minLength": 1, "maxLength": 120 },
+ "labels": { "type": "object", "additionalProperties": { "type": "string", "maxLength": 60 } },
+ "source": { "$ref": "watch.v1.json#/$defs/source" },
+ "cadence": { "$ref": "watch.v1.json#/$defs/cadence" },
+ "extraction": { "$ref": "watch.v1.json#/$defs/extraction" },
+ "comparison": { "$ref": "watch.v1.json#/$defs/comparison" },
+ "condition": { "$ref": "watch.v1.json#/$defs/condition" },
+ "action": { "type": "array", "minItems": 1, "maxItems": 8, "items": { "$ref": "watch.v1.json#/$defs/action" } },
+ "budget": { "$ref": "watch.v1.json#/$defs/budget" },
+ "retention": { "$ref": "watch.v1.json#/$defs/retention" },
+ "status": { "enum": ["active", "paused", "disabled", "failed"] }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/watch/watch-result.v1.json",
+ "title": "WatchResult",
+ "description": "watch.watch-result@1: answers of the watch routes on OpenVibe.Watch. GET /api/v1/watches → { watches } and POST /api/v1/watches → 201 { watch } (watch.watch.read, watch.watch.manage); PATCH → { watch }; POST /:id/pause and /:id/resume → { id, status }; DELETE /api/v1/watches/:id → { id, deleted: true }.",
+ "anyOf": [
+ {
+ "type": "object",
+ "required": ["watches"],
+ "additionalProperties": false,
+ "properties": { "watches": { "type": "array", "items": { "$ref": "watch.v1.json" } } }
+ },
+ {
+ "type": "object",
+ "required": ["watch"],
+ "additionalProperties": false,
+ "properties": { "watch": { "$ref": "watch.v1.json" } }
+ },
+ {
+ "type": "object",
+ "required": ["id", "status"],
+ "additionalProperties": false,
+ "properties": {
+ "id": { "type": "string", "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$" },
+ "status": { "enum": ["active", "paused", "disabled", "failed"] }
+ }
+ },
+ {
+ "type": "object",
+ "required": ["id", "deleted"],
+ "additionalProperties": false,
+ "properties": {
+ "id": { "type": "string", "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$" },
+ "deleted": { "const": true }
+ }
+ }
+ ]
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,102 @@
@@ -0,0 +1,102 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/watch/watch.v1.json",
+ "title": "Watch",
+ "description": "watch.watch@1: a user-defined persistent observation (plan T18). It names a source (a push event, a webhook, a conditional HTTP URL, a feed or API, a local Node probe, or an expensive Run check), how a value is extracted, how it is compared with the last observation, the condition that fires, the actions it wakes, its budget and its retention. Carrier preference is binding: an event or webhook source is used when one exists, then ETag/Last-Modified, then a feed, then an API, and browser polling through Run only when none works. A price or stock is 'as of' the observation, null when it stated none.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["id", "owner", "status", "source", "extraction", "condition", "action", "created_at", "updated_at"],
+ "properties": {
+ "id": { "type": "string", "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$" },
+ "project_id": { "type": ["string", "null"], "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$" },
+ "owner": { "type": "string", "description": "The acting person or agent the watch belongs to: usr_…, agt_… or svc:…." },
+ "name": { "type": "string", "minLength": 1, "maxLength": 120 },
+ "labels": { "type": "object", "additionalProperties": { "type": "string", "maxLength": 60 } },
+ "status": { "enum": ["active", "paused", "disabled", "failed"] },
+ "source": { "$ref": "#/$defs/source" },
+ "cadence": { "$ref": "#/$defs/cadence" },
+ "extraction": { "$ref": "#/$defs/extraction" },
+ "comparison": { "$ref": "#/$defs/comparison" },
+ "condition": { "$ref": "#/$defs/condition" },
+ "action": { "type": "array", "minItems": 1, "maxItems": 8, "items": { "$ref": "#/$defs/action" } },
+ "budget": { "$ref": "#/$defs/budget" },
+ "retention": { "$ref": "#/$defs/retention" },
+ "health": { "type": ["object", "null"], "additionalProperties": true },
+ "created_at": { "type": "string", "format": "date-time" },
+ "updated_at": { "type": "string", "format": "date-time" }
+ },
+ "$defs": {
+ "auth": {
+ "type": "object",
+ "required": ["mode"],
+ "additionalProperties": false,
+ "properties": {
+ "mode": { "enum": ["none", "header", "bearer", "query"] },
+ "env": { "type": ["string", "null"], "pattern": "^WATCH_CRED_[A-Z0-9_]{2,60}$", "description": "The name of the environment variable holding the credential; Watch reads it by name at fetch time and never stores the value." },
+ "header": { "type": ["string", "null"] },
+ "param": { "type": ["string", "null"] }
+ }
+ },
+ "source": {
+ "oneOf": [
+ { "type": "object", "required": ["kind"], "additionalProperties": false,
+ "properties": { "kind": { "const": "webhook" }, "endpoint": { "type": "string", "pattern": "^/internal/hooks/" } } },
+ { "type": "object", "required": ["kind", "pattern"], "additionalProperties": false,
+ "properties": { "kind": { "const": "event" }, "pattern": { "type": "string", "pattern": "^[a-z][a-z0-9_-]*(\\.[a-z0-9_*]+){1,}$" },
+ "filter": { "type": ["object", "null"], "additionalProperties": { "type": ["string", "number", "boolean", "null"] } } } },
+ { "type": "object", "required": ["kind", "url"], "additionalProperties": false,
+ "properties": { "kind": { "enum": ["http", "feed", "api"] }, "url": { "type": "string", "format": "uri", "pattern": "^https?://" },
+ "method": { "enum": ["GET", "HEAD"] }, "format": { "enum": ["rss", "atom", "json", null] },
+ "items_path": { "type": ["string", "null"] }, "fields": { "type": ["object", "null"], "additionalProperties": { "type": "string" } },
+ "auth": { "$ref": "#/$defs/auth" }, "headers": { "type": "object", "additionalProperties": { "type": "string" } },
+ "conditional": { "type": "boolean", "description": "Send If-None-Match / If-Modified-Since from the stored ETag/Last-Modified when the server gave one." } } },
+ { "type": "object", "required": ["kind", "node_id", "probe"], "additionalProperties": false,
+ "properties": { "kind": { "const": "node" }, "node_id": { "type": "string" }, "probe": { "type": "object", "additionalProperties": true } } },
+ { "type": "object", "required": ["kind", "runtime", "steps"], "additionalProperties": false,
+ "properties": { "kind": { "const": "run" }, "runtime": { "enum": ["browser", "code", "desktop"] },
+ "url": { "type": ["string", "null"], "format": "uri" }, "steps": { "type": "array", "minItems": 1, "items": { "type": "object", "additionalProperties": true } },
+ "workload": { "$ref": "../platform/workload-requirements.v1.json" } } }
+ ]
+ },
+ "cadence": {
+ "type": ["object", "null"], "additionalProperties": false,
+ "description": "Required for http/feed/api/node sources; null for event/webhook sources (they never poll).",
+ "properties": { "every_sec": { "type": "integer", "minimum": 30, "maximum": 2592000 }, "jitter_sec": { "type": "integer", "minimum": 0, "maximum": 3600 }, "timezone": { "type": ["string", "null"] } }
+ },
+ "extraction": {
+ "type": "object", "additionalProperties": false,
+ "properties": { "kind": { "enum": ["text", "html", "json", "regex", "css", "jsonpath", "ai"] },
+ "selector": { "type": ["string", "null"] }, "fields": { "type": ["object", "null"], "additionalProperties": { "type": "string" } },
+ "value_path": { "type": ["string", "null"] }, "ai": { "type": ["object", "null"], "additionalProperties": true } }
+ },
+ "comparison": {
+ "type": ["object", "null"], "additionalProperties": false,
+ "properties": { "mode": { "enum": ["changed", "threshold", "none"] }, "tolerance": { "type": ["number", "null"] }, "percent": { "type": ["number", "null"] } }
+ },
+ "condition": {
+ "type": "object", "additionalProperties": false,
+ "properties": { "op": { "enum": ["changed", "gt", "gte", "lt", "lte", "eq", "ne", "contains", "matches", "exists", "absent"] },
+ "value": { "type": ["string", "number", "null"] }, "for_sec": { "type": ["integer", "null"], "minimum": 0 } }
+ },
+ "action": { "oneOf": [
+ { "type": "object", "required": ["kind"], "additionalProperties": false,
+ "properties": { "kind": { "const": "notification" }, "category": { "enum": ["service", "social", "system"] }, "priority": { "enum": ["low", "normal", "high", "critical"] } } },
+ { "type": "object", "required": ["kind", "event_type"], "additionalProperties": false,
+ "properties": { "kind": { "const": "event" }, "event_type": { "type": "string" }, "payload": { "type": ["object", "null"], "additionalProperties": true } } },
+ { "type": "object", "required": ["kind", "url", "secret_env"], "additionalProperties": false,
+ "properties": { "kind": { "const": "webhook" }, "url": { "type": "string", "format": "uri", "pattern": "^https://" }, "secret_env": { "type": "string", "pattern": "^WATCH_HOOK_[A-Z0-9_]{2,60}$" } } },
+ { "type": "object", "required": ["kind", "brief"], "additionalProperties": false,
+ "properties": { "kind": { "const": "actor-task" }, "brief": { "type": "string", "maxLength": 8000 }, "budget_usd": { "type": ["number", "null"] } } },
+ { "type": "object", "required": ["kind", "repo", "brief"], "additionalProperties": false,
+ "properties": { "kind": { "const": "codes-run" }, "repo": { "type": "string" }, "brief": { "type": "string", "maxLength": 8000 } } },
+ { "type": "object", "required": ["kind", "runtime", "command"], "additionalProperties": false,
+ "properties": { "kind": { "const": "run-job" }, "runtime": { "enum": ["function", "code", "browser", "linux"] }, "command": { "type": "string" }, "workload": { "type": ["object", "null"], "additionalProperties": true } } } ] },
+ "budget": {
+ "type": "object", "additionalProperties": false,
+ "properties": { "checks_per_day": { "type": ["integer", "null"], "minimum": 1 }, "usd_per_month": { "type": ["number", "null"], "minimum": 0 },
+ "max_runtime_ms": { "type": ["integer", "null"], "minimum": 100 }, "max_bytes": { "type": ["integer", "null"], "minimum": 1024 } }
+ },
+ "retention": { "type": "object", "additionalProperties": false,
+ "properties": { "observations_days": { "type": ["integer", "null"], "minimum": 1 }, "keep_snapshots": { "type": "boolean" } } }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
+{
+ "id": "ckr_01JAB2C3D4E5F6G7H8J9K0MNPT",
+ "watch_id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
+ "trigger": "schedule",
+ "carrier": "http",
+ "started_at": "2026-10-05T09:00:00.000Z",
+ "finished_at": "2026-10-05T09:00:01.250Z",
+ "state": "exploded",
+ "http_status": 200,
+ "observations": 1,
+ "triggers": 0,
+ "cost_usd": 0,
+ "detail": null
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
+{
+ "id": "ckr_01JAB2C3D4E5F6G7H8J9K0MNPT",
+ "watch_id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
+ "trigger": "schedule",
+ "carrier": "http",
+ "started_at": "2026-10-05T09:00:00.000Z",
+ "finished_at": "2026-10-05T09:00:01.250Z",
+ "state": "changed",
+ "http_status": 200,
+ "observations": 1,
+ "triggers": 0,
+ "cost_usd": 0,
+ "detail": null
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,8 @@
@@ -0,0 +1,8 @@
+{
+ "watch_id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
+ "state": "timeout",
+ "carrier": "api",
+ "http_status": null,
+ "error_code": "deadline_exceeded",
+ "consecutive_failures": 0
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,8 @@
@@ -0,0 +1,8 @@
+{
+ "watch_id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
+ "state": "http_error",
+ "carrier": "http",
+ "http_status": 503,
+ "error_code": "upstream_unavailable",
+ "consecutive_failures": 2
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,8 @@
@@ -0,0 +1,8 @@
+{
+ "watch_id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
+ "observed_at": "2026-10-05T09:00:00.000Z",
+ "value": 189.99,
+ "value_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ "changed": true,
+ "condition_met": true
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
+{
+ "watch_id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
+ "owner": "usr_01JAB2C3D4E5F6G7H8J9K0MNPR",
+ "observed_at": "2026-10-05T09:00:00.000Z",
+ "value": 189.99,
+ "value_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ "changed": true,
+ "condition_met": true
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
+{
+ "id": "wco_01JAB2C3D4E5F6G7H8J9K0MNPS",
+ "watch_id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
+ "observed_at": "2026-10-05T09:00:00.000Z",
+ "value": 189.99,
+ "value_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ "previous_hash": null,
+ "changed": true,
+ "condition_met": true,
+ "snapshot": null
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
+{
+ "id": "wco_01JAB2C3D4E5F6G7H8J9K0MNPS",
+ "watch_id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
+ "check_run_id": "ckr_01JAB2C3D4E5F6G7H8J9K0MNPT",
+ "observed_at": "2026-10-05T09:00:00.000Z",
+ "value": 189.99,
+ "value_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ "previous_hash": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+ "changed": true,
+ "condition_met": true,
+ "snapshot": "{\"price\":189.99,\"currency\":\"USD\"}"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
+{
+ "name": "Release 0.102.0 published",
+ "source": { "kind": "event", "pattern": "host.release.published" },
+ "condition": { "op": "changed" },
+ "action": [ { "kind": "notification" } ],
+ "status": "archived"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
+{
+ "name": "Release 0.102.0 published",
+ "source": { "kind": "event", "pattern": "host.release.published", "filter": null },
+ "cadence": null,
+ "extraction": { "kind": "json", "selector": null, "fields": null, "value_path": "$.release", "ai": null },
+ "comparison": { "mode": "changed", "tolerance": null, "percent": null },
+ "condition": { "op": "changed", "value": null, "for_sec": null },
+ "action": [ { "kind": "notification", "category": "service", "priority": "normal" } ],
+ "budget": { "checks_per_day": 100, "usd_per_month": 0, "max_runtime_ms": 5000, "max_bytes": 1048576 },
+ "retention": { "observations_days": 30, "keep_snapshots": false },
+ "status": "active"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{ "id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ", "deleted": false }
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{ "id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ", "status": "paused" }
new file mode 100644
new file mode 100644
@@ -0,0 +1,8 @@
@@ -0,0 +1,8 @@
+{
+ "watch_id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
+ "recipient": "usr_01JAB2C3D4E5F6G7H8J9K0MNPR",
+ "project_id": null,
+ "name": "Steam Deck OLED price",
+ "condition": { "op": "lt", "value": 199, "for_sec": null },
+ "fired_at": "2026-10-05T09:00:01.250Z"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
+{
+ "watch_id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
+ "recipient": "usr_01JAB2C3D4E5F6G7H8J9K0MNPR",
+ "project_id": null,
+ "name": "Steam Deck OLED price",
+ "condition": { "op": "lt", "value": 199, "for_sec": null },
+ "observation": {
+ "id": "wco_01JAB2C3D4E5F6G7H8J9K0MNPS",
+ "observed_at": "2026-10-05T09:00:00.000Z",
+ "value": 189.99,
+ "previous_value": 209.99
+ },
+ "fired_at": "2026-10-05T09:00:01.250Z"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
+{
+ "id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
+ "name": "Steam Deck OLED price",
+ "status": "active",
+ "source": { "kind": "api", "url": "https://openvibe.deals/api/offers/steam-deck-oled" },
+ "extraction": { "kind": "jsonpath", "value_path": "$.price" },
+ "condition": { "op": "lt", "value": 199 },
+ "action": [ { "kind": "notification" } ],
+ "created_at": "2026-10-05T08:00:00.000Z",
+ "updated_at": "2026-10-05T08:00:00.000Z"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
+{
+ "id": "wch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
+ "project_id": null,
+ "owner": "usr_01JAB2C3D4E5F6G7H8J9K0MNPR",
+ "name": "Steam Deck OLED price",
+ "labels": { "topic": "hardware" },
+ "status": "active",
+ "source": {
+ "kind": "api",
+ "url": "https://openvibe.deals/api/offers/steam-deck-oled",
+ "method": "GET",
+ "format": "json",
+ "items_path": "offers",
+ "fields": { "price": "price", "currency": "currency" },
+ "auth": { "mode": "none" },
+ "headers": {},
+ "conditional": true
+ },
+ "cadence": { "every_sec": 3600, "jitter_sec": 60, "timezone": null },
+ "extraction": { "kind": "jsonpath", "selector": null, "fields": null, "value_path": "$.offers[0].price", "ai": null },
+ "comparison": { "mode": "threshold", "tolerance": 0.01, "percent": null },
+ "condition": { "op": "lt", "value": 199, "for_sec": null },
+ "action": [ { "kind": "notification", "category": "service", "priority": "high" } ],
+ "budget": { "checks_per_day": 100, "usd_per_month": 0, "max_runtime_ms": 20000, "max_bytes": 5242880 },
+ "retention": { "observations_days": 90, "keep_snapshots": false },
+ "health": null,
+ "created_at": "2026-10-05T08:00:00.000Z",
+ "updated_at": "2026-10-05T08:00:00.000Z"
+}
@@ -46078,6 +46078,1184 @@
@@ -46078,6 +46078,1184 @@
}
}
}
}
},
},
+ "watch.watch": {
+ "version": "1.0.0",
+ "owner": "watch",
+ "status": "planned",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/watch/watch.v1.json",
+ "title": "Watch",
+ "description": "watch.watch@1: a user-defined persistent observation (plan T18). It names a source (a push event, a webhook, a conditional HTTP URL, a feed or API, a local Node probe, or an expensive Run check), how a value is extracted, how it is compared with the last observation, the condition that fires, the actions it wakes, its budget and its retention. Carrier preference is binding: an event or webhook source is used when one exists, then ETag/Last-Modified, then a feed, then an API, and browser polling through Run only when none works. A price or stock is 'as of' the observation, null when it stated none.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "id",
+ "owner",
+ "status",
+ "source",
+ "extraction",
+ "condition",
+ "action",
+ "created_at",
+ "updated_at"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "project_id": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "owner": {
+ "type": "string",
+ "description": "The acting person or agent the watch belongs to: usr_…, agt_… or svc:…."
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 120
+ },
+ "labels": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string",
+ "maxLength": 60
+ }
+ },
+ "status": {
+ "enum": [
+ "active",
+ "paused",
+ "disabled",
+ "failed"
+ ]
+ },
+ "source": {
+ "$ref": "#/$defs/source"
+ },
+ "cadence": {
+ "$ref": "#/$defs/cadence"
+ },
+ "extraction": {
+ "$ref": "#/$defs/extraction"
+ },
+ "comparison": {
+ "$ref": "#/$defs/comparison"
+ },
+ "condition": {
+ "$ref": "#/$defs/condition"
+ },
+ "action": {
+ "type": "array",
+ "minItems": 1,
+ "maxItems": 8,
+ "items": {
+ "$ref": "#/$defs/action"
+ }
+ },
+ "budget": {
+ "$ref": "#/$defs/budget"
+ },
+ "retention": {
+ "$ref": "#/$defs/retention"
+ },
+ "health": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": true
+ },
+ "created_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updated_at": {
+ "type": "string",
+ "format": "date-time"
+ }
+ },
+ "$defs": {
+ "auth": {
+ "type": "object",
+ "required": [
+ "mode"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "enum": [
+ "none",
+ "header",
+ "bearer",
+ "query"
+ ]
+ },
+ "env": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "pattern": "^WATCH_CRED_[A-Z0-9_]{2,60}$",
+ "description": "The name of the environment variable holding the credential; Watch reads it by name at fetch time and never stores the value."
+ },
+ "header": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "param": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ }
+ },
+ "source": {
+ "oneOf": [
+ {
+ "type": "object",
+ "required": [
+ "kind"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "kind": {
+ "const": "webhook"
+ },
+ "endpoint": {
+ "type": "string",
+ "pattern": "^/internal/hooks/"
+ }
+ }
+ },
+ {
+ "type": "object",
+ "required": [
+ "kind",
+ "pattern"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "kind": {
+ "const": "event"
+ },
+ "pattern": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9_-]*(\\.[a-z0-9_*]+){1,}$"
+ },
+ "filter": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": [
+ "string",
+ "number",
+ "boolean",
+ "null"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "type": "object",
+ "required": [
+ "kind",
+ "url"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "kind": {
+ "enum": [
+ "http",
+ "feed",
+ "api"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "format": "uri",
+ "pattern": "^https?://"
+ },
+ "method": {
+ "enum": [
+ "GET",
+ "HEAD"
+ ]
+ },
+ "format": {
+ "enum": [
+ "rss",
+ "atom",
+ "json",
+ null
+ ]
+ },
+ "items_path": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "fields": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "auth": {
+ "$ref": "#/$defs/auth"
+ },
+ "headers": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "conditional": {
+ "type": "boolean",
+ "description": "Send If-None-Match / If-Modified-Since from the stored ETag/Last-Modified when the server gave one."
+ }
+ }
+ },
+ {
+ "type": "object",
+ "required": [
+ "kind",
+ "node_id",
+ "probe"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "kind": {
+ "const": "node"
+ },
+ "node_id": {
+ "type": "string"
+ },
+ "probe": {
+ "type": "object",
+ "additionalProperties": true
+ }
+ }
+ },
+ {
+ "type": "object",
+ "required": [
+ "kind",
+ "runtime",
+ "steps"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "kind": {
+ "const": "run"
+ },
+ "runtime": {
+ "enum": [
+ "browser",
+ "code",
+ "desktop"
+ ]
+ },
+ "url": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "format": "uri"
+ },
+ "steps": {
+ "type": "array",
+ "minItems": 1,
+ "items": {
+ "type": "object",
+ "additionalProperties": true
+ }
+ },
+ "workload": {
+ "$ref": "../platform/workload-requirements.v1.json"
+ }
+ }
+ }
+ ]
+ },
+ "cadence": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": false,
+ "description": "Required for http/feed/api/node sources; null for event/webhook sources (they never poll).",
+ "properties": {
+ "every_sec": {
+ "type": "integer",
+ "minimum": 30,
+ "maximum": 2592000
+ },
+ "jitter_sec": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 3600
+ },
+ "timezone": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ }
+ },
+ "extraction": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kind": {
+ "enum": [
+ "text",
+ "html",
+ "json",
+ "regex",
+ "css",
+ "jsonpath",
+ "ai"
+ ]
+ },
+ "selector": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "fields": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "value_path": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "ai": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": true
+ }
+ }
+ },
+ "comparison": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "enum": [
+ "changed",
+ "threshold",
+ "none"
+ ]
+ },
+ "tolerance": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "percent": {
+ "type": [
+ "number",
+ "null"
+ ]
+ }
+ }
+ },
+ "condition": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "op": {
+ "enum": [
+ "changed",
+ "gt",
+ "gte",
+ "lt",
+ "lte",
+ "eq",
+ "ne",
+ "contains",
+ "matches",
+ "exists",
+ "absent"
+ ]
+ },
+ "value": {
+ "type": [
+ "string",
+ "number",
+ "null"
+ ]
+ },
+ "for_sec": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "minimum": 0
+ }
+ }
+ },
+ "action": {
+ "oneOf": [
+ {
+ "type": "object",
+ "required": [
+ "kind"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "kind": {
+ "const": "notification"
+ },
+ "category": {
+ "enum": [
+ "service",
+ "social",
+ "system"
+ ]
+ },
+ "priority": {
+ "enum": [
+ "low",
+ "normal",
+ "high",
+ "critical"
+ ]
+ }
+ }
+ },
+ {
+ "type": "object",
+ "required": [
+ "kind",
+ "event_type"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "kind": {
+ "const": "event"
+ },
+ "event_type": {
+ "type": "string"
+ },
+ "payload": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": true
+ }
+ }
+ },
+ {
+ "type": "object",
+ "required": [
+ "kind",
+ "url",
+ "secret_env"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "kind": {
+ "const": "webhook"
+ },
+ "url": {
+ "type": "string",
+ "format": "uri",
+ "pattern": "^https://"
+ },
+ "secret_env": {
+ "type": "string",
+ "pattern": "^WATCH_HOOK_[A-Z0-9_]{2,60}$"
+ }
+ }
+ },
+ {
+ "type": "object",
+ "required": [
+ "kind",
+ "brief"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "kind": {
+ "const": "actor-task"
+ },
+ "brief": {
+ "type": "string",
+ "maxLength": 8000
+ },
+ "budget_usd": {
+ "type": [
+ "number",
+ "null"
+ ]
+ }
+ }
+ },
+ {
+ "type": "object",
+ "required": [
+ "kind",
+ "repo",
+ "brief"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "kind": {
+ "const": "codes-run"
+ },
+ "repo": {
+ "type": "string"
+ },
+ "brief": {
+ "type": "string",
+ "maxLength": 8000
+ }
+ }
+ },
+ {
+ "type": "object",
+ "required": [
+ "kind",
+ "runtime",
+ "command"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "kind": {
+ "const": "run-job"
+ },
+ "runtime": {
+ "enum": [
+ "function",
+ "code",
+ "browser",
+ "linux"
+ ]
+ },
+ "command": {
+ "type": "string"
+ },
+ "workload": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": true
+ }
+ }
+ }
+ ]
+ },
+ "budget": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks_per_day": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "minimum": 1
+ },
+ "usd_per_month": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "minimum": 0
+ },
+ "max_runtime_ms": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "minimum": 100
+ },
+ "max_bytes": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "minimum": 1024
+ }
+ }
+ },
+ "retention": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "observations_days": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "minimum": 1
+ },
+ "keep_snapshots": {
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ }
+ },
+ "watch.watch-request": {
+ "version": "1.0.0",
+ "owner": "watch",
+ "status": "planned",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/watch/watch-request.v1.json",
+ "title": "WatchRequest",
+ "description": "watch.watch-request@1: the body of POST /api/v1/watches and PATCH /api/v1/watches/:id on OpenVibe.Watch (watch.watch.manage; the acting person). Every field is optional on a patch; a create requires source, extraction, condition and action, which the service enforces in code (422 watch.invalid).",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 120
+ },
+ "labels": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string",
+ "maxLength": 60
+ }
+ },
+ "source": {
+ "$ref": "watch.v1.json#/$defs/source"
+ },
+ "cadence": {
+ "$ref": "watch.v1.json#/$defs/cadence"
+ },
+ "extraction": {
+ "$ref": "watch.v1.json#/$defs/extraction"
+ },
+ "comparison": {
+ "$ref": "watch.v1.json#/$defs/comparison"
+ },
+ "condition": {
+ "$ref": "watch.v1.json#/$defs/condition"
+ },
+ "action": {
+ "type": "array",
+ "minItems": 1,
+ "maxItems": 8,
+ "items": {
+ "$ref": "watch.v1.json#/$defs/action"
+ }
+ },
+ "budget": {
+ "$ref": "watch.v1.json#/$defs/budget"
+ },
+ "retention": {
+ "$ref": "watch.v1.json#/$defs/retention"
+ },
+ "status": {
+ "enum": [
+ "active",
+ "paused",
+ "disabled",
+ "failed"
+ ]
+ }
+ }
+ }
+ },
+ "watch.watch-result": {
+ "version": "1.0.0",
+ "owner": "watch",
+ "status": "planned",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/watch/watch-result.v1.json",
+ "title": "WatchResult",
+ "description": "watch.watch-result@1: answers of the watch routes on OpenVibe.Watch. GET /api/v1/watches → { watches } and POST /api/v1/watches → 201 { watch } (watch.watch.read, watch.watch.manage); PATCH → { watch }; POST /:id/pause and /:id/resume → { id, status }; DELETE /api/v1/watches/:id → { id, deleted: true }.",
+ "anyOf": [
+ {
+ "type": "object",
+ "required": [
+ "watches"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "watches": {
+ "type": "array",
+ "items": {
+ "$ref": "watch.v1.json"
+ }
+ }
+ }
+ },
+ {
+ "type": "object",
+ "required": [
+ "watch"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "watch": {
+ "$ref": "watch.v1.json"
+ }
+ }
+ },
+ {
+ "type": "object",
+ "required": [
+ "id",
+ "status"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "id": {
+ "type": "string",
+ "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "status": {
+ "enum": [
+ "active",
+ "paused",
+ "disabled",
+ "failed"
+ ]
+ }
+ }
+ },
+ {
+ "type": "object",
+ "required": [
+ "id",
+ "deleted"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "id": {
+ "type": "string",
+ "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "deleted": {
+ "const": true
+ }
+ }
+ }
+ ]
+ }
+ },
+ "watch.observation": {
+ "version": "1.0.0",
+ "owner": "watch",
+ "status": "planned",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/watch/observation.v1.json",
+ "title": "WatchObservation",
+ "description": "watch.observation@1: one value a check recorded for a watch (plan T18): what was extracted, when, from which check run, and whether it changed or met the condition. value is the extracted value exactly as the source stated it, never inferred; snapshot is a capped copy of the raw body kept according to the watch's retention. Rows are immutable.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "id",
+ "watch_id",
+ "check_run_id",
+ "observed_at",
+ "value",
+ "value_hash",
+ "previous_hash",
+ "changed",
+ "condition_met",
+ "snapshot"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "pattern": "^wco_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "watch_id": {
+ "type": "string",
+ "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "check_run_id": {
+ "type": "string",
+ "pattern": "^ckr_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "observed_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "value": {
+ "description": "The extracted value as the source stated it: text, a decimal number, a structured object."
+ },
+ "value_hash": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{64}$",
+ "description": "SHA-256 hex of the canonical value."
+ },
+ "previous_hash": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "pattern": "^[0-9a-f]{64}$",
+ "description": "SHA-256 of the previous observation's value; null for the first observation."
+ },
+ "changed": {
+ "type": "boolean"
+ },
+ "condition_met": {
+ "type": "boolean"
+ },
+ "snapshot": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ }
+ }
+ },
+ "watch.check-run": {
+ "version": "1.0.0",
+ "owner": "watch",
+ "status": "planned",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/watch/check-run.v1.json",
+ "title": "WatchCheckRun",
+ "description": "watch.check-run@1: one execution of a watch's check (plan T18), by schedule, manually, or from a delivered event or webhook. carrier names the mechanism that carried it; state is the terminal state (the same values the service's check_runs.state CHECK allows). observations is how many observations the run recorded and triggers how many conditions it fired; cost_usd is what the run cost. Rows are immutable.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "id",
+ "watch_id",
+ "trigger",
+ "carrier",
+ "started_at",
+ "finished_at",
+ "state",
+ "http_status",
+ "observations",
+ "triggers",
+ "cost_usd",
+ "detail"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "pattern": "^ckr_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "watch_id": {
+ "type": "string",
+ "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "trigger": {
+ "enum": [
+ "schedule",
+ "manual",
+ "event",
+ "webhook"
+ ]
+ },
+ "carrier": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "enum": [
+ "event",
+ "webhook",
+ "http",
+ "feed",
+ "api",
+ "node",
+ "run",
+ null
+ ]
+ },
+ "started_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "finished_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "state": {
+ "enum": [
+ "ok",
+ "not_modified",
+ "no_change",
+ "changed",
+ "condition_met",
+ "http_error",
+ "timeout",
+ "parse_error",
+ "rate_limited",
+ "budget_exceeded",
+ "skipped",
+ "disabled"
+ ]
+ },
+ "http_status": {
+ "type": [
+ "integer",
+ "null"
+ ]
+ },
+ "observations": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "triggers": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "cost_usd": {
+ "type": "number",
+ "minimum": 0
+ },
+ "detail": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ }
+ }
+ },
+ "watch.observation.recorded": {
+ "version": "1.0.0",
+ "owner": "watch",
+ "status": "planned",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/events/payloads/watch.observation.recorded.v1.json",
+ "title": "WatchObservationRecordedPayload",
+ "description": "watch.observation.recorded v1 (OpenVibe.Watch, plan T18): a check recorded an observation for a watch. It carries the extracted value as the source stated it and its hash, never the raw body. Envelope: subject { type: watch, id: <watch_id> }, visibility internal, priority low, actor service:watch. Watch's own records are the full observation (watch.observation@1); this event is the notification that one exists.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "watch_id",
+ "owner",
+ "observed_at",
+ "value",
+ "value_hash",
+ "changed",
+ "condition_met"
+ ],
+ "properties": {
+ "watch_id": {
+ "type": "string",
+ "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "owner": {
+ "type": "string",
+ "pattern": "^(usr|agt)_[0-9A-HJKMNP-TV-Z]{26}$",
+ "description": "The watch owner's subject id: who this observation is for."
+ },
+ "observed_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "value": {
+ "description": "The extracted value as the source stated it; null when it stated none."
+ },
+ "value_hash": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{64}$",
+ "description": "SHA-256 hex of the canonical value."
+ },
+ "changed": {
+ "type": "boolean"
+ },
+ "condition_met": {
+ "type": "boolean"
+ }
+ }
+ }
+ },
+ "watch.watch.triggered": {
+ "version": "1.0.0",
+ "owner": "watch",
+ "status": "planned",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/events/payloads/watch.watch.triggered.v1.json",
+ "title": "WatchTriggeredPayload",
+ "description": "watch.watch.triggered v1 (OpenVibe.Watch, plan T18; the dossier's watch.triggered, named with three segments as every event type is here — the repo's event-type pattern requires at least three): a watch's condition fired. OpenVibe.Network turns it into a WATCH_TRIGGERED notification for payload.recipient (mirrors deals.watch.matched). Envelope: subject { type: watch, id: <watch_id> }, visibility internal, priority important, actor service:watch.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "watch_id",
+ "recipient",
+ "project_id",
+ "name",
+ "condition",
+ "observation",
+ "fired_at"
+ ],
+ "properties": {
+ "watch_id": {
+ "type": "string",
+ "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "recipient": {
+ "type": "string",
+ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$",
+ "description": "The watch owner's user subject id: who is notified."
+ },
+ "project_id": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 120
+ },
+ "condition": {
+ "$ref": "../../watch/watch.v1.json#/$defs/condition"
+ },
+ "observation": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "id",
+ "observed_at",
+ "value",
+ "previous_value"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "pattern": "^wco_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "observed_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "value": {
+ "description": "The value that fired the condition."
+ },
+ "previous_value": {
+ "description": "The previous observation's value; null when there was none."
+ }
+ }
+ },
+ "fired_at": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ }
+ },
+ "watch.check.failed": {
+ "version": "1.0.0",
+ "owner": "watch",
+ "status": "planned",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/events/payloads/watch.check.failed.v1.json",
+ "title": "WatchCheckFailedPayload",
+ "description": "watch.check.failed v1 (OpenVibe.Watch, plan T18): a check ended in a failure state. consecutive_failures is how many runs in a row have failed, so a consumer can tell a blip from a watch that is down. Envelope: subject { type: watch, id: <watch_id> }, visibility internal, priority normal, actor service:watch.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "watch_id",
+ "state",
+ "carrier",
+ "http_status",
+ "error_code",
+ "consecutive_failures"
+ ],
+ "properties": {
+ "watch_id": {
+ "type": "string",
+ "pattern": "^wch_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "state": {
+ "enum": [
+ "http_error",
+ "timeout",
+ "parse_error",
+ "rate_limited",
+ "budget_exceeded",
+ "skipped",
+ "disabled"
+ ]
+ },
+ "carrier": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "enum": [
+ "event",
+ "webhook",
+ "http",
+ "feed",
+ "api",
+ "node",
+ "run",
+ null
+ ]
+ },
+ "http_status": {
+ "type": [
+ "integer",
+ "null"
+ ]
+ },
+ "error_code": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "consecutive_failures": {
+ "type": "integer",
+ "minimum": 1
+ }
+ }
+ }
+ },
"games.player.joined": {
"games.player.joined": {
"version": "1.0.0",
"version": "1.0.0",
"owner": "games",
"owner": "games",
@@ -61560,7 +62738,7 @@
@@ -61560,7 +62738,7 @@
"type": "string",
"type": "string",
"pattern": "^[a-z][a-z0-9-]*:[a-z0-9.-]+$"
"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. Kind harness: task:edit, task:review, task:browse, task:run, task:test and task:plan for the task kinds it takes (its detail's task_capabilities), and harness:mcp, harness:resume, harness:host-access and harness:long-autonomy for its detail's capabilities that are true. The `worker:<class>` names that map to platform.runtime-class@1 values are reserved for OpenVibe.Node's job worker, one per class: worker:function, worker:code, worker:browser, worker:linux, worker:desktop and worker:gpu ($defs.reservedWorkerCapabilities). A node advertises the name of each class it runs (Node's status.capabilities.worker); every other `worker:` name (worker:ffmpeg, worker:ai-gpu) is an ordinary capability name."
+ "description": "e.g. node:http, worker:browser, worker:ffmpeg, worker:ai-gpu, events:gateway, events:durable, object:r2. Kind harness: task:edit, task:review, task:browse, task:run, task:test and task:plan for the task kinds it takes (its detail's task_capabilities), and harness:mcp, harness:resume, harness:host-access and harness:long-autonomy for its detail's capabilities that are true. The `worker:<class>` names that map to platform.runtime-class@1 values are reserved for OpenVibe.Node's job worker, one per class: worker:function, worker:code, worker:browser, worker:linux, worker:desktop and worker:gpu ($defs.reservedWorkerCapabilities). A node advertises the name of each class it runs (Node's status.capabilities.worker); every other `worker:` name (worker:ffmpeg, worker:ai-gpu) is an ordinary capability name. Beside them, a kind harness names `runtime:<class>` for each platform.runtime-class@1 class it can run (runtime:function, runtime:code, runtime:browser, runtime:linux, runtime:desktop, runtime:gpu); these are ordinary capability names, not reserved, and OpenVibe.Codes already advertises the classes it offers."
},
},
"capacity": {
"capacity": {
"type": "object",
"type": "object",
@@ -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.101.0",
- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.102.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Billing API",
"title": "OpenVibe.Billing API",
- "version": "0.101.0",
- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.102.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Blog API",
"title": "OpenVibe.Blog API",
- "version": "0.101.0",
- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.Bot API",
"title": "OpenVibe.Bot API",
- "version": "0.101.0",
- "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",
- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",
- "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.102.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Community API",
"title": "OpenVibe.Community API",
- "version": "0.101.0",
- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",
- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",
- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",
- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.102.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Games API",
"title": "OpenVibe.Games API",
- "version": "0.101.0",
- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.102.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Host API",
"title": "OpenVibe.Host API",
- "version": "0.101.0",
- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",
- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",
- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",
- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.News API",
"title": "OpenVibe.News API",
- "version": "0.101.0",
- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",
- "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.102.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Reviews API",
"title": "OpenVibe.Reviews API",
- "version": "0.101.0",
- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",
- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",
- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.Space API",
"title": "OpenVibe.Space API",
- "version": "0.101.0",
- "description": "Routes of OpenVibe.Space as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.Space as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",
- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.102.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Tools API",
"title": "OpenVibe.Tools API",
- "version": "0.101.0",
- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",
- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.102.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.101.0",
- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.102.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Wiki API",
"title": "OpenVibe.Wiki API",
- "version": "0.101.0",
- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.101.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.102.0",
+ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.102.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"
@@ -46238,6 +46238,3098 @@ export interface TradeWatchlist {
@@ -46238,6 +46238,3098 @@ export interface TradeWatchlist {
}[];
}[];
}
}
+/** [email protected] (owner: watch) */
+/**
+ * watch.watch@1: a user-defined persistent observation (plan T18). It names a source (a push event, a webhook, a conditional HTTP URL, a feed or API, a local Node probe, or an expensive Run check), how a value is extracted, how it is compared with the last observation, the condition that fires, the actions it wakes, its budget and its retention. Carrier preference is binding: an event or webhook source is used when one exists, then ETag/Last-Modified, then a feed, then an API, and browser polling through Run only when none works. A price or stock is 'as of' the observation, null when it stated none.
+ */
+export interface Watch {
+ id: string;
+ project_id?: string | null;
+ /**
+ * The acting person or agent the watch belongs to: usr_…, agt_… or svc:….
+ */
+ owner: string;
+ name?: string;
+ labels?: {
+ [k: string]: string | undefined;
+ };
+ status: "active" | "paused" | "disabled" | "failed";
+ source:
+ | {
+ kind: "webhook";
+ endpoint?: string;
+ }
+ | {
+ kind: "event";
+ pattern: string;
+ filter?: {
+ [k: string]: (string | number | boolean | null) | undefined;
+ } | null;
+ }
+ | {
+ kind: "http" | "feed" | "api";
+ url: string;
+ method?: "GET" | "HEAD";
+ format?: "rss" | "atom" | "json" | null;
+ items_path?: string | null;
+ fields?: {
+ [k: string]: string | undefined;
+ } | null;
+ auth?: {
+ mode: "none" | "header" | "bearer" | "query";
+ /**
+ * The name of the environment variable holding the credential; Watch reads it by name at fetch time and never stores the value.
+ */
+ env?: string | null;
+ header?: string | null;
+ param?: string | null;
+ };
+ headers?: {
+ [k: string]: string | undefined;
+ };
+ /**
+ * Send If-None-Match / If-Modified-Since from the stored ETag/Last-Modified when the server gave one.
+ */
+ conditional?: boolean;
+ }
+ | {
+ kind: "node";
+ node_id: string;
+ probe: {
+ [k: string]: unknown | undefined;
+ };
+ }
+ | {
+ kind: "run";
+ runtime: "browser" | "code" | "desktop";
+ url?: string | null;
+ /**
+ * @minItems 1
+ */
+ steps: [
+ {
+ [k: string]: unknown | undefined;
+ },
+ ...{
+ [k: string]: unknown | undefined;
+ }[]
+ ];
+ workload?: WorkloadRequirements;
+ };
+ /**
+ * Required for http/feed/api/node sources; null for event/webhook sources (they never poll).
+ */
+ cadence?: {
+ every_sec?: number;
+ jitter_sec?: number;
+ timezone?: string | null;
+ } | null;
+ extraction: {
+ kind?: "text" | "html" | "json" | "regex" | "css" | "jsonpath" | "ai";
+ selector?: string | null;
+ fields?: {
+ [k: string]: string | undefined;
+ } | null;
+ value_path?: string | null;
+ ai?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ };
+ comparison?: {
+ mode?: "changed" | "threshold" | "none";
+ tolerance?: number | null;
+ percent?: number | null;
+ } | null;
+ condition: {
+ op?: "changed" | "gt" | "gte" | "lt" | "lte" | "eq" | "ne" | "contains" | "matches" | "exists" | "absent";
+ value?: string | number | null;
+ for_sec?: number | null;
+ };
+ /**
+ * @minItems 1
+ * @maxItems 8
+ */
+ action:
+ | [
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ]
+ | [
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ )
+ ]
+ | [
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ )
+ ]
+ | [
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ )
+ ]
+ | [
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ )
+ ]
+ | [
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ )
+ ]
+ | [
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ )
+ ]
+ | [
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ )
+ ];
+ budget?: {
+ checks_per_day?: number | null;
+ usd_per_month?: number | null;
+ max_runtime_ms?: number | null;
+ max_bytes?: number | null;
+ };
+ retention?: {
+ observations_days?: number | null;
+ keep_snapshots?: boolean;
+ };
+ health?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ created_at: string;
+ updated_at: string;
+}
+
+/** [email protected] (owner: watch) */
+/**
+ * watch.watch-request@1: the body of POST /api/v1/watches and PATCH /api/v1/watches/:id on OpenVibe.Watch (watch.watch.manage; the acting person). Every field is optional on a patch; a create requires source, extraction, condition and action, which the service enforces in code (422 watch.invalid).
+ */
+export interface WatchRequest {
+ name?: string;
+ labels?: {
+ [k: string]: string | undefined;
+ };
+ source?:
+ | {
+ kind: "webhook";
+ endpoint?: string;
+ }
+ | {
+ kind: "event";
+ pattern: string;
+ filter?: {
+ [k: string]: (string | number | boolean | null) | undefined;
+ } | null;
+ }
+ | {
+ kind: "http" | "feed" | "api";
+ url: string;
+ method?: "GET" | "HEAD";
+ format?: "rss" | "atom" | "json" | null;
+ items_path?: string | null;
+ fields?: {
+ [k: string]: string | undefined;
+ } | null;
+ auth?: {
+ mode: "none" | "header" | "bearer" | "query";
+ /**
+ * The name of the environment variable holding the credential; Watch reads it by name at fetch time and never stores the value.
+ */
+ env?: string | null;
+ header?: string | null;
+ param?: string | null;
+ };
+ headers?: {
+ [k: string]: string | undefined;
+ };
+ /**
+ * Send If-None-Match / If-Modified-Since from the stored ETag/Last-Modified when the server gave one.
+ */
+ conditional?: boolean;
+ }
+ | {
+ kind: "node";
+ node_id: string;
+ probe: {
+ [k: string]: unknown | undefined;
+ };
+ }
+ | {
+ kind: "run";
+ runtime: "browser" | "code" | "desktop";
+ url?: string | null;
+ /**
+ * @minItems 1
+ */
+ steps: [
+ {
+ [k: string]: unknown | undefined;
+ },
+ ...{
+ [k: string]: unknown | undefined;
+ }[]
+ ];
+ workload?: WorkloadRequirements;
+ };
+ /**
+ * Required for http/feed/api/node sources; null for event/webhook sources (they never poll).
+ */
+ cadence?: {
+ every_sec?: number;
+ jitter_sec?: number;
+ timezone?: string | null;
+ } | null;
+ extraction?: {
+ kind?: "text" | "html" | "json" | "regex" | "css" | "jsonpath" | "ai";
+ selector?: string | null;
+ fields?: {
+ [k: string]: string | undefined;
+ } | null;
+ value_path?: string | null;
+ ai?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ };
+ comparison?: {
+ mode?: "changed" | "threshold" | "none";
+ tolerance?: number | null;
+ percent?: number | null;
+ } | null;
+ condition?: {
+ op?: "changed" | "gt" | "gte" | "lt" | "lte" | "eq" | "ne" | "contains" | "matches" | "exists" | "absent";
+ value?: string | number | null;
+ for_sec?: number | null;
+ };
+ /**
+ * @minItems 1
+ * @maxItems 8
+ */
+ action?:
+ | [
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ]
+ | [
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ )
+ ]
+ | [
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ )
+ ]
+ | [
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ )
+ ]
+ | [
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ )
+ ]
+ | [
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ )
+ ]
+ | [
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ )
+ ]
+ | [
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ ),
+ (
+ | {
+ kind: "notification";
+ category?: "service" | "social" | "system";
+ priority?: "low" | "normal" | "high" | "critical";
+ }
+ | {
+ kind: "event";
+ event_type: string;
+ payload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ | {
+ kind: "webhook";
+ url: string;
+ secret_env: string;
+ }
+ | {
+ kind: "actor-task";
+ brief: string;
+ budget_usd?: number | null;
+ }
+ | {
+ kind: "codes-run";
+ repo: string;
+ brief: string;
+ }
+ | {
+ kind: "run-job";
+ runtime: "function" | "code" | "browser" | "linux";
+ command: string;
+ workload?: {
+ [k: string]: unknown | undefined;
+ } | null;
+ }
+ )
+ ];
+ budget?: {
+ checks_per_day?: number | null;
+ usd_per_month?: number | null;
+ max_runtime_ms?: number | null;
+ max_bytes?: number | null;
+ };
+ retention?: {
+ observations_days?: number | null;
+ keep_snapshots?: boolean;
+ };
+ status?: "active" | "paused" | "disabled" | "failed";
+}
+
+/** [email protected] (owner: watch) */
+/**
+ * watch.watch-result@1: answers of the watch routes on OpenVibe.Watch. GET /api/v1/watches → { watches } and POST /api/v1/watches → 201 { watch } (watch.watch.read, watch.watch.manage); PATCH → { watch }; POST /:id/pause and /:id/resume → { id, status }; DELETE /api/v1/watches/:id → { id, deleted: true }.
+ */
+export type WatchResult =
+ | {
+ watches: Watch[];
+ }
+ | {
+ watch: Watch;
+ }
+ | {
+ id: string;
+ status: "active" | "paused" | "disabled" | "failed";
+ }
+ | {
+ id: string;
+ deleted: true;
+ };
+
+/** [email protected] (owner: watch) */
+/**
+ * watch.observation@1: one value a check recorded for a watch (plan T18): what was extracted, when, from which check run, and whether it changed or met the condition. value is the extracted value exactly as the source stated it, never inferred; snapshot is a capped copy of the raw body kept according to the watch's retention. Rows are immutable.
+ */
+export interface WatchObservation {
+ id: string;
+ watch_id: string;
+ check_run_id: string;
+ observed_at: string;
+ /**
+ * The extracted value as the source stated it: text, a decimal number, a structured object.
+ */
+ value: {
+ [k: string]: unknown | undefined;
+ };
+ /**
+ * SHA-256 hex of the canonical value.
+ */
+ value_hash: string;
+ /**
+ * SHA-256 of the previous observation's value; null for the first observation.
+ */
+ previous_hash: string | null;
+ changed: boolean;
+ condition_met: boolean;
+ snapshot: string | null;
+}
+
+/** [email protected] (owner: watch) */
+/**
+ * watch.check-run@1: one execution of a watch's check (plan T18), by schedule, manually, or from a delivered event or webhook. carrier names the mechanism that carried it; state is the terminal state (the same values the service's check_runs.state CHECK allows). observations is how many observations the run recorded and triggers how many conditions it fired; cost_usd is what the run cost. Rows are immutable.
+ */
+export interface WatchCheckRun {
+ id: string;
+ watch_id: string;
+ trigger: "schedule" | "manual" | "event" | "webhook";
+ carrier: "event" | "webhook" | "http" | "feed" | "api" | "node" | "run" | null;
+ started_at: string;
+ finished_at: string;
+ state:
+ | "ok"
+ | "not_modified"
+ | "no_change"
+ | "changed"
+ | "condition_met"
+ | "http_error"
+ | "timeout"
+ | "parse_error"
+ | "rate_limited"
+ | "budget_exceeded"
+ | "skipped"
+ | "disabled";
+ http_status: number | null;
+ observations: number;
+ triggers: number;
+ cost_usd: number;
+ detail: string | null;
+}
+
+/** [email protected] (owner: watch) */
+/**
+ * watch.observation.recorded v1 (OpenVibe.Watch, plan T18): a check recorded an observation for a watch. It carries the extracted value as the source stated it and its hash, never the raw body. Envelope: subject { type: watch, id: <watch_id> }, visibility internal, priority low, actor service:watch. Watch's own records are the full observation (watch.observation@1); this event is the notification that one exists.
+ */
+export interface WatchObservationRecordedPayload {
+ watch_id: string;
+ /**
+ * The watch owner's subject id: who this observation is for.
+ */
+ owner: string;
+ observed_at: string;
+ /**
+ * The extracted value as the source stated it; null when it stated none.
+ */
+ value: {
+ [k: string]: unknown | undefined;
+ };
+ /**
+ * SHA-256 hex of the canonical value.
+ */
+ value_hash: string;
+ changed: boolean;
+ condition_met: boolean;
+}
+
+/** [email protected] (owner: watch) */
+/**
+ * watch.watch.triggered v1 (OpenVibe.Watch, plan T18; the dossier's watch.triggered, named with three segments as every event type is here — the repo's event-type pattern requires at least three): a watch's condition fired. OpenVibe.Network turns it into a WATCH_TRIGGERED notification for payload.recipient (mirrors deals.watch.matched). Envelope: subject { type: watch, id: <watch_id> }, visibility internal, priority important, actor service:watch.
+ */
+export interface WatchTriggeredPayload {
+ watch_id: string;
+ /**
+ * The watch owner's user subject id: who is notified.
+ */
+ recipient: string;
+ project_id: string | null;
+ name: string;
+ condition: {
+ op?: "changed" | "gt" | "gte" | "lt" | "lte" | "eq" | "ne" | "contains" | "matches" | "exists" | "absent";
+ value?: string | number | null;
+ for_sec?: number | null;
+ };
+ observation: {
+ id: string;
+ observed_at: string;
+ /**
+ * The value that fired the condition.
+ */
+ value: {
+ [k: string]: unknown | undefined;
+ };
+ /**
+ * The previous observation's value; null when there was none.
+ */
+ previous_value: {
+ [k: string]: unknown | undefined;
+ };
+ };
+ fired_at: string;
+}
+
+/** [email protected] (owner: watch) */
+/**
+ * watch.check.failed v1 (OpenVibe.Watch, plan T18): a check ended in a failure state. consecutive_failures is how many runs in a row have failed, so a consumer can tell a blip from a watch that is down. Envelope: subject { type: watch, id: <watch_id> }, visibility internal, priority normal, actor service:watch.
+ */
+export interface WatchCheckFailedPayload {
+ watch_id: string;
+ state: "http_error" | "timeout" | "parse_error" | "rate_limited" | "budget_exceeded" | "skipped" | "disabled";
+ carrier: "event" | "webhook" | "http" | "feed" | "api" | "node" | "run" | null;
+ http_status: number | null;
+ error_code: string | null;
+ consecutive_failures: number;
+}
+
/** [email protected] (owner: games) */
/** [email protected] (owner: games) */
/**
/**
* games.player.joined v1 (OpenVibe.Games apps/server/src/platform/gameEvents.ts playerJoinedEvent, via GameEventRecorder.recordJoin from game/gameServer.ts handleHello). A character entered the world: written to Games' event_outbox in a transaction of its own once the session exists and the welcome was sent (a new character's row is first written by its next save). restored is true when the character already existed in the database, false for a new one. Only emitted while Events publishing is configured. No position, appearance, inventory, rank or connection data. Envelope: subject { type: player, id: <player.id> }, visibility subject when the player has a Network subject and internal otherwise, priority low, actor user:<usr_...> or guest:<gst_...> from player.subject, else service:games. No consumer yet.
* games.player.joined v1 (OpenVibe.Games apps/server/src/platform/gameEvents.ts playerJoinedEvent, via GameEventRecorder.recordJoin from game/gameServer.ts handleHello). A character entered the world: written to Games' event_outbox in a transaction of its own once the session exists and the welcome was sent (a new character's row is first written by its next save). restored is true when the character already existed in the database, false for a new one. Only emitted while Events publishing is configured. No position, appearance, inventory, rank or connection data. Envelope: subject { type: player, id: <player.id> }, visibility subject when the player has a Network subject and internal otherwise, priority low, actor user:<usr_...> or guest:<gst_...> from player.subject, else service:games. No consumer yet.
@@ -51677,7 +54769,7 @@ export type ResourceOffer = {
@@ -51677,7 +54769,7 @@ export type ResourceOffer = {
*/
*/
trust: "first-party" | "user-owned" | "partner" | "community" | "external";
trust: "first-party" | "user-owned" | "partner" | "community" | "external";
/**
/**
- * e.g. node:http, worker:browser, worker:ffmpeg, worker:ai-gpu, events:gateway, events:durable, object:r2. Kind harness: task:edit, task:review, task:browse, task:run, task:test and task:plan for the task kinds it takes (its detail's task_capabilities), and harness:mcp, harness:resume, harness:host-access and harness:long-autonomy for its detail's capabilities that are true. The `worker:<class>` names that map to platform.runtime-class@1 values are reserved for OpenVibe.Node's job worker, one per class: worker:function, worker:code, worker:browser, worker:linux, worker:desktop and worker:gpu ($defs.reservedWorkerCapabilities). A node advertises the name of each class it runs (Node's status.capabilities.worker); every other `worker:` name (worker:ffmpeg, worker:ai-gpu) is an ordinary capability name.
+ * e.g. node:http, worker:browser, worker:ffmpeg, worker:ai-gpu, events:gateway, events:durable, object:r2. Kind harness: task:edit, task:review, task:browse, task:run, task:test and task:plan for the task kinds it takes (its detail's task_capabilities), and harness:mcp, harness:resume, harness:host-access and harness:long-autonomy for its detail's capabilities that are true. The `worker:<class>` names that map to platform.runtime-class@1 values are reserved for OpenVibe.Node's job worker, one per class: worker:function, worker:code, worker:browser, worker:linux, worker:desktop and worker:gpu ($defs.reservedWorkerCapabilities). A node advertises the name of each class it runs (Node's status.capabilities.worker); every other `worker:` name (worker:ffmpeg, worker:ai-gpu) is an ordinary capability name. Beside them, a kind harness names `runtime:<class>` for each platform.runtime-class@1 class it can run (runtime:function, runtime:code, runtime:browser, runtime:linux, runtime:desktop, runtime:gpu); these are ordinary capability names, not reserved, and OpenVibe.Codes already advertises the classes it offers.
*/
*/
capabilities: string[];
capabilities: string[];
capacity?: {
capacity?: {
new file mode 100644
new file mode 100644
@@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
+{
+ "id": "watch.check.run",
+ "version": "1.0",
+ "owner": "watch",
+ "status": "planned",
+ "visibility": "first-party",
+ "description": "PLANNED (plan T18; OpenVibe.Watch is not built yet): Run one check of a watch now, outside its cadence: POST /api/v1/watches/:id/check (409 watch.busy when one is already running). It becomes active, and enters generated/openapi/watch.json, when OpenVibe.Watch implements the route.",
+ "permissions": [
+ "watch:run"
+ ],
+ "resourceConstraints": [
+ "owner"
+ ],
+ "quotaClass": "watch-run",
+ "events": [],
+ "implementedBy": [],
+ "inputSchema": "common.no-body@1",
+ "outputSchema": "watch.check-run@1"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
+{
+ "id": "watch.observation.read",
+ "version": "1.0",
+ "owner": "watch",
+ "status": "planned",
+ "visibility": "first-party",
+ "description": "PLANNED (plan T18; OpenVibe.Watch is not built yet): Read a watch's observations and check runs: GET /api/v1/watches/:id/observations and GET /api/v1/watches/:id/checks. It becomes active, and enters generated/openapi/watch.json, when OpenVibe.Watch implements the routes.",
+ "permissions": [
+ "watch:read"
+ ],
+ "resourceConstraints": [
+ "owner"
+ ],
+ "quotaClass": "watch-read",
+ "events": [],
+ "implementedBy": [],
+ "inputSchema": "common.no-body@1",
+ "outputSchema": "watch.observation@1"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
+{
+ "id": "watch.watch.manage",
+ "version": "1.0",
+ "owner": "watch",
+ "status": "planned",
+ "visibility": "first-party",
+ "description": "PLANNED (plan T18; OpenVibe.Watch is not built yet): Create, change, pause, resume and delete a watch: POST /api/v1/watches, PATCH /api/v1/watches/:id, POST /api/v1/watches/:id/pause, POST /api/v1/watches/:id/resume and DELETE /api/v1/watches/:id. It becomes active, and enters generated/openapi/watch.json, when OpenVibe.Watch implements the routes.",
+ "permissions": [
+ "watch:manage"
+ ],
+ "resourceConstraints": [
+ "owner"
+ ],
+ "quotaClass": "watch-write",
+ "events": [
+ "watch.watch.created",
+ "watch.watch.updated",
+ "watch.watch.paused",
+ "watch.watch.removed"
+ ],
+ "implementedBy": [],
+ "inputSchema": "watch.watch-request@1",
+ "outputSchema": "watch.watch-result@1"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
+{
+ "id": "watch.watch.read",
+ "version": "1.0",
+ "owner": "watch",
+ "status": "planned",
+ "visibility": "first-party",
+ "description": "PLANNED (plan T18; OpenVibe.Watch is not built yet): List and read the acting person's or project's watches: GET /api/v1/watches and GET /api/v1/watches/:id. It becomes active, and enters generated/openapi/watch.json, when OpenVibe.Watch implements the routes.",
+ "permissions": [
+ "watch:read"
+ ],
+ "resourceConstraints": [
+ "owner"
+ ],
+ "quotaClass": "watch-read",
+ "events": [],
+ "implementedBy": [],
+ "inputSchema": "common.no-body@1",
+ "outputSchema": "watch.watch-result@1"
+}
@@ -27,6 +27,7 @@
@@ -27,6 +27,7 @@
"keywords": "website change monitoring, uptime monitoring api, price drop alerts, restock alerts, release monitoring, youtube video analysis, security camera alerts",
"keywords": "website change monitoring, uptime monitoring api, price drop alerts, restock alerts, release monitoring, youtube video analysis, security camera alerts",
"launch": "the watch service on the shared queue and workers",
"launch": "the watch service on the shared queue and workers",
"relationships": {
"relationships": {
+ "service": "watch",
"noRepo": true,
"noRepo": true,
"meanwhile": [
"meanwhile": [
{
{
new file mode 100644
new file mode 100644
@@ -0,0 +1,57 @@
@@ -0,0 +1,57 @@
+{
+ "version": "0.0.0",
+ "contractRanges": {
+ "openvibe-contracts": ">=0.102.0 <1.0.0"
+ },
+ "id": "watch",
+ "name": "OpenVibe.Watch",
+ "status": "placeholder",
+ "repository": "OpenVibers/OpenVibe.Watch",
+ "domains": [
+ "openvibe.watch"
+ ],
+ "publicOrigin": "https://openvibe.watch",
+ "exposure": {
+ "state": "placeholder",
+ "publicSite": null,
+ "note": "planned (plan T18); the OpenVibe.Watch repository does not exist yet, and nothing serves openvibe.watch"
+ },
+ "capabilities": [
+ "watch.watch.read",
+ "watch.watch.manage",
+ "watch.observation.read",
+ "watch.check.run"
+ ],
+ "eventsProduced": [
+ "watch.watch.created",
+ "watch.watch.updated",
+ "watch.watch.paused",
+ "watch.watch.removed",
+ "watch.observation.recorded",
+ "watch.watch.triggered",
+ "watch.check.failed"
+ ],
+ "eventsConsumed": [],
+ "namespacesOwned": [],
+ "lifecycle": {
+ "liveness": {
+ "none": "not built yet; nothing listens on a loopback address"
+ },
+ "shutdown": {
+ "none": "not built yet; nothing runs or drains"
+ },
+ "startupRecovery": {
+ "none": "not built yet; nothing starts"
+ },
+ "rollback": {
+ "none": "not built yet; nothing is released or rolled back"
+ },
+ "contracts": {
+ "range": ">=0.102.0 <1.0.0"
+ },
+ "leases": {
+ "none": "not built yet; nothing runs"
+ }
+ },
+ "notes": "The watch service of the network (plan T18): a user defines persistent observations and conditions over pages, feeds, APIs, events, releases, streams and local devices, and is told when they change or wakes an Actor task, a Codes run, a Run job or a webhook. Sources ingests structured sources, Run runs expensive browser/code checks, Node observes local/LAN things, Events transports the trigger. Planned: nothing is built; the OpenVibe.Watch repository does not exist yet."
+}
@@ -1,12 +1,12 @@
@@ -1,12 +1,12 @@
{
{
"name": "openvibe-contracts",
"name": "openvibe-contracts",
- "version": "0.101.0",
+ "version": "0.102.0",
"lockfileVersion": 3,
"lockfileVersion": 3,
"requires": true,
"requires": true,
"packages": {
"packages": {
"": {
"": {
"name": "openvibe-contracts",
"name": "openvibe-contracts",
- "version": "0.101.0",
+ "version": "0.102.0",
"license": "AGPL-3.0-only",
"license": "AGPL-3.0-only",
"dependencies": {
"dependencies": {
"ajv": "^8.17.1",
"ajv": "^8.17.1",
@@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
{
{
"name": "openvibe-contracts",
"name": "openvibe-contracts",
- "version": "0.101.0",
+ "version": "0.102.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",