openvibers/openvibe.contracts Commits

A6: agent.timeline-entry@1 and the agent.step.* events (0.316.0) (#321)

OP OpenVibers committed 6 days ago · c5c7b0b692 · 71 files, +1936 −104

* A6: the agent's timeline contract and the agent.step.* events

* A6: the timeline capability names the live stream too

* A6: the release number is 0.313.0 (0.312.0 is claimed by #320)

* Merge remote-tracking branch 'origin/main' into a6/one-timeline

# Conflicts:
#	CHANGELOG.md
#	generated/openapi/actor.json
#	generated/openapi/ai.json
#	generated/openapi/bench.json
#	generated/openapi/billing.json
#	generated/openapi/blog.json
#	generated/openapi/bot.json
#	generated/openapi/chat.json
#	generated/openapi/codes.json
#	generated/openapi/community.json
#	generated/openapi/coupons.json
#	generated/openapi/deals.json
#	generated/openapi/domains.json
#	generated/openapi/events.json
#	generated/openapi/food.json
#	generated/openapi/games.json
#	generated/openapi/host.json
#	generated/openapi/index.json
#	generated/openapi/inventory.json
#	generated/openapi/live.json
#	generated/openapi/media-hub.json
#	generated/openapi/media.json
#	generated/openapi/network.json
#	generated/openapi/news.json
#	generated/openapi/openre.json
#	generated/openapi/play.json
#	generated/openapi/quest.json
#	generated/openapi/report.json
#	generated/openapi/reviews.json
#	generated/openapi/run.json
#	generated/openapi/search.json
#	generated/openapi/services.json
#	generated/openapi/sources.json
#	generated/openapi/space.json
#	generated/openapi/tips.json
#	generated/openapi/today.json
#	generated/openapi/tools.json
#	generated/openapi/trade.json
#	generated/openapi/vip.json
#	generated/openapi/vision.json
#	generated/openapi/watch.json
#	generated/openapi/wiki.json
#	generated/openapi/work.json
#	generated/openapi/zone.json
#	package.json

* A6: merge main into the timeline contracts; 0.316.0 (0.313.0 stays unused)

Changes

ddiff --git a/CHANGELOG.md b/CHANGELOG.md
iindex 238b2781..ff9b4170 100644
---- a/CHANGELOG.md
++++ b/CHANGELOG.md
@@@ -1,5 +1,13 @@
# Changelog
++## 0.316.0 — 2026-11-07
++
++- Add `agent.timeline-entry@1`: one entry of the agent's timeline (design 2026-11-07 §2) — one step of the agent's work, in one mode, for one person. It carries the mode, the product, the step's own id, a plain title, when it started and ended, its status (running, waiting, needs_you, done, failed, stopped), the placement (where it ran and why), the cost, a link to the step's page, the one-line reason when it failed, the transition sentence when the mode changed, and the audience (private is Only me, the default). It never carries a prompt, a diff or a page.
++- Add `common.agent-step@1` and the three events `agent.step.started`, `agent.step.updated` and `agent.step.ended`: the one shape every mode publishes when the agent does something (Chat, Codes, Run, Watch, Live, Surf), with the person's subject on the envelope. The payload is the step's shape only — a title, an outcome, a link, a cost — and never the step's content: a prompt, a diff, a page, a message or a file is refused by the schema. The `agent.*` namespace belongs to the network (like `provider.*`), so any first-party mode may publish into it; OpenVibe.Actor registers the family in Contracts and keeps the one timeline behind the Dock.
++- Add `agent.timeline-list-result@1`: what the Dock's Agent panel reads — the step happening now, what needs the person (oldest first), the entries themselves (newest first), the next cursor, and the per-mode counts so a filter never hides without a count.
++- Add `actor.timeline.read`: `GET /api/v1/agent/timeline`, the person's own timeline with the cursor and the mode and needs-you filters. Only their own entries; another person's entry is a 404.
++- Valid and invalid fixtures cover a step that starts, waits and ends, a timeline entry and a list, a payload with a prompt or a diff in it, an unknown status, a mode that is not one of the seven, and an entry of another person.
++
## 0.315.0 — 2026-11-07
- The owner's Setup tab reaches seven more services: `<service>.config.manage` for `chat`, `connect`, `deals`, `work`, `sources`, `design` and `domains` is now **active** and listed in each service's manifest, because each mounts openvibe-shared/config's routes on `/internal/config` (`GET /internal/config`, `GET|POST /internal/config/:namespace`, `PUT|DELETE /internal/config/:namespace/secrets/:key`, `POST /internal/config/:namespace/test/:key`). Only Network's admin proxy, acting for the owner, holds them and they are never grantable to apps. `media.config.manage` stays planned until Media mounts the routes.
@@@ -12,10 +20,6 @@
- Add `live.agent-sandbox-worker-request@1`: the worker's check-in body, which names the five isolation facts Live reads exactly (`host_network` false, `credentials` false, `profile` false, `egress_proxy` true, `workspace` `ephemeral`) and may carry the worker's own checks, limits, versions and counts. A worker that cannot say each of the five is not registered. Add `live.agent-sandbox-worker-result@1`: the worker's state for the stream's owner, with the reason when there is no healthy one, the last check-in and the minute a check-in counts for. Live never returns an endpoint: there is none.
- Valid and invalid fixtures cover a full worker check-in and an isolation-only one, a worker with the host's network and one that cannot say there is no profile, and a healthy worker, a stale one, a missing stale window and an unknown state code.
--## 0.313.0 — 2026-11-07
--
--- Placeholder for the 0.313.0 that #321 claims (A6: `agent.timeline-entry@1` and the agent.step.* events). This line keeps the history whole until that pull request merges; it is replaced by that release's own entry then.
--
## 0.312.0 — 2026-11-07
- Add the Codes skills-hub records (the Compute plan §5, E6). `codes.skill@1` is one skill, rule, MCP server, command or hook: its owner, kind, stable slug, title, summary, the four sharing audiences (`private`, `people`, `link`, `public`), the harnesses it is written for, the newest version and that version's body. A `private`, `people` or `link` record is never in the gallery; only `public` is. The body is untrusted Markdown and the page renders it through the markup gate.
@@@ -45,7 +49,6 @@
- `network.node.self.manage` names the five pool routes a machine calls with its own token (announce, read, approve, renew readiness, leave) in `implementedBy`.
- Valid and invalid fixtures cover a pool waiting for approvals, an approved pool of three, a single-machine offer, a pool's offer and one still waiting, a group offer, a missing head or owner, a one-machine pool, a repeated member, a private key in the certificate slot, a public, loopback or wildcard address, a port under 1024, and an address, certificate or key smuggled into a field the schema does not name.
--
## 0.308.0 — 2026-11-07
- Add `ai.memory-export@1` (Memory M5): the one portable memory file. It carries `format: openvibe.memory-export@1`, `version: 1`, `exported_at` and every item's text, kind, scope, source, confidence and source reference. It deliberately has no ids, owners, merge links or conflict pair, so a file can be imported into another account without carrying anyone's identity, and a profile is derived from the items and rebuilt, never imported. OpenVibe.AI's `GET /api/v1/memory/export` writes it and `POST /api/v1/memory/import` accepts the same document; both redact again.
@@@ -149,7 +152,6 @@
- PUT accepts `notify` (default true); access requests can be `dismissed`; a transfer request accepts `{ name }` or `{ subject }`.
- Add the five `share.*` event payloads with strict ids-only fields; Network owns the model, adopting services produce events using their own source. Valid and invalid fixtures cover every new contract. No existing schema changes.
--
## 0.290.0 — 2026-11-05
- **A comma-separated body, and an identity from several columns** (OpenVibe.Food's USDA ERS fruit and vegetable
@@@ -585,7 +587,6 @@
session on AI's own site behind a same-origin check, reaches them. A service token is refused, and so is any token
carrying `on_behalf_of`, whatever capabilities it holds (the AI #204/#205 rule).
--
## 0.256.0 — 2026-10-31
- **`ai.looks` is retired** (`network.consent@1`). The owner removed the rule that AI text never describes people
ddiff --git a/contracts/agent/timeline-entry.v1.json b/contracts/agent/timeline-entry.v1.json
nnew file mode 100644
iindex 00000000..640b4dcc
---- /dev/null
++++ b/contracts/agent/timeline-entry.v1.json
@@@ -0,0 +1,173 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/agent/timeline-entry.v1.json",
++ "title": "AgentTimelineEntry",
++ "description": "One entry of the agent's timeline (design 2026-11-07 §2): one step of the agent's work, in one mode, for one person. The Dock shows it: the mode's icon and word, the title, where it ran and why, the outcome, the time and the cost. Only a title, an outcome and a link: never a prompt, a diff or a page. A person sees their own entries; another person's entry is a 404. The audience is 'private' (Only me) unless the person shared the entry through the one Share sheet.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "id",
++ "subject",
++ "mode",
++ "product",
++ "title",
++ "status",
++ "started_at",
++ "audience"
++ ],
++ "properties": {
++ "id": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 80
++ },
++ "subject": {
++ "type": "string",
++ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$",
++ "description": "The person the step was for."
++ },
++ "mode": {
++ "enum": [
++ "talk",
++ "act",
++ "run",
++ "code",
++ "browse",
++ "watch",
++ "stream"
++ ]
++ },
++ "product": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 40
++ },
++ "ref": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 120
++ },
++ "title": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 160
++ },
++ "started_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "ended_at": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "format": "date-time"
++ },
++ "status": {
++ "enum": [
++ "running",
++ "waiting",
++ "needs_you",
++ "done",
++ "failed",
++ "stopped"
++ ]
++ },
++ "placement": {
++ "type": [
++ "object",
++ "null"
++ ],
++ "additionalProperties": false,
++ "description": "Where the step ran and why the agent put it there, in one line each.",
++ "properties": {
++ "where": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 160
++ },
++ "why": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 240
++ }
++ }
++ },
++ "cost_usd": {
++ "type": [
++ "number",
++ "null"
++ ],
++ "minimum": 0
++ },
++ "link": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "pattern": "^https://",
++ "maxLength": 2048
++ },
++ "reason": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 240
++ },
++ "transition": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 240
++ },
++ "approval": {
++ "type": [
++ "object",
++ "null"
++ ],
++ "additionalProperties": false,
++ "description": "The approval this step waits on, and the mode that owns it. The person answers it in the mode.",
++ "properties": {
++ "product": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 40
++ },
++ "id": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 80
++ },
++ "kind": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 40
++ }
++ }
++ },
++ "audience": {
++ "enum": [
++ "private",
++ "link",
++ "people",
++ "public"
++ ],
++ "description": "Who may see it. 'private' is Only me, the default; the other three come from the one Share sheet."
++ },
++ "shared": {
++ "type": [
++ "boolean",
++ "null"
++ ],
++ "description": "Whether the person shared this entry (the share row itself lives in the sharing system)."
++ }
++ }
++}
ddiff --git a/contracts/agent/timeline-list-result.v1.json b/contracts/agent/timeline-list-result.v1.json
nnew file mode 100644
iindex 00000000..3aa96d83
---- /dev/null
++++ b/contracts/agent/timeline-list-result.v1.json
@@@ -0,0 +1,59 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/agent/timeline-list-result.v1.json",
++ "title": "AgentTimelineListResult",
++ "description": "The person's agent timeline (design 2026-11-07 §1): what the agent is doing now, what needs them, and the entries themselves, newest first. The Dock's filters live in the query (cursor, mode, needs_you); counts say how many entries a hidden filter would show, so a filter never hides without a count.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "now",
++ "needs_you",
++ "entries",
++ "next_cursor",
++ "counts"
++ ],
++ "properties": {
++ "now": {
++ "anyOf": [
++ {
++ "$ref": "./timeline-entry.v1.json"
++ },
++ {
++ "type": "null"
++ }
++ ],
++ "description": "The step the agent is doing this moment, if any."
++ },
++ "needs_you": {
++ "type": "array",
++ "maxItems": 50,
++ "items": {
++ "$ref": "./timeline-entry.v1.json"
++ },
++ "description": "Every approval or question from any mode, oldest first."
++ },
++ "entries": {
++ "type": "array",
++ "maxItems": 200,
++ "items": {
++ "$ref": "./timeline-entry.v1.json"
++ }
++ },
++ "next_cursor": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 200,
++ "description": "The cursor of the next page, or null at the end."
++ },
++ "counts": {
++ "type": "object",
++ "additionalProperties": {
++ "type": "integer",
++ "minimum": 0
++ },
++ "description": "How many entries each mode has (and \"needs_you\"), so the Dock can show what a filter would hide."
++ }
++ }
++}
ddiff --git a/contracts/catalog.json b/contracts/catalog.json
iindex b5ae3788..bf910e84 100644
---- a/contracts/catalog.json
++++ b/contracts/catalog.json
@@@ -9717,6 +9717,60 @@
"visibility": "first-party",
"compatibility": "backward",
"status": "active"
++ },
++ {
++ "id": "common.agent-step",
++ "version": "1.0.0",
++ "owner": "contracts",
++ "schema": "common/agent-step.v1.json",
++ "visibility": "first-party",
++ "compatibility": "backward",
++ "status": "active"
++ },
++ {
++ "id": "agent.step.started",
++ "version": "1.0.0",
++ "owner": "actor",
++ "schema": "events/payloads/agent.step.started.v1.json",
++ "visibility": "first-party",
++ "compatibility": "backward",
++ "status": "active"
++ },
++ {
++ "id": "agent.step.updated",
++ "version": "1.0.0",
++ "owner": "actor",
++ "schema": "events/payloads/agent.step.updated.v1.json",
++ "visibility": "first-party",
++ "compatibility": "backward",
++ "status": "active"
++ },
++ {
++ "id": "agent.step.ended",
++ "version": "1.0.0",
++ "owner": "actor",
++ "schema": "events/payloads/agent.step.ended.v1.json",
++ "visibility": "first-party",
++ "compatibility": "backward",
++ "status": "active"
++ },
++ {
++ "id": "agent.timeline-entry",
++ "version": "1.0.0",
++ "owner": "actor",
++ "schema": "agent/timeline-entry.v1.json",
++ "visibility": "first-party",
++ "compatibility": "backward",
++ "status": "active"
++ },
++ {
++ "id": "agent.timeline-list-result",
++ "version": "1.0.0",
++ "owner": "actor",
++ "schema": "agent/timeline-list-result.v1.json",
++ "visibility": "first-party",
++ "compatibility": "backward",
++ "status": "active"
}
]
}
ddiff --git a/contracts/common/agent-step.v1.json b/contracts/common/agent-step.v1.json
nnew file mode 100644
iindex 00000000..56e39807
---- /dev/null
++++ b/contracts/common/agent-step.v1.json
@@@ -0,0 +1,158 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/common/agent-step.v1.json",
++ "title": "AgentStepPayload",
++ "description": "One step of the agent's work, as any mode publishes it (agent.step.started, agent.step.updated, agent.step.ended; design 2026-11-07 §2). The person it is for is the envelope's subject. The payload is the step's shape: what it is, where it ran, why, how it ended, what it cost, and where to see it. It never carries the step's content: no prompt, no diff, no page, no message, no file. The three events share this payload; what differs is the envelope's event_type. The agent.* namespace belongs to the network, so any first-party mode may publish into it (like provider.*); OpenVibe.Actor registers the family and keeps the timeline.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "step_id",
++ "mode",
++ "product",
++ "title",
++ "status",
++ "started_at"
++ ],
++ "properties": {
++ "step_id": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 80,
++ "description": "The mode's own id for this step (a Codes task id, a Run job id, a stream id)."
++ },
++ "mode": {
++ "enum": [
++ "talk",
++ "act",
++ "run",
++ "code",
++ "browse",
++ "watch",
++ "stream"
++ ],
++ "description": "The mode the step belongs to."
++ },
++ "product": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 40,
++ "description": "The product that ran it (chat, codes, run, watch, live, surf, actor)."
++ },
++ "ref": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 120,
++ "description": "The product's own id for the thing this step is about."
++ },
++ "title": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 160,
++ "description": "A short plain-text name for the step. What it was, never what it said."
++ },
++ "status": {
++ "enum": [
++ "running",
++ "waiting",
++ "needs_you",
++ "done",
++ "failed",
++ "stopped"
++ ]
++ },
++ "started_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "ended_at": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "format": "date-time"
++ },
++ "placement": {
++ "type": [
++ "object",
++ "null"
++ ],
++ "additionalProperties": false,
++ "description": "Where the step ran and why the agent put it there, in one line each.",
++ "properties": {
++ "where": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 160
++ },
++ "why": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 240
++ }
++ }
++ },
++ "cost_usd": {
++ "type": [
++ "number",
++ "null"
++ ],
++ "minimum": 0
++ },
++ "link": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "pattern": "^https://",
++ "maxLength": 2048,
++ "description": "The step's own page in its product."
++ },
++ "reason": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 240,
++ "description": "Why it failed or stopped, in one line a person can act on."
++ },
++ "transition": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 240,
++ "description": "The agent's sentence for the mode change this step announced."
++ },
++ "approval": {
++ "type": [
++ "object",
++ "null"
++ ],
++ "additionalProperties": false,
++ "description": "The approval this step waits on, and the mode that owns it. The person answers it in the mode.",
++ "properties": {
++ "product": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 40
++ },
++ "id": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 80
++ },
++ "kind": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 40
++ }
++ }
++ }
++ }
++}
ddiff --git a/contracts/events/payloads/agent.step.ended.v1.json b/contracts/events/payloads/agent.step.ended.v1.json
nnew file mode 100644
iindex 00000000..7a4834fe
---- /dev/null
++++ b/contracts/events/payloads/agent.step.ended.v1.json
@@@ -0,0 +1,7 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/events/payloads/agent.step.ended.v1.json",
++ "title": "AgentStepEndedPayload",
++ "description": "agent.step.ended v1 (design 2026-11-07 §2). A step ended: it is done, it failed, or the person stopped it. Envelope: source the mode that ran it, subject the person it is for, visibility internal. The payload is common.agent-step@1: titles, outcomes and links only, never a prompt or a diff.",
++ "$ref": "../../common/agent-step.v1.json"
++}
ddiff --git a/contracts/events/payloads/agent.step.started.v1.json b/contracts/events/payloads/agent.step.started.v1.json
nnew file mode 100644
iindex 00000000..21e37bbf
---- /dev/null
++++ b/contracts/events/payloads/agent.step.started.v1.json
@@@ -0,0 +1,7 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/events/payloads/agent.step.started.v1.json",
++ "title": "AgentStepStartedPayload",
++ "description": "agent.step.started v1 (design 2026-11-07 §2). A step began: the mode started working on it. Envelope: source the mode that runs it (a first-party service), subject the person it is for, visibility internal, actor the person or the mode. The payload is common.agent-step@1: titles, outcomes and links only, never a prompt or a diff.",
++ "$ref": "../../common/agent-step.v1.json"
++}
ddiff --git a/contracts/events/payloads/agent.step.updated.v1.json b/contracts/events/payloads/agent.step.updated.v1.json
nnew file mode 100644
iindex 00000000..f55e4f32
---- /dev/null
++++ b/contracts/events/payloads/agent.step.updated.v1.json
@@@ -0,0 +1,7 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/events/payloads/agent.step.updated.v1.json",
++ "title": "AgentStepUpdatedPayload",
++ "description": "agent.step.updated v1 (design 2026-11-07 §2). A step changed: it is waiting, it needs the person, or it moved on. The same payload as agent.step.started; the envelope says what changed. The payload is common.agent-step@1: titles, outcomes and links only, never a prompt or a diff.",
++ "$ref": "../../common/agent-step.v1.json"
++}
ddiff --git a/fixtures/agent.step.ended/invalid/unknown-status.json b/fixtures/agent.step.ended/invalid/unknown-status.json
nnew file mode 100644
iindex 00000000..f4b3bfd5
---- /dev/null
++++ b/fixtures/agent.step.ended/invalid/unknown-status.json
@@@ -0,0 +1,19 @@
++{
++ "step_id": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "mode": "code",
++ "product": "codes",
++ "ref": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "title": "Running the checkout tests",
++ "status": "maybe",
++ "started_at": "2026-11-07T09:00:00.000Z",
++ "ended_at": null,
++ "placement": {
++ "where": "On your desktop",
++ "why": "it needs your files and your Claude sign-in, and it is free"
++ },
++ "cost_usd": null,
++ "link": "https://codes.openvibe.network/tasks/tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "reason": null,
++ "transition": null,
++ "approval": null
++}
ddiff --git a/fixtures/agent.step.ended/valid/done.json b/fixtures/agent.step.ended/valid/done.json
nnew file mode 100644
iindex 00000000..f7fc1d78
---- /dev/null
++++ b/fixtures/agent.step.ended/valid/done.json
@@@ -0,0 +1,19 @@
++{
++ "step_id": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "mode": "code",
++ "product": "codes",
++ "ref": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "title": "Running the checkout tests",
++ "status": "done",
++ "started_at": "2026-11-07T09:00:00.000Z",
++ "ended_at": "2026-11-07T09:04:00.000Z",
++ "placement": {
++ "where": "On your desktop",
++ "why": "it needs your files and your Claude sign-in, and it is free"
++ },
++ "cost_usd": 0.42,
++ "link": "https://codes.openvibe.network/tasks/tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "reason": null,
++ "transition": null,
++ "approval": null
++}
ddiff --git a/fixtures/agent.step.started/invalid/with-prompt.json b/fixtures/agent.step.started/invalid/with-prompt.json
nnew file mode 100644
iindex 00000000..3d0ae4f9
---- /dev/null
++++ b/fixtures/agent.step.started/invalid/with-prompt.json
@@@ -0,0 +1,20 @@
++{
++ "step_id": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "mode": "code",
++ "product": "codes",
++ "ref": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "title": "Running the checkout tests",
++ "status": "running",
++ "started_at": "2026-11-07T09:00:00.000Z",
++ "ended_at": null,
++ "placement": {
++ "where": "On your desktop",
++ "why": "it needs your files and your Claude sign-in, and it is free"
++ },
++ "cost_usd": null,
++ "link": "https://codes.openvibe.network/tasks/tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "reason": null,
++ "transition": null,
++ "approval": null,
++ "prompt": "the prompt the person typed"
++}
ddiff --git a/fixtures/agent.step.started/valid/codes-step.json b/fixtures/agent.step.started/valid/codes-step.json
nnew file mode 100644
iindex 00000000..96aea181
---- /dev/null
++++ b/fixtures/agent.step.started/valid/codes-step.json
@@@ -0,0 +1,19 @@
++{
++ "step_id": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "mode": "code",
++ "product": "codes",
++ "ref": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "title": "Running the checkout tests",
++ "status": "running",
++ "started_at": "2026-11-07T09:00:00.000Z",
++ "ended_at": null,
++ "placement": {
++ "where": "On your desktop",
++ "why": "it needs your files and your Claude sign-in, and it is free"
++ },
++ "cost_usd": null,
++ "link": "https://codes.openvibe.network/tasks/tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "reason": null,
++ "transition": null,
++ "approval": null
++}
ddiff --git a/fixtures/agent.step.updated/invalid/with-diff.json b/fixtures/agent.step.updated/invalid/with-diff.json
nnew file mode 100644
iindex 00000000..f2823192
---- /dev/null
++++ b/fixtures/agent.step.updated/invalid/with-diff.json
@@@ -0,0 +1,20 @@
++{
++ "step_id": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "mode": "code",
++ "product": "codes",
++ "ref": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "title": "Running the checkout tests",
++ "status": "running",
++ "started_at": "2026-11-07T09:00:00.000Z",
++ "ended_at": null,
++ "placement": {
++ "where": "On your desktop",
++ "why": "it needs your files and your Claude sign-in, and it is free"
++ },
++ "cost_usd": null,
++ "link": "https://codes.openvibe.network/tasks/tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "reason": null,
++ "transition": null,
++ "approval": null,
++ "diff": "@@ -1 +1 @@"
++}
ddiff --git a/fixtures/agent.step.updated/valid/waiting.json b/fixtures/agent.step.updated/valid/waiting.json
nnew file mode 100644
iindex 00000000..4073a027
---- /dev/null
++++ b/fixtures/agent.step.updated/valid/waiting.json
@@@ -0,0 +1,19 @@
++{
++ "step_id": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "mode": "code",
++ "product": "codes",
++ "ref": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "title": "Waiting for CI on #167",
++ "status": "waiting",
++ "started_at": "2026-11-07T09:00:00.000Z",
++ "ended_at": null,
++ "placement": {
++ "where": "On your desktop",
++ "why": "it needs your files and your Claude sign-in, and it is free"
++ },
++ "cost_usd": null,
++ "link": "https://codes.openvibe.network/tasks/tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "reason": null,
++ "transition": null,
++ "approval": null
++}
ddiff --git a/fixtures/agent.timeline-entry/invalid/with-prompt.json b/fixtures/agent.timeline-entry/invalid/with-prompt.json
nnew file mode 100644
iindex 00000000..49b05896
---- /dev/null
++++ b/fixtures/agent.timeline-entry/invalid/with-prompt.json
@@@ -0,0 +1,23 @@
++{
++ "id": "tl_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "subject": "usr_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "mode": "code",
++ "product": "codes",
++ "ref": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "title": "Running the checkout tests",
++ "started_at": "2026-11-07T09:00:00.000Z",
++ "ended_at": "2026-11-07T09:04:00.000Z",
++ "status": "done",
++ "placement": {
++ "where": "On your desktop",
++ "why": "it needs your files and your Claude sign-in, and it is free"
++ },
++ "cost_usd": 0.42,
++ "link": "https://codes.openvibe.network/tasks/tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "reason": null,
++ "transition": null,
++ "approval": null,
++ "audience": "private",
++ "shared": false,
++ "prompt": "the prompt the person typed"
++}
ddiff --git a/fixtures/agent.timeline-entry/valid/entry.json b/fixtures/agent.timeline-entry/valid/entry.json
nnew file mode 100644
iindex 00000000..d99cf854
---- /dev/null
++++ b/fixtures/agent.timeline-entry/valid/entry.json
@@@ -0,0 +1,22 @@
++{
++ "id": "tl_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "subject": "usr_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "mode": "code",
++ "product": "codes",
++ "ref": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "title": "Running the checkout tests",
++ "started_at": "2026-11-07T09:00:00.000Z",
++ "ended_at": "2026-11-07T09:04:00.000Z",
++ "status": "done",
++ "placement": {
++ "where": "On your desktop",
++ "why": "it needs your files and your Claude sign-in, and it is free"
++ },
++ "cost_usd": 0.42,
++ "link": "https://codes.openvibe.network/tasks/tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "reason": null,
++ "transition": null,
++ "approval": null,
++ "audience": "private",
++ "shared": false
++}
ddiff --git a/fixtures/agent.timeline-list-result/invalid/entry-with-prompt.json b/fixtures/agent.timeline-list-result/invalid/entry-with-prompt.json
nnew file mode 100644
iindex 00000000..eb0595b3
---- /dev/null
++++ b/fixtures/agent.timeline-list-result/invalid/entry-with-prompt.json
@@@ -0,0 +1,31 @@
++{
++ "now": null,
++ "needs_you": [],
++ "entries": [
++ {
++ "id": "tl_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "subject": "usr_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "mode": "code",
++ "product": "codes",
++ "ref": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "title": "Running the checkout tests",
++ "started_at": "2026-11-07T09:00:00.000Z",
++ "ended_at": "2026-11-07T09:04:00.000Z",
++ "status": "done",
++ "placement": {
++ "where": "On your desktop",
++ "why": "it needs your files and your Claude sign-in, and it is free"
++ },
++ "cost_usd": 0.42,
++ "link": "https://codes.openvibe.network/tasks/tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "reason": null,
++ "transition": null,
++ "approval": null,
++ "audience": "private",
++ "shared": false,
++ "diff": "@@ -1 +1 @@"
++ }
++ ],
++ "next_cursor": null,
++ "counts": {}
++}
ddiff --git a/fixtures/agent.timeline-list-result/valid/list.json b/fixtures/agent.timeline-list-result/valid/list.json
nnew file mode 100644
iindex 00000000..8d8fc222
---- /dev/null
++++ b/fixtures/agent.timeline-list-result/valid/list.json
@@@ -0,0 +1,34 @@
++{
++ "now": null,
++ "needs_you": [],
++ "entries": [
++ {
++ "id": "tl_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "subject": "usr_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "mode": "code",
++ "product": "codes",
++ "ref": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "title": "Running the checkout tests",
++ "started_at": "2026-11-07T09:00:00.000Z",
++ "ended_at": "2026-11-07T09:04:00.000Z",
++ "status": "done",
++ "placement": {
++ "where": "On your desktop",
++ "why": "it needs your files and your Claude sign-in, and it is free"
++ },
++ "cost_usd": 0.42,
++ "link": "https://codes.openvibe.network/tasks/tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "reason": null,
++ "transition": null,
++ "approval": null,
++ "audience": "private",
++ "shared": false
++ }
++ ],
++ "next_cursor": "tl_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "counts": {
++ "code": 1,
++ "act": 0,
++ "needs_you": 0
++ }
++}
ddiff --git a/fixtures/common.agent-step/invalid/with-prompt.json b/fixtures/common.agent-step/invalid/with-prompt.json
nnew file mode 100644
iindex 00000000..33d65efe
---- /dev/null
++++ b/fixtures/common.agent-step/invalid/with-prompt.json
@@@ -0,0 +1,20 @@
++{
++ "step_id": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "mode": "code",
++ "product": "codes",
++ "ref": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "title": "Running the checkout tests",
++ "status": "running",
++ "started_at": "2026-11-07T09:00:00.000Z",
++ "ended_at": null,
++ "placement": {
++ "where": "On your desktop",
++ "why": "it needs your files and your Claude sign-in, and it is free"
++ },
++ "cost_usd": null,
++ "link": "https://codes.openvibe.network/tasks/tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "reason": null,
++ "transition": null,
++ "approval": null,
++ "prompt": "the prompt"
++}
ddiff --git a/fixtures/common.agent-step/valid/step.json b/fixtures/common.agent-step/valid/step.json
nnew file mode 100644
iindex 00000000..96aea181
---- /dev/null
++++ b/fixtures/common.agent-step/valid/step.json
@@@ -0,0 +1,19 @@
++{
++ "step_id": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "mode": "code",
++ "product": "codes",
++ "ref": "tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "title": "Running the checkout tests",
++ "status": "running",
++ "started_at": "2026-11-07T09:00:00.000Z",
++ "ended_at": null,
++ "placement": {
++ "where": "On your desktop",
++ "why": "it needs your files and your Claude sign-in, and it is free"
++ },
++ "cost_usd": null,
++ "link": "https://codes.openvibe.network/tasks/tsk_01JAB2C3D4E5F6G7H8J9K0MNPS",
++ "reason": null,
++ "transition": null,
++ "approval": null
++}
ddiff --git a/generated/json-schema/bundle.json b/generated/json-schema/bundle.json
iindex eb4a1955..3864a04a 100644
---- a/generated/json-schema/bundle.json
++++ b/generated/json-schema/bundle.json
@@@ -107242,6 +107242,447 @@
}
}
}
++ },
++ "common.agent-step": {
++ "version": "1.0.0",
++ "owner": "contracts",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/common/agent-step.v1.json",
++ "title": "AgentStepPayload",
++ "description": "One step of the agent's work, as any mode publishes it (agent.step.started, agent.step.updated, agent.step.ended; design 2026-11-07 §2). The person it is for is the envelope's subject. The payload is the step's shape: what it is, where it ran, why, how it ended, what it cost, and where to see it. It never carries the step's content: no prompt, no diff, no page, no message, no file. The three events share this payload; what differs is the envelope's event_type. The agent.* namespace belongs to the network, so any first-party mode may publish into it (like provider.*); OpenVibe.Actor registers the family and keeps the timeline.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "step_id",
++ "mode",
++ "product",
++ "title",
++ "status",
++ "started_at"
++ ],
++ "properties": {
++ "step_id": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 80,
++ "description": "The mode's own id for this step (a Codes task id, a Run job id, a stream id)."
++ },
++ "mode": {
++ "enum": [
++ "talk",
++ "act",
++ "run",
++ "code",
++ "browse",
++ "watch",
++ "stream"
++ ],
++ "description": "The mode the step belongs to."
++ },
++ "product": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 40,
++ "description": "The product that ran it (chat, codes, run, watch, live, surf, actor)."
++ },
++ "ref": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 120,
++ "description": "The product's own id for the thing this step is about."
++ },
++ "title": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 160,
++ "description": "A short plain-text name for the step. What it was, never what it said."
++ },
++ "status": {
++ "enum": [
++ "running",
++ "waiting",
++ "needs_you",
++ "done",
++ "failed",
++ "stopped"
++ ]
++ },
++ "started_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "ended_at": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "format": "date-time"
++ },
++ "placement": {
++ "type": [
++ "object",
++ "null"
++ ],
++ "additionalProperties": false,
++ "description": "Where the step ran and why the agent put it there, in one line each.",
++ "properties": {
++ "where": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 160
++ },
++ "why": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 240
++ }
++ }
++ },
++ "cost_usd": {
++ "type": [
++ "number",
++ "null"
++ ],
++ "minimum": 0
++ },
++ "link": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "pattern": "^https://",
++ "maxLength": 2048,
++ "description": "The step's own page in its product."
++ },
++ "reason": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 240,
++ "description": "Why it failed or stopped, in one line a person can act on."
++ },
++ "transition": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 240,
++ "description": "The agent's sentence for the mode change this step announced."
++ },
++ "approval": {
++ "type": [
++ "object",
++ "null"
++ ],
++ "additionalProperties": false,
++ "description": "The approval this step waits on, and the mode that owns it. The person answers it in the mode.",
++ "properties": {
++ "product": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 40
++ },
++ "id": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 80
++ },
++ "kind": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 40
++ }
++ }
++ }
++ }
++ }
++ },
++ "agent.step.started": {
++ "version": "1.0.0",
++ "owner": "actor",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/events/payloads/agent.step.started.v1.json",
++ "title": "AgentStepStartedPayload",
++ "description": "agent.step.started v1 (design 2026-11-07 §2). A step began: the mode started working on it. Envelope: source the mode that runs it (a first-party service), subject the person it is for, visibility internal, actor the person or the mode. The payload is common.agent-step@1: titles, outcomes and links only, never a prompt or a diff.",
++ "$ref": "../../common/agent-step.v1.json"
++ }
++ },
++ "agent.step.updated": {
++ "version": "1.0.0",
++ "owner": "actor",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/events/payloads/agent.step.updated.v1.json",
++ "title": "AgentStepUpdatedPayload",
++ "description": "agent.step.updated v1 (design 2026-11-07 §2). A step changed: it is waiting, it needs the person, or it moved on. The same payload as agent.step.started; the envelope says what changed. The payload is common.agent-step@1: titles, outcomes and links only, never a prompt or a diff.",
++ "$ref": "../../common/agent-step.v1.json"
++ }
++ },
++ "agent.step.ended": {
++ "version": "1.0.0",
++ "owner": "actor",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/events/payloads/agent.step.ended.v1.json",
++ "title": "AgentStepEndedPayload",
++ "description": "agent.step.ended v1 (design 2026-11-07 §2). A step ended: it is done, it failed, or the person stopped it. Envelope: source the mode that ran it, subject the person it is for, visibility internal. The payload is common.agent-step@1: titles, outcomes and links only, never a prompt or a diff.",
++ "$ref": "../../common/agent-step.v1.json"
++ }
++ },
++ "agent.timeline-entry": {
++ "version": "1.0.0",
++ "owner": "actor",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/agent/timeline-entry.v1.json",
++ "title": "AgentTimelineEntry",
++ "description": "One entry of the agent's timeline (design 2026-11-07 §2): one step of the agent's work, in one mode, for one person. The Dock shows it: the mode's icon and word, the title, where it ran and why, the outcome, the time and the cost. Only a title, an outcome and a link: never a prompt, a diff or a page. A person sees their own entries; another person's entry is a 404. The audience is 'private' (Only me) unless the person shared the entry through the one Share sheet.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "id",
++ "subject",
++ "mode",
++ "product",
++ "title",
++ "status",
++ "started_at",
++ "audience"
++ ],
++ "properties": {
++ "id": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 80
++ },
++ "subject": {
++ "type": "string",
++ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$",
++ "description": "The person the step was for."
++ },
++ "mode": {
++ "enum": [
++ "talk",
++ "act",
++ "run",
++ "code",
++ "browse",
++ "watch",
++ "stream"
++ ]
++ },
++ "product": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 40
++ },
++ "ref": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 120
++ },
++ "title": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 160
++ },
++ "started_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "ended_at": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "format": "date-time"
++ },
++ "status": {
++ "enum": [
++ "running",
++ "waiting",
++ "needs_you",
++ "done",
++ "failed",
++ "stopped"
++ ]
++ },
++ "placement": {
++ "type": [
++ "object",
++ "null"
++ ],
++ "additionalProperties": false,
++ "description": "Where the step ran and why the agent put it there, in one line each.",
++ "properties": {
++ "where": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 160
++ },
++ "why": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 240
++ }
++ }
++ },
++ "cost_usd": {
++ "type": [
++ "number",
++ "null"
++ ],
++ "minimum": 0
++ },
++ "link": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "pattern": "^https://",
++ "maxLength": 2048
++ },
++ "reason": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 240
++ },
++ "transition": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 240
++ },
++ "approval": {
++ "type": [
++ "object",
++ "null"
++ ],
++ "additionalProperties": false,
++ "description": "The approval this step waits on, and the mode that owns it. The person answers it in the mode.",
++ "properties": {
++ "product": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 40
++ },
++ "id": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 80
++ },
++ "kind": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 40
++ }
++ }
++ },
++ "audience": {
++ "enum": [
++ "private",
++ "link",
++ "people",
++ "public"
++ ],
++ "description": "Who may see it. 'private' is Only me, the default; the other three come from the one Share sheet."
++ },
++ "shared": {
++ "type": [
++ "boolean",
++ "null"
++ ],
++ "description": "Whether the person shared this entry (the share row itself lives in the sharing system)."
++ }
++ }
++ }
++ },
++ "agent.timeline-list-result": {
++ "version": "1.0.0",
++ "owner": "actor",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/agent/timeline-list-result.v1.json",
++ "title": "AgentTimelineListResult",
++ "description": "The person's agent timeline (design 2026-11-07 §1): what the agent is doing now, what needs them, and the entries themselves, newest first. The Dock's filters live in the query (cursor, mode, needs_you); counts say how many entries a hidden filter would show, so a filter never hides without a count.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "now",
++ "needs_you",
++ "entries",
++ "next_cursor",
++ "counts"
++ ],
++ "properties": {
++ "now": {
++ "anyOf": [
++ {
++ "$ref": "./timeline-entry.v1.json"
++ },
++ {
++ "type": "null"
++ }
++ ],
++ "description": "The step the agent is doing this moment, if any."
++ },
++ "needs_you": {
++ "type": "array",
++ "maxItems": 50,
++ "items": {
++ "$ref": "./timeline-entry.v1.json"
++ },
++ "description": "Every approval or question from any mode, oldest first."
++ },
++ "entries": {
++ "type": "array",
++ "maxItems": 200,
++ "items": {
++ "$ref": "./timeline-entry.v1.json"
++ }
++ },
++ "next_cursor": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 200,
++ "description": "The cursor of the next page, or null at the end."
++ },
++ "counts": {
++ "type": "object",
++ "additionalProperties": {
++ "type": "integer",
++ "minimum": 0
++ },
++ "description": "How many entries each mode has (and \"needs_you\"), so the Dock can show what a filter would hide."
++ }
++ }
++ }
}
}
}
ddiff --git a/generated/openapi/actor.json b/generated/openapi/actor.json
iindex 6bb20299..84584f9f 100644
---- a/generated/openapi/actor.json
++++ b/generated/openapi/actor.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Actor API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for 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"
@@@ -239,6 +239,98 @@
}
}
},
++ "/api/v1/agent/timeline": {
++ "get": {
++ "operationId": "get_api_v1_agent_timeline",
++ "summary": "Read one person's agent timeline from OpenVibe.Actor (design 2026-11-07): what the agent did in every mode, newest first, with a cursor and the mode and needs-you filters, as agent.timeline-list-resul",
++ "description": "**actor.timeline.read** (first-party): Read one person's agent timeline from OpenVibe.Actor (design 2026-11-07): what the agent did in every mode, newest first, with a cursor and the mode and needs-you filters, as agent.timeline-list-result@1. GET /api/v1/agent/timeline. Only the person's own entries; titles, outcomes and links only, never a prompt or a diff.",
++ "tags": [
++ "actor.timeline"
++ ],
++ "x-openvibe-capabilities": [
++ "actor.timeline.read"
++ ],
++ "x-openvibe-visibility": [
++ "first-party"
++ ],
++ "x-openvibe-quota-class": "standard",
++ "security": [
++ {
++ "openvibeToken": [
++ "actor.timeline.read"
++ ]
++ }
++ ],
++ "responses": {
++ "2XX": {
++ "description": "Success",
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/agent.timeline-list-result.v1"
++ }
++ }
++ }
++ },
++ "default": {
++ "description": "An error (RFC 9457 problem details)",
++ "content": {
++ "application/problem+json": {
++ "schema": {
++ "$ref": "#/components/schemas/errors.problem.v1"
++ }
++ }
++ }
++ }
++ }
++ }
++ },
++ "/api/v1/agent/timeline/stream": {
++ "get": {
++ "operationId": "get_api_v1_agent_timeline_stream",
++ "summary": "Read one person's agent timeline from OpenVibe.Actor (design 2026-11-07): what the agent did in every mode, newest first, with a cursor and the mode and needs-you filters, as agent.timeline-list-resul",
++ "description": "**actor.timeline.read** (first-party): Read one person's agent timeline from OpenVibe.Actor (design 2026-11-07): what the agent did in every mode, newest first, with a cursor and the mode and needs-you filters, as agent.timeline-list-result@1. GET /api/v1/agent/timeline. Only the person's own entries; titles, outcomes and links only, never a prompt or a diff.",
++ "tags": [
++ "actor.timeline"
++ ],
++ "x-openvibe-capabilities": [
++ "actor.timeline.read"
++ ],
++ "x-openvibe-visibility": [
++ "first-party"
++ ],
++ "x-openvibe-quota-class": "standard",
++ "security": [
++ {
++ "openvibeToken": [
++ "actor.timeline.read"
++ ]
++ }
++ ],
++ "responses": {
++ "2XX": {
++ "description": "Success",
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/agent.timeline-list-result.v1"
++ }
++ }
++ }
++ },
++ "default": {
++ "description": "An error (RFC 9457 problem details)",
++ "content": {
++ "application/problem+json": {
++ "schema": {
++ "$ref": "#/components/schemas/errors.problem.v1"
++ }
++ }
++ }
++ }
++ }
++ }
++ },
"/api/v1/agents": {
"get": {
"operationId": "get_api_v1_agents",
@@@ -3483,6 +3575,234 @@
}
}
},
++ "agent.timeline-entry.v1": {
++ "title": "AgentTimelineEntry",
++ "description": "One entry of the agent's timeline (design 2026-11-07 §2): one step of the agent's work, in one mode, for one person. The Dock shows it: the mode's icon and word, the title, where it ran and why, the outcome, the time and the cost. Only a title, an outcome and a link: never a prompt, a diff or a page. A person sees their own entries; another person's entry is a 404. The audience is 'private' (Only me) unless the person shared the entry through the one Share sheet.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "id",
++ "subject",
++ "mode",
++ "product",
++ "title",
++ "status",
++ "started_at",
++ "audience"
++ ],
++ "properties": {
++ "id": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 80
++ },
++ "subject": {
++ "type": "string",
++ "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$",
++ "description": "The person the step was for."
++ },
++ "mode": {
++ "enum": [
++ "talk",
++ "act",
++ "run",
++ "code",
++ "browse",
++ "watch",
++ "stream"
++ ]
++ },
++ "product": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 40
++ },
++ "ref": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 120
++ },
++ "title": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 160
++ },
++ "started_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "ended_at": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "format": "date-time"
++ },
++ "status": {
++ "enum": [
++ "running",
++ "waiting",
++ "needs_you",
++ "done",
++ "failed",
++ "stopped"
++ ]
++ },
++ "placement": {
++ "type": [
++ "object",
++ "null"
++ ],
++ "additionalProperties": false,
++ "description": "Where the step ran and why the agent put it there, in one line each.",
++ "properties": {
++ "where": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 160
++ },
++ "why": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 240
++ }
++ }
++ },
++ "cost_usd": {
++ "type": [
++ "number",
++ "null"
++ ],
++ "minimum": 0
++ },
++ "link": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "pattern": "^https://",
++ "maxLength": 2048
++ },
++ "reason": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 240
++ },
++ "transition": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 240
++ },
++ "approval": {
++ "type": [
++ "object",
++ "null"
++ ],
++ "additionalProperties": false,
++ "description": "The approval this step waits on, and the mode that owns it. The person answers it in the mode.",
++ "properties": {
++ "product": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 40
++ },
++ "id": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 80
++ },
++ "kind": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 40
++ }
++ }
++ },
++ "audience": {
++ "enum": [
++ "private",
++ "link",
++ "people",
++ "public"
++ ],
++ "description": "Who may see it. 'private' is Only me, the default; the other three come from the one Share sheet."
++ },
++ "shared": {
++ "type": [
++ "boolean",
++ "null"
++ ],
++ "description": "Whether the person shared this entry (the share row itself lives in the sharing system)."
++ }
++ }
++ },
++ "agent.timeline-list-result.v1": {
++ "title": "AgentTimelineListResult",
++ "description": "The person's agent timeline (design 2026-11-07 §1): what the agent is doing now, what needs them, and the entries themselves, newest first. The Dock's filters live in the query (cursor, mode, needs_you); counts say how many entries a hidden filter would show, so a filter never hides without a count.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "now",
++ "needs_you",
++ "entries",
++ "next_cursor",
++ "counts"
++ ],
++ "properties": {
++ "now": {
++ "anyOf": [
++ {
++ "$ref": "#/components/schemas/agent.timeline-entry.v1"
++ },
++ {
++ "type": "null"
++ }
++ ],
++ "description": "The step the agent is doing this moment, if any."
++ },
++ "needs_you": {
++ "type": "array",
++ "maxItems": 50,
++ "items": {
++ "$ref": "#/components/schemas/agent.timeline-entry.v1"
++ },
++ "description": "Every approval or question from any mode, oldest first."
++ },
++ "entries": {
++ "type": "array",
++ "maxItems": 200,
++ "items": {
++ "$ref": "#/components/schemas/agent.timeline-entry.v1"
++ }
++ },
++ "next_cursor": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 200,
++ "description": "The cursor of the next page, or null at the end."
++ },
++ "counts": {
++ "type": "object",
++ "additionalProperties": {
++ "type": "integer",
++ "minimum": 0
++ },
++ "description": "How many entries each mode has (and \"needs_you\"), so the Dock can show what a filter would hide."
++ }
++ }
++ },
"common.action-item.v1": {
"title": "ActionItem",
"description": "One piece of a person's agent work in the Action Center (plan 2026-10-28 §3.10): an agent task, a coding task, an AI run, or an approval waiting on them. Each authority answers its own items in this shape (common.action-list-result@1); OpenVibe.Network merges them into buckets (network.me-actions-result@1). Text is plain (no markup); a cost is what the person was charged in USD, null when unknown or free; href is a page on the authority's own public site.",
ddiff --git a/generated/openapi/ai.json b/generated/openapi/ai.json
iindex fda6584b..151b92dd 100644
---- a/generated/openapi/ai.json
++++ b/generated/openapi/ai.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.AI API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/bench.json b/generated/openapi/bench.json
iindex 437f7c9a..cf60e71b 100644
---- a/generated/openapi/bench.json
++++ b/generated/openapi/bench.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Bench API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Bench as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Bench as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/billing.json b/generated/openapi/billing.json
iindex 7884b9ad..c4a514df 100644
---- a/generated/openapi/billing.json
++++ b/generated/openapi/billing.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Billing API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/blog.json b/generated/openapi/blog.json
iindex 8c9ce7d3..9c3f1d15 100644
---- a/generated/openapi/blog.json
++++ b/generated/openapi/blog.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Blog API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/bot.json b/generated/openapi/bot.json
iindex 928edcbc..cab03e13 100644
---- a/generated/openapi/bot.json
++++ b/generated/openapi/bot.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Bot API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/chat.json b/generated/openapi/chat.json
iindex f49539e9..5dfd639e 100644
---- a/generated/openapi/chat.json
++++ b/generated/openapi/chat.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Chat API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/codes.json b/generated/openapi/codes.json
iindex 5c8570f3..1f2eb1be 100644
---- a/generated/openapi/codes.json
++++ b/generated/openapi/codes.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Codes API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/community.json b/generated/openapi/community.json
iindex 8c0064cb..38b5c4aa 100644
---- a/generated/openapi/community.json
++++ b/generated/openapi/community.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Community API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/connect.json b/generated/openapi/connect.json
iindex f85b24f3..89b4dd16 100644
---- a/generated/openapi/connect.json
++++ b/generated/openapi/connect.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe Connect API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe Connect as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe Connect as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/coupons.json b/generated/openapi/coupons.json
iindex 099976b2..326a106c 100644
---- a/generated/openapi/coupons.json
++++ b/generated/openapi/coupons.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Coupons API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/deals.json b/generated/openapi/deals.json
iindex edb19b21..58d0d2a8 100644
---- a/generated/openapi/deals.json
++++ b/generated/openapi/deals.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Deals API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/design.json b/generated/openapi/design.json
iindex 1cb2c957..d32d7d18 100644
---- a/generated/openapi/design.json
++++ b/generated/openapi/design.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Design API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Design as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Design as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/domains.json b/generated/openapi/domains.json
iindex 3ab3a599..2727ec1d 100644
---- a/generated/openapi/domains.json
++++ b/generated/openapi/domains.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Domains API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Domains as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Domains as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/events.json b/generated/openapi/events.json
iindex 7d416cea..2e1a164b 100644
---- a/generated/openapi/events.json
++++ b/generated/openapi/events.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Events API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/food.json b/generated/openapi/food.json
iindex d01defb2..c8a0addc 100644
---- a/generated/openapi/food.json
++++ b/generated/openapi/food.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Food API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/games.json b/generated/openapi/games.json
iindex a7edabfa..a15f405f 100644
---- a/generated/openapi/games.json
++++ b/generated/openapi/games.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Games API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/host.json b/generated/openapi/host.json
iindex f59ac00e..7242730b 100644
---- a/generated/openapi/host.json
++++ b/generated/openapi/host.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Host API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/index.json b/generated/openapi/index.json
iindex 2e388b3e..a68ec2ef 100644
---- a/generated/openapi/index.json
++++ b/generated/openapi/index.json
@@@ -5,8 +5,8 @@
"service": "actor",
"name": "OpenVibe.Actor",
"origin": "https://openvibe.actor",
-- "operations": 37,
-- "capabilities": 13
++ "operations": 39,
++ "capabilities": 14
},
{
"service": "ai",
ddiff --git a/generated/openapi/inventory.json b/generated/openapi/inventory.json
iindex 156af2a4..5df57f23 100644
---- a/generated/openapi/inventory.json
++++ b/generated/openapi/inventory.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Inventory API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/live.json b/generated/openapi/live.json
iindex 7fa79c85..bc68ce0a 100644
---- a/generated/openapi/live.json
++++ b/generated/openapi/live.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Live API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/media-hub.json b/generated/openapi/media-hub.json
iindex 92682e0a..1a95dd83 100644
---- a/generated/openapi/media-hub.json
++++ b/generated/openapi/media-hub.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.MediaHub API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.MediaHub as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.MediaHub as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/media.json b/generated/openapi/media.json
iindex ba97b65c..bcf8b048 100644
---- a/generated/openapi/media.json
++++ b/generated/openapi/media.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Media API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/network.json b/generated/openapi/network.json
iindex 0b36c033..4f42a579 100644
---- a/generated/openapi/network.json
++++ b/generated/openapi/network.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Network API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/news.json b/generated/openapi/news.json
iindex db9513c6..b37c9450 100644
---- a/generated/openapi/news.json
++++ b/generated/openapi/news.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.News API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/openre.json b/generated/openapi/openre.json
iindex a6dcd7f7..52a7e515 100644
---- a/generated/openapi/openre.json
++++ b/generated/openapi/openre.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenRestream API",
-- "version": "0.315.0",
-- "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/play.json b/generated/openapi/play.json
iindex c562a034..b515ee97 100644
---- a/generated/openapi/play.json
++++ b/generated/openapi/play.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Play API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Play as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Play as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/quest.json b/generated/openapi/quest.json
iindex ebd28aca..312b7bcf 100644
---- a/generated/openapi/quest.json
++++ b/generated/openapi/quest.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Quest API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Quest as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Quest as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/report.json b/generated/openapi/report.json
iindex 59c320ec..dd0301be 100644
---- a/generated/openapi/report.json
++++ b/generated/openapi/report.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Report API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Report as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Report as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/reviews.json b/generated/openapi/reviews.json
iindex 4274f21d..376295ef 100644
---- a/generated/openapi/reviews.json
++++ b/generated/openapi/reviews.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Reviews API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/run.json b/generated/openapi/run.json
iindex 8003bfc9..d50ee8cc 100644
---- a/generated/openapi/run.json
++++ b/generated/openapi/run.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Run API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/search.json b/generated/openapi/search.json
iindex 374a3f81..0302ed9e 100644
---- a/generated/openapi/search.json
++++ b/generated/openapi/search.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Search API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/services.json b/generated/openapi/services.json
iindex 74003cca..cffc4f94 100644
---- a/generated/openapi/services.json
++++ b/generated/openapi/services.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Services API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/sources.json b/generated/openapi/sources.json
iindex dd36973a..94114f0c 100644
---- a/generated/openapi/sources.json
++++ b/generated/openapi/sources.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Sources API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/space.json b/generated/openapi/space.json
iindex 7a829e80..5501efbe 100644
---- a/generated/openapi/space.json
++++ b/generated/openapi/space.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Space API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Space as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Space as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/tips.json b/generated/openapi/tips.json
iindex ee56cd34..2bae1f02 100644
---- a/generated/openapi/tips.json
++++ b/generated/openapi/tips.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Tips API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/today.json b/generated/openapi/today.json
iindex 81dd6903..49226982 100644
---- a/generated/openapi/today.json
++++ b/generated/openapi/today.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Today API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Today as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Today as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/tools.json b/generated/openapi/tools.json
iindex 501942ec..766affa1 100644
---- a/generated/openapi/tools.json
++++ b/generated/openapi/tools.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Tools API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/trade.json b/generated/openapi/trade.json
iindex 01ab5153..b6600941 100644
---- a/generated/openapi/trade.json
++++ b/generated/openapi/trade.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Trade API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/vip.json b/generated/openapi/vip.json
iindex 0017c8b5..6c9a9eb2 100644
---- a/generated/openapi/vip.json
++++ b/generated/openapi/vip.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.VIP API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/vision.json b/generated/openapi/vision.json
iindex 8ae12b2c..6eeab524 100644
---- a/generated/openapi/vision.json
++++ b/generated/openapi/vision.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Vision API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Vision as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Vision as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/watch.json b/generated/openapi/watch.json
iindex c758083e..84ef66d1 100644
---- a/generated/openapi/watch.json
++++ b/generated/openapi/watch.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Watch API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/wiki.json b/generated/openapi/wiki.json
iindex b9c32dc0..5548c19a 100644
---- a/generated/openapi/wiki.json
++++ b/generated/openapi/wiki.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Wiki API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/work.json b/generated/openapi/work.json
iindex 51e479ea..a2c298a9 100644
---- a/generated/openapi/work.json
++++ b/generated/openapi/work.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Work API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Work as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Work as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/zone.json b/generated/openapi/zone.json
iindex b9c1658a..60213355 100644
---- a/generated/openapi/zone.json
++++ b/generated/openapi/zone.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Zone API",
-- "version": "0.315.0",
-- "description": "Routes of OpenVibe.Zone as the OpenVibe contracts describe them (openvibe-contracts 0.315.0): each operation lists the capabilities it performs; a token for 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.316.0",
++ "description": "Routes of OpenVibe.Zone as the OpenVibe contracts describe them (openvibe-contracts 0.316.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/typescript/index.d.ts b/generated/typescript/index.d.ts
iindex 896462b1..baaaf461 100644
---- a/generated/typescript/index.d.ts
++++ b/generated/typescript/index.d.ts
@@@ -298021,3 +298021,312 @@ export interface AiOffer {
};
pool?: AiOfferPool;
}
++
++/** [email protected] (owner: contracts) */
++/**
++ * One step of the agent's work, as any mode publishes it (agent.step.started, agent.step.updated, agent.step.ended; design 2026-11-07 §2). The person it is for is the envelope's subject. The payload is the step's shape: what it is, where it ran, why, how it ended, what it cost, and where to see it. It never carries the step's content: no prompt, no diff, no page, no message, no file. The three events share this payload; what differs is the envelope's event_type. The agent.* namespace belongs to the network, so any first-party mode may publish into it (like provider.*); OpenVibe.Actor registers the family and keeps the timeline.
++ */
++export interface AgentStepPayload {
++ /**
++ * The mode's own id for this step (a Codes task id, a Run job id, a stream id).
++ */
++ step_id: string;
++ /**
++ * The mode the step belongs to.
++ */
++ mode: "talk" | "act" | "run" | "code" | "browse" | "watch" | "stream";
++ /**
++ * The product that ran it (chat, codes, run, watch, live, surf, actor).
++ */
++ product: string;
++ /**
++ * The product's own id for the thing this step is about.
++ */
++ ref?: string | null;
++ /**
++ * A short plain-text name for the step. What it was, never what it said.
++ */
++ title: string;
++ status: "running" | "waiting" | "needs_you" | "done" | "failed" | "stopped";
++ started_at: string;
++ ended_at?: string | null;
++ /**
++ * Where the step ran and why the agent put it there, in one line each.
++ */
++ placement?: {
++ where?: string | null;
++ why?: string | null;
++ } | null;
++ cost_usd?: number | null;
++ /**
++ * The step's own page in its product.
++ */
++ link?: string | null;
++ /**
++ * Why it failed or stopped, in one line a person can act on.
++ */
++ reason?: string | null;
++ /**
++ * The agent's sentence for the mode change this step announced.
++ */
++ transition?: string | null;
++ /**
++ * The approval this step waits on, and the mode that owns it. The person answers it in the mode.
++ */
++ approval?: {
++ product?: string;
++ id?: string;
++ kind?: string;
++ } | null;
++}
++
++/** [email protected] (owner: actor) */
++/**
++ * agent.step.started v1 (design 2026-11-07 §2). A step began: the mode started working on it. Envelope: source the mode that runs it (a first-party service), subject the person it is for, visibility internal, actor the person or the mode. The payload is common.agent-step@1: titles, outcomes and links only, never a prompt or a diff.
++ */
++export interface AgentStepStartedPayload {
++ /**
++ * The mode's own id for this step (a Codes task id, a Run job id, a stream id).
++ */
++ step_id: string;
++ /**
++ * The mode the step belongs to.
++ */
++ mode: "talk" | "act" | "run" | "code" | "browse" | "watch" | "stream";
++ /**
++ * The product that ran it (chat, codes, run, watch, live, surf, actor).
++ */
++ product: string;
++ /**
++ * The product's own id for the thing this step is about.
++ */
++ ref?: string | null;
++ /**
++ * A short plain-text name for the step. What it was, never what it said.
++ */
++ title: string;
++ status: "running" | "waiting" | "needs_you" | "done" | "failed" | "stopped";
++ started_at: string;
++ ended_at?: string | null;
++ /**
++ * Where the step ran and why the agent put it there, in one line each.
++ */
++ placement?: {
++ where?: string | null;
++ why?: string | null;
++ } | null;
++ cost_usd?: number | null;
++ /**
++ * The step's own page in its product.
++ */
++ link?: string | null;
++ /**
++ * Why it failed or stopped, in one line a person can act on.
++ */
++ reason?: string | null;
++ /**
++ * The agent's sentence for the mode change this step announced.
++ */
++ transition?: string | null;
++ /**
++ * The approval this step waits on, and the mode that owns it. The person answers it in the mode.
++ */
++ approval?: {
++ product?: string;
++ id?: string;
++ kind?: string;
++ } | null;
++}
++
++/** [email protected] (owner: actor) */
++/**
++ * agent.step.updated v1 (design 2026-11-07 §2). A step changed: it is waiting, it needs the person, or it moved on. The same payload as agent.step.started; the envelope says what changed. The payload is common.agent-step@1: titles, outcomes and links only, never a prompt or a diff.
++ */
++export interface AgentStepUpdatedPayload {
++ /**
++ * The mode's own id for this step (a Codes task id, a Run job id, a stream id).
++ */
++ step_id: string;
++ /**
++ * The mode the step belongs to.
++ */
++ mode: "talk" | "act" | "run" | "code" | "browse" | "watch" | "stream";
++ /**
++ * The product that ran it (chat, codes, run, watch, live, surf, actor).
++ */
++ product: string;
++ /**
++ * The product's own id for the thing this step is about.
++ */
++ ref?: string | null;
++ /**
++ * A short plain-text name for the step. What it was, never what it said.
++ */
++ title: string;
++ status: "running" | "waiting" | "needs_you" | "done" | "failed" | "stopped";
++ started_at: string;
++ ended_at?: string | null;
++ /**
++ * Where the step ran and why the agent put it there, in one line each.
++ */
++ placement?: {
++ where?: string | null;
++ why?: string | null;
++ } | null;
++ cost_usd?: number | null;
++ /**
++ * The step's own page in its product.
++ */
++ link?: string | null;
++ /**
++ * Why it failed or stopped, in one line a person can act on.
++ */
++ reason?: string | null;
++ /**
++ * The agent's sentence for the mode change this step announced.
++ */
++ transition?: string | null;
++ /**
++ * The approval this step waits on, and the mode that owns it. The person answers it in the mode.
++ */
++ approval?: {
++ product?: string;
++ id?: string;
++ kind?: string;
++ } | null;
++}
++
++/** [email protected] (owner: actor) */
++/**
++ * agent.step.ended v1 (design 2026-11-07 §2). A step ended: it is done, it failed, or the person stopped it. Envelope: source the mode that ran it, subject the person it is for, visibility internal. The payload is common.agent-step@1: titles, outcomes and links only, never a prompt or a diff.
++ */
++export interface AgentStepEndedPayload {
++ /**
++ * The mode's own id for this step (a Codes task id, a Run job id, a stream id).
++ */
++ step_id: string;
++ /**
++ * The mode the step belongs to.
++ */
++ mode: "talk" | "act" | "run" | "code" | "browse" | "watch" | "stream";
++ /**
++ * The product that ran it (chat, codes, run, watch, live, surf, actor).
++ */
++ product: string;
++ /**
++ * The product's own id for the thing this step is about.
++ */
++ ref?: string | null;
++ /**
++ * A short plain-text name for the step. What it was, never what it said.
++ */
++ title: string;
++ status: "running" | "waiting" | "needs_you" | "done" | "failed" | "stopped";
++ started_at: string;
++ ended_at?: string | null;
++ /**
++ * Where the step ran and why the agent put it there, in one line each.
++ */
++ placement?: {
++ where?: string | null;
++ why?: string | null;
++ } | null;
++ cost_usd?: number | null;
++ /**
++ * The step's own page in its product.
++ */
++ link?: string | null;
++ /**
++ * Why it failed or stopped, in one line a person can act on.
++ */
++ reason?: string | null;
++ /**
++ * The agent's sentence for the mode change this step announced.
++ */
++ transition?: string | null;
++ /**
++ * The approval this step waits on, and the mode that owns it. The person answers it in the mode.
++ */
++ approval?: {
++ product?: string;
++ id?: string;
++ kind?: string;
++ } | null;
++}
++
++/** [email protected] (owner: actor) */
++/**
++ * One entry of the agent's timeline (design 2026-11-07 §2): one step of the agent's work, in one mode, for one person. The Dock shows it: the mode's icon and word, the title, where it ran and why, the outcome, the time and the cost. Only a title, an outcome and a link: never a prompt, a diff or a page. A person sees their own entries; another person's entry is a 404. The audience is 'private' (Only me) unless the person shared the entry through the one Share sheet.
++ */
++export interface AgentTimelineEntry {
++ id: string;
++ /**
++ * The person the step was for.
++ */
++ subject: string;
++ mode: "talk" | "act" | "run" | "code" | "browse" | "watch" | "stream";
++ product: string;
++ ref?: string | null;
++ title: string;
++ started_at: string;
++ ended_at?: string | null;
++ status: "running" | "waiting" | "needs_you" | "done" | "failed" | "stopped";
++ /**
++ * Where the step ran and why the agent put it there, in one line each.
++ */
++ placement?: {
++ where?: string | null;
++ why?: string | null;
++ } | null;
++ cost_usd?: number | null;
++ link?: string | null;
++ reason?: string | null;
++ transition?: string | null;
++ /**
++ * The approval this step waits on, and the mode that owns it. The person answers it in the mode.
++ */
++ approval?: {
++ product?: string;
++ id?: string;
++ kind?: string;
++ } | null;
++ /**
++ * Who may see it. 'private' is Only me, the default; the other three come from the one Share sheet.
++ */
++ audience: "private" | "link" | "people" | "public";
++ /**
++ * Whether the person shared this entry (the share row itself lives in the sharing system).
++ */
++ shared?: boolean | null;
++}
++
++/** [email protected] (owner: actor) */
++/**
++ * The person's agent timeline (design 2026-11-07 §1): what the agent is doing now, what needs them, and the entries themselves, newest first. The Dock's filters live in the query (cursor, mode, needs_you); counts say how many entries a hidden filter would show, so a filter never hides without a count.
++ */
++export interface AgentTimelineListResult {
++ /**
++ * The step the agent is doing this moment, if any.
++ */
++ now: AgentTimelineEntry | null;
++ /**
++ * Every approval or question from any mode, oldest first.
++ *
++ * @maxItems 50
++ */
++ needs_you: AgentTimelineEntry[];
++ /**
++ * @maxItems 200
++ */
++ entries: AgentTimelineEntry[];
++ /**
++ * The cursor of the next page, or null at the end.
++ */
++ next_cursor: string | null;
++ /**
++ * How many entries each mode has (and "needs_you"), so the Dock can show what a filter would hide.
++ */
++ counts: {
++ [k: string]: number | undefined;
++ };
++}
ddiff --git a/manifests/capabilities/actor.timeline.read.json b/manifests/capabilities/actor.timeline.read.json
nnew file mode 100644
iindex 00000000..de0fcdfc
---- /dev/null
++++ b/manifests/capabilities/actor.timeline.read.json
@@@ -0,0 +1,22 @@
++{
++ "id": "actor.timeline.read",
++ "version": "1.0",
++ "owner": "actor",
++ "status": "active",
++ "visibility": "first-party",
++ "description": "Read one person's agent timeline from OpenVibe.Actor (design 2026-11-07): what the agent did in every mode, newest first, with a cursor and the mode and needs-you filters, as agent.timeline-list-result@1. GET /api/v1/agent/timeline. Only the person's own entries; titles, outcomes and links only, never a prompt or a diff.",
++ "permissions": [
++ "actor:read"
++ ],
++ "resourceConstraints": [
++ "none"
++ ],
++ "quotaClass": "standard",
++ "events": [],
++ "implementedBy": [
++ "GET /api/v1/agent/timeline",
++ "GET /api/v1/agent/timeline/stream"
++ ],
++ "inputSchema": "common.no-body@1",
++ "outputSchema": "agent.timeline-list-result@1"
++}
ddiff --git a/manifests/services/actor.json b/manifests/services/actor.json
iindex 181ac43b..d9452494 100644
---- a/manifests/services/actor.json
++++ b/manifests/services/actor.json
@@@ -28,13 +28,21 @@
"actor.approval.decide",
"actor.model.manage",
"actor.a2a.task",
-- "actor.config.manage"
++ "actor.config.manage",
++ "actor.timeline.read"
++ ],
++ "eventsProduced": [
++ "agent.step.started",
++ "agent.step.updated",
++ "agent.step.ended"
],
-- "eventsProduced": [],
"eventsConsumed": [
"network.account.export_requested",
"network.account.deleted",
-- "chat.message.created"
++ "chat.message.created",
++ "agent.step.started",
++ "agent.step.updated",
++ "agent.step.ended"
],
"namespacesOwned": [
"actor.*"
@@@ -83,7 +91,7 @@
"none": "no claims: a task runs in the process that accepted it"
}
},
-- "notes": "Port 4950, unit openvibe-actor.service. OpenVibe's own general agent and the router for agent work (plan T17, ADR-044): POST /api/v1/tasks takes a task in plain words, a mode and a budget; the planner (openvibe-sdk/placement) picks an agent system, runs it, has a second model family check the result and answers with the result, the cost and the explanation (platform.task@1). Agent systems: the OpenVibe runtime (a tool-using model that acts through OpenVibe services: Search, Tools), other platforms' agents (OpenAI's Responses agent with web search) and an open model on OpenVibe's own hardware for private mode; coding work goes to OpenVibe.Codes. Consumes OpenVibe.Network (SSO with PKCE S256 as OAuth client actor, JWKS for app and person tokens), OpenVibe.Search (public reads) and OpenVibe.Tools (tools.tool.run). Owns its tasks and their event logs; model provider keys are the operator's (BYO keys through OpenVibe.AI come next). Ask Actor from chat (plan T17 reach): a signed-in person's \"@actor <task>\" in OpenVibe's global chat or their own channel (chat.message.created) becomes their task with public tools only (never their computers, robots or code), and the answer is posted back in the room through OpenVibe.Chat's service API (chat.message.send).",
++ "notes": "Port 4950, unit openvibe-actor.service. OpenVibe's own general agent and the router for agent work (plan T17, ADR-044): POST /api/v1/tasks takes a task in plain words, a mode and a budget; the planner (openvibe-sdk/placement) picks an agent system, runs it, has a second model family check the result and answers with the result, the cost and the explanation (platform.task@1). Agent systems: the OpenVibe runtime (a tool-using model that acts through OpenVibe services: Search, Tools), other platforms' agents (OpenAI's Responses agent with web search) and an open model on OpenVibe's own hardware for private mode; coding work goes to OpenVibe.Codes. Consumes OpenVibe.Network (SSO with PKCE S256 as OAuth client actor, JWKS for app and person tokens), OpenVibe.Search (public reads) and OpenVibe.Tools (tools.tool.run). Owns its tasks and their event logs; model provider keys are the operator's (BYO keys through OpenVibe.AI come next). Ask Actor from chat (plan T17 reach): a signed-in person's \"@actor <task>\" in OpenVibe's global chat or their own channel (chat.message.created) becomes their task with public tools only (never their computers, robots or code), and the answer is posted back in the room through OpenVibe.Chat's service API (chat.message.send). The agent.* namespace is the network's, like provider.*: any first-party mode (Chat, Codes, Run, Watch, Live, Surf) publishes agent.step.started|updated|ended into it with the person's subject, and Actor keeps the one timeline behind the Dock (GET /api/v1/agent/timeline). Actor registers the family here (one producer per event type) and consumes what the modes publish.",
"health": "/api/health",
"ready": "/api/ready",
"internalOrigin": "http://127.0.0.1:4950",
ddiff --git a/package.json b/package.json
iindex 8d95982a..5189f3cc 100644
---- a/package.json
++++ b/package.json
@@@ -1,6 +1,6 @@
{
"name": "openvibe-contracts",
-- "version": "0.315.0",
++ "version": "0.316.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",
ddiff --git a/test/changelog-history.test.js b/test/changelog-history.test.js
iindex 4c913b3a..a729b1a4 100644
---- a/test/changelog-history.test.js
++++ b/test/changelog-history.test.js
@@@ -14,8 +14,9 @@ const [major, minor] = pkg.version.split('.').map(Number);
// Minor versions that were never released (no tag), so they have no entry. 306 and 307 were reserved for the pooled
// machines and consent branches, which merged after Memory M5 took 308: they became 0.309.0 and 0.310.0, and the two
--// numbers stay unused (a tag below the newest one would read as a downgrade to the pin bot).
--const NEVER_RELEASED = new Set([293, 306, 307]);
++// numbers stay unused (a tag below the newest one would read as a downgrade to the pin bot). 313 was claimed by A6's
++// Contracts PR while main moved to 0.314.0 and 0.315.0; it merged as 0.316.0 and the number stays unused.
++const NEVER_RELEASED = new Set([293, 306, 307, 313]);
const FIRST_MINOR = 30;
assert.strictEqual(major, 0, 'the check counts 0.x minors; update it when 1.0.0 ships');