openvibers/openvibe.contracts Commits

v0.22.0: OpenVibe.Trade is alpha (trade.* capabilities; informational only per ADR-025)

OP OpenVibers committed 23 Sept 2026 · 5602b74c38 · 14 files, +288 −9


Changes

ddiff --git a/manifests/capabilities/trade.alert.create.json b/manifests/capabilities/trade.alert.create.json
nnew file mode 100644
iindex 00000000..e58b3bec
---- /dev/null
++++ b/manifests/capabilities/trade.alert.create.json
@@@ -0,0 +1,21 @@
++{
++ "id": "trade.alert.create",
++ "version": "1.0",
++ "owner": "trade",
++ "status": "active",
++ "visibility": "first-party",
++ "description": "Create an alert rule for the person in X-OV-Subject: threshold (a crossing of a metric in a unit), filing_type or new_document. Deliveries are unique per (rule, triggering observation or document) and are sent as trade.alert.triggered (visibility subject); no email.",
++ "permissions": [
++ "trade:write"
++ ],
++ "resourceConstraints": [
++ "owner"
++ ],
++ "quotaClass": "trade-write",
++ "events": [
++ "trade.alert.triggered"
++ ],
++ "implementedBy": [
++ "POST /api/v1/alerts"
++ ]
++}
ddiff --git a/manifests/capabilities/trade.alert.delete.json b/manifests/capabilities/trade.alert.delete.json
nnew file mode 100644
iindex 00000000..1693fa83
---- /dev/null
++++ b/manifests/capabilities/trade.alert.delete.json
@@@ -0,0 +1,19 @@
++{
++ "id": "trade.alert.delete",
++ "version": "1.0",
++ "owner": "trade",
++ "status": "active",
++ "visibility": "first-party",
++ "description": "Delete an alert rule of the person in X-OV-Subject.",
++ "permissions": [
++ "trade:write"
++ ],
++ "resourceConstraints": [
++ "owner"
++ ],
++ "quotaClass": "trade-write",
++ "events": [],
++ "implementedBy": [
++ "DELETE /api/v1/alerts/:id"
++ ]
++}
ddiff --git a/manifests/capabilities/trade.alert.read.json b/manifests/capabilities/trade.alert.read.json
nnew file mode 100644
iindex 00000000..8252eeac
---- /dev/null
++++ b/manifests/capabilities/trade.alert.read.json
@@@ -0,0 +1,20 @@
++{
++ "id": "trade.alert.read",
++ "version": "1.0",
++ "owner": "trade",
++ "status": "active",
++ "visibility": "first-party",
++ "description": "Read the alert rules and recent deliveries of the person in X-OV-Subject.",
++ "permissions": [
++ "trade:read"
++ ],
++ "resourceConstraints": [
++ "owner"
++ ],
++ "quotaClass": "trade-read",
++ "events": [],
++ "implementedBy": [
++ "GET /api/v1/alerts",
++ "GET /api/v1/alerts/deliveries"
++ ]
++}
ddiff --git a/manifests/capabilities/trade.context.propose.json b/manifests/capabilities/trade.context.propose.json
nnew file mode 100644
iindex 00000000..052b05b3
---- /dev/null
++++ b/manifests/capabilities/trade.context.propose.json
@@@ -0,0 +1,19 @@
++{
++ "id": "trade.context.propose",
++ "version": "1.0",
++ "owner": "trade",
++ "status": "active",
++ "visibility": "first-party",
++ "description": "Deliver a context revision. With X-OV-Origin: ai it is OpenVibe.AI output (workflow trade.summarize_market_context and its run id required): authorship ai, never attributed to a person, stored as a draft that cannot be published before a person on the editor list approves it. Text that reads as a recommendation to trade is refused.",
++ "permissions": [
++ "trade:write"
++ ],
++ "resourceConstraints": [
++ "none"
++ ],
++ "quotaClass": "trade-write",
++ "events": [],
++ "implementedBy": [
++ "POST /api/v1/instruments/:symbol/context"
++ ]
++}
ddiff --git a/manifests/capabilities/trade.context.read.json b/manifests/capabilities/trade.context.read.json
nnew file mode 100644
iindex 00000000..54c41f27
---- /dev/null
++++ b/manifests/capabilities/trade.context.read.json
@@@ -0,0 +1,20 @@
++{
++ "id": "trade.context.read",
++ "version": "1.0",
++ "owner": "trade",
++ "status": "active",
++ "visibility": "first-party",
++ "description": "Read an instrument's published context with its citations and disclosure; with ?all=1 the drafts awaiting review; and the numbered-source input for OpenVibe.AI's trade.summarize_market_context workflow.",
++ "permissions": [
++ "trade:read"
++ ],
++ "resourceConstraints": [
++ "none"
++ ],
++ "quotaClass": "trade-read",
++ "events": [],
++ "implementedBy": [
++ "GET /api/v1/instruments/:symbol/context",
++ "GET /api/v1/instruments/:symbol/context/input"
++ ]
++}
ddiff --git a/manifests/capabilities/trade.instrument.manage.json b/manifests/capabilities/trade.instrument.manage.json
nnew file mode 100644
iindex 00000000..33fb07fd
---- /dev/null
++++ b/manifests/capabilities/trade.instrument.manage.json
@@@ -0,0 +1,24 @@
++{
++ "id": "trade.instrument.manage",
++ "version": "1.0",
++ "owner": "trade",
++ "status": "active",
++ "visibility": "first-party",
++ "description": "Create and edit instruments (symbol, name, kind, exchange, CIK, currency, status) and add ticker, CIK or name aliases. People must also be on the Trade editor list.",
++ "permissions": [
++ "trade:write"
++ ],
++ "resourceConstraints": [
++ "none"
++ ],
++ "quotaClass": "trade-write",
++ "events": [
++ "trade.index_document.upserted",
++ "trade.index_document.deleted"
++ ],
++ "implementedBy": [
++ "POST /api/v1/instruments",
++ "PATCH /api/v1/instruments/:symbol",
++ "POST /api/v1/instruments/:symbol/aliases"
++ ]
++}
ddiff --git a/manifests/capabilities/trade.instrument.resolve.json b/manifests/capabilities/trade.instrument.resolve.json
nnew file mode 100644
iindex 00000000..a8540d98
---- /dev/null
++++ b/manifests/capabilities/trade.instrument.resolve.json
@@@ -0,0 +1,19 @@
++{
++ "id": "trade.instrument.resolve",
++ "version": "1.0",
++ "owner": "trade",
++ "status": "active",
++ "visibility": "first-party",
++ "description": "Resolve a ticker, SEC CIK or exact company name to an instrument, deterministically (CIK, then ticker, then exact normalised name; several name matches are \"ambiguous\" and none is chosen). Browsers and anonymous readers need no capability.",
++ "permissions": [
++ "trade:read"
++ ],
++ "resourceConstraints": [
++ "none"
++ ],
++ "quotaClass": "trade-read",
++ "events": [],
++ "implementedBy": [
++ "GET /api/v1/instruments/resolve"
++ ]
++}
ddiff --git a/manifests/capabilities/trade.observation.write.json b/manifests/capabilities/trade.observation.write.json
nnew file mode 100644
iindex 00000000..9e8a398a
---- /dev/null
++++ b/manifests/capabilities/trade.observation.write.json
@@@ -0,0 +1,26 @@
++{
++ "id": "trade.observation.write",
++ "version": "1.0",
++ "owner": "trade",
++ "status": "active",
++ "visibility": "first-party",
++ "description": "Record a market observation a source stated: value exactly as stated, unit, currency, observed_at (required, never inferred), source key and reference, retrieved_at (required). Idempotent per (source_key, source_ref); a different value under the same reference is 409. Services only.",
++ "permissions": [
++ "trade:write"
++ ],
++ "resourceConstraints": [
++ "none"
++ ],
++ "quotaClass": "trade-write",
++ "events": [
++ "trade.observation.created",
++ "trade.alert.triggered",
++ "trade.source.stale",
++ "trade.source.recovered",
++ "trade.index_document.upserted",
++ "trade.index_document.deleted"
++ ],
++ "implementedBy": [
++ "POST /api/v1/observations"
++ ]
++}
ddiff --git a/manifests/capabilities/trade.watchlist.create.json b/manifests/capabilities/trade.watchlist.create.json
nnew file mode 100644
iindex 00000000..488f6220
---- /dev/null
++++ b/manifests/capabilities/trade.watchlist.create.json
@@@ -0,0 +1,19 @@
++{
++ "id": "trade.watchlist.create",
++ "version": "1.0",
++ "owner": "trade",
++ "status": "active",
++ "visibility": "first-party",
++ "description": "Create a private watchlist for the person in X-OV-Subject.",
++ "permissions": [
++ "trade:write"
++ ],
++ "resourceConstraints": [
++ "owner"
++ ],
++ "quotaClass": "trade-write",
++ "events": [],
++ "implementedBy": [
++ "POST /api/v1/watchlists"
++ ]
++}
ddiff --git a/manifests/capabilities/trade.watchlist.delete.json b/manifests/capabilities/trade.watchlist.delete.json
nnew file mode 100644
iindex 00000000..5db90397
---- /dev/null
++++ b/manifests/capabilities/trade.watchlist.delete.json
@@@ -0,0 +1,19 @@
++{
++ "id": "trade.watchlist.delete",
++ "version": "1.0",
++ "owner": "trade",
++ "status": "active",
++ "visibility": "first-party",
++ "description": "Delete a watchlist of the person in X-OV-Subject.",
++ "permissions": [
++ "trade:write"
++ ],
++ "resourceConstraints": [
++ "owner"
++ ],
++ "quotaClass": "trade-write",
++ "events": [],
++ "implementedBy": [
++ "DELETE /api/v1/watchlists/:id"
++ ]
++}
ddiff --git a/manifests/capabilities/trade.watchlist.read.json b/manifests/capabilities/trade.watchlist.read.json
nnew file mode 100644
iindex 00000000..b09630b1
---- /dev/null
++++ b/manifests/capabilities/trade.watchlist.read.json
@@@ -0,0 +1,20 @@
++{
++ "id": "trade.watchlist.read",
++ "version": "1.0",
++ "owner": "trade",
++ "status": "active",
++ "visibility": "first-party",
++ "description": "Read the watchlists of the person in X-OV-Subject (never anyone else's: another person's watchlist is 404).",
++ "permissions": [
++ "trade:read"
++ ],
++ "resourceConstraints": [
++ "owner"
++ ],
++ "quotaClass": "trade-read",
++ "events": [],
++ "implementedBy": [
++ "GET /api/v1/watchlists",
++ "GET /api/v1/watchlists/:id"
++ ]
++}
ddiff --git a/manifests/capabilities/trade.watchlist.update.json b/manifests/capabilities/trade.watchlist.update.json
nnew file mode 100644
iindex 00000000..57e45395
---- /dev/null
++++ b/manifests/capabilities/trade.watchlist.update.json
@@@ -0,0 +1,21 @@
++{
++ "id": "trade.watchlist.update",
++ "version": "1.0",
++ "owner": "trade",
++ "status": "active",
++ "visibility": "first-party",
++ "description": "Rename a watchlist of the person in X-OV-Subject, or add and remove instruments on it.",
++ "permissions": [
++ "trade:write"
++ ],
++ "resourceConstraints": [
++ "owner"
++ ],
++ "quotaClass": "trade-write",
++ "events": [],
++ "implementedBy": [
++ "PATCH /api/v1/watchlists/:id",
++ "PUT /api/v1/watchlists/:id/items/:symbol",
++ "DELETE /api/v1/watchlists/:id/items/:symbol"
++ ]
++}
ddiff --git a/manifests/services/trade.json b/manifests/services/trade.json
iindex b6d17d94..f79a9f3e 100644
---- a/manifests/services/trade.json
++++ b/manifests/services/trade.json
@@@ -1,16 +1,48 @@
{
"version": "0.1.0",
"contractRanges": {
-- "openvibe-contracts": "^0.1.0"
++ "openvibe-contracts": ">=0.19.0 <1.0.0"
},
"id": "trade",
"name": "OpenVibe.Trade",
-- "status": "placeholder",
++ "status": "alpha",
"repository": "OpenVibers/OpenVibe.Trade",
-- "domains": [],
-- "capabilities": [],
-- "eventsProduced": [],
-- "eventsConsumed": [],
-- "namespacesOwned": [],
-- "notes": "Informational watchlists, sourced market context and alerts. No custody, no order execution. Charter only; no runtime."
++ "domains": [
++ "openvibe.trade"
++ ],
++ "publicOrigin": "https://openvibe.trade",
++ "health": "/api/health",
++ "ready": "/api/ready",
++ "capabilities": [
++ "trade.instrument.resolve",
++ "trade.instrument.manage",
++ "trade.observation.write",
++ "trade.context.read",
++ "trade.context.propose",
++ "trade.watchlist.read",
++ "trade.watchlist.create",
++ "trade.watchlist.update",
++ "trade.watchlist.delete",
++ "trade.alert.read",
++ "trade.alert.create",
++ "trade.alert.delete"
++ ],
++ "eventsProduced": [
++ "trade.observation.created",
++ "trade.alert.triggered",
++ "trade.source.stale",
++ "trade.source.recovered",
++ "trade.index_document.upserted",
++ "trade.index_document.deleted"
++ ],
++ "eventsConsumed": [
++ "sources.item.created",
++ "sources.item.updated",
++ "sources.item.removed",
++ "sources.fetch.failed"
++ ],
++ "namespacesOwned": [
++ "trade.*"
++ ],
++ "notes": "Port 4860. Informational only (ADR-025): no custody, order execution, escrow, listings between users or personalised advice. Owns trade_instruments, trade_instrument_aliases, trade_watchlists, trade_watchlist_items, trade_market_observations, trade_source_documents, trade_alert_rules, trade_alert_deliveries, trade_context_revisions in its own SQLite. Reads OpenVibe.Sources (sources.item.read, sources.source.read, category trade) by cursor and wakes on signed sources.* webhook deliveries; consumes OpenVibe.AI trade.summarize_market_context output as reviewed drafts; publishes through OpenVibe.Events (events.event.publish); OpenVibe.Search reads trade.index_document.* from Events."
}
ddiff --git a/package.json b/package.json
iindex 52f00916..ec2e3bf5 100644
---- a/package.json
++++ b/package.json
@@@ -1,6 +1,6 @@
{
"name": "openvibe-contracts",
-- "version": "0.21.0",
++ "version": "0.22.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",