openvibers/openvibe.contracts Commits

0.252.0: ai.memory.read and ai.memory.write, the Memory M2 contracts (#260)

OP OpenVibers committed 14 days ago · 83f8f35374 · 59 files, +2003 −88

Changes

ddiff --git a/CHANGELOG.md b/CHANGELOG.md
iindex 0d803049..5207d524 100644
---- a/CHANGELOG.md
++++ b/CHANGELOG.md
@@@ -1,5 +1,17 @@
# Changelog
++## 0.252.0 — 2026-10-30
++
++- **Memory M2 capabilities and contracts** (OpenVibe.AI; plan `OpenVibe_Memory_Plan_2026-10-30.md`, spec
++ `research-2026-10-30/memory-m2-spec.md`).
++ - New active first-party capabilities `ai.memory.read` and `ai.memory.write`, owned by `ai`: the person's own API
++ reads and writes, and a service acting `on_behalf_of` a person with the capability (agent search is at most 8
++ active items in the scopes its grant names, audited in `memory_reads` with ids only, never text).
++ - Three additive v1 contracts: `ai.memory-item@1` (one decrypted item as its owner reads it), `ai.memory-result@1`
++ (the list, item, profile, deletion count and agent search answers) and `ai.memory-write-request@1` (the batch
++ import, the patch and the source deletion). The sealed fields (`text_enc`, `text_mac`, `source_ref_enc`) are never
++ in a response, and the text is never logged.
++
All notable changes to `openvibe-contracts`. Releases are git tags (`vX.Y.Z`) that consumers install
from `https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/<tag>`. Before v0.30.0,
the notes were in the tag and commit messages (`git tag -n1`).
ddiff --git a/contracts/ai/memory-item.v1.json b/contracts/ai/memory-item.v1.json
nnew file mode 100644
iindex 00000000..e37fc648
---- /dev/null
++++ b/contracts/ai/memory-item.v1.json
@@@ -0,0 +1,112 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/ai/memory-item.v1.json",
++ "title": "AiMemoryItem",
++ "description": "ai.memory-item@1 (OpenVibe.AI; Memory M2): one memory item as the person's own API reads it. Tenant is the owner (`user:usr_…`); the text is decrypted only inside AI's process and never logged, never in an error, a span or an event. `source_ref` is the file path relative to the scanned root and the heading, when the item came from a file.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "id",
++ "owner",
++ "scope",
++ "kind",
++ "text",
++ "source",
++ "status",
++ "confidence",
++ "created_at",
++ "updated_at"
++ ],
++ "properties": {
++ "id": {
++ "type": "string",
++ "pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "owner": {
++ "type": "string",
++ "pattern": "^user:usr_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "scope": {
++ "type": "string",
++ "pattern": "^(user|project:[a-z0-9][a-z0-9._-]{0,63})$",
++ "description": "`user` for the person's own notes, or `project:<slug>` for a repo or folder they chose. Never an absolute path."
++ },
++ "kind": {
++ "enum": [
++ "preference",
++ "fact",
++ "project_rule",
++ "procedure",
++ "decision",
++ "lesson"
++ ]
++ },
++ "text": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 8000,
++ "description": "The item text after the server-side redaction. Only the person's own routes and a granted agent search see it."
++ },
++ "source": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 100,
++ "description": "The adapter id (claude-code, cursor, …) or the service (actor, vibe, know, person)."
++ },
++ "source_ref": {
++ "type": [
++ "object",
++ "null"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "path": {
++ "type": "string",
++ "maxLength": 500
++ },
++ "heading": {
++ "type": "string",
++ "maxLength": 300
++ }
++ },
++ "description": "The path relative to the scanned root and the heading, when the item came from a file."
++ },
++ "status": {
++ "enum": [
++ "active",
++ "suggested",
++ "archived",
++ "conflict"
++ ]
++ },
++ "confidence": {
++ "type": "number",
++ "minimum": 0,
++ "maximum": 1
++ },
++ "seen_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "created_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "updated_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "machine": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 100,
++ "description": "The Node machine id it came from, when it came from one."
++ },
++ "no_looks": {
++ "type": "boolean",
++ "description": "True when the item was produced by an AI: the server ran noLooks on it (Memory M2 rule 5)."
++ }
++ }
++}
ddiff --git a/contracts/ai/memory-result.v1.json b/contracts/ai/memory-result.v1.json
nnew file mode 100644
iindex 00000000..0aed1ff1
---- /dev/null
++++ b/contracts/ai/memory-result.v1.json
@@@ -0,0 +1,58 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/ai/memory-result.v1.json",
++ "title": "AiMemoryResult",
++ "description": "ai.memory-result@1 (OpenVibe.AI; Memory M2): what the memory API answers: a list of items (GET /items, the batch import), one item (GET or PATCH /items/{id}), the cached profile (GET /profile), a count of deleted rows (DELETE) or the agent search's items (GET /search, at most 8, active only). The text is the person's own and is never logged.",
++ "type": "object",
++ "additionalProperties": false,
++ "properties": {
++ "items": {
++ "type": "array",
++ "maxItems": 200,
++ "items": {
++ "$ref": "memory-item.v1.json"
++ }
++ },
++ "item": {
++ "$ref": "memory-item.v1.json"
++ },
++ "profile": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "scope",
++ "text",
++ "items_hash",
++ "built_at"
++ ],
++ "properties": {
++ "scope": {
++ "type": "string",
++ "pattern": "^(user|project:[a-z0-9][a-z0-9._-]{0,63})$"
++ },
++ "text": {
++ "type": "string",
++ "maxLength": 4000,
++ "description": "The cached summary of the person's own notes for this scope. It passed noLooks before it was stored."
++ },
++ "items_hash": {
++ "type": "string",
++ "pattern": "^[0-9a-f]{64}$",
++ "description": "sha256 of the sorted item MACs the profile was built from."
++ },
++ "built_at": {
++ "type": "string",
++ "format": "date-time"
++ }
++ }
++ },
++ "deleted": {
++ "type": "integer",
++ "minimum": 0
++ },
++ "count": {
++ "type": "integer",
++ "minimum": 0
++ }
++ }
++}
ddiff --git a/contracts/ai/memory-write-request.v1.json b/contracts/ai/memory-write-request.v1.json
nnew file mode 100644
iindex 00000000..334969dc
---- /dev/null
++++ b/contracts/ai/memory-write-request.v1.json
@@@ -0,0 +1,128 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/ai/memory-write-request.v1.json",
++ "title": "AiMemoryWriteRequest",
++ "description": "ai.memory-write-request@1 (OpenVibe.AI; Memory M2): the body of POST /api/v1/memory/items:batch (up to 200 items), PATCH /api/v1/memory/items/{id} (text, kind, scope or status) and DELETE /api/v1/memory/items?source= (the source to delete). Secret shapes are redacted again on the server, and an item that is only a secret is refused. AI-produced items are suggestions until the person accepts them.",
++ "type": "object",
++ "additionalProperties": false,
++ "properties": {
++ "items": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 200,
++ "items": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "text"
++ ],
++ "properties": {
++ "id": {
++ "type": "string",
++ "pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "text": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 8000
++ },
++ "kind": {
++ "enum": [
++ "preference",
++ "fact",
++ "project_rule",
++ "procedure",
++ "decision",
++ "lesson"
++ ]
++ },
++ "scope": {
++ "type": "string",
++ "pattern": "^(user|project:[a-z0-9][a-z0-9._-]{0,63})$"
++ },
++ "source": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 100
++ },
++ "source_ref": {
++ "type": [
++ "object",
++ "null"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "path": {
++ "type": "string",
++ "maxLength": 500
++ },
++ "heading": {
++ "type": "string",
++ "maxLength": 300
++ }
++ }
++ },
++ "status": {
++ "enum": [
++ "active",
++ "suggested",
++ "archived",
++ "conflict"
++ ]
++ },
++ "confidence": {
++ "type": "number",
++ "minimum": 0,
++ "maximum": 1
++ },
++ "machine": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 100
++ },
++ "no_looks": {
++ "type": "boolean"
++ },
++ "seen_at": {
++ "type": "string",
++ "format": "date-time"
++ }
++ }
++ }
++ },
++ "text": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 8000
++ },
++ "kind": {
++ "enum": [
++ "preference",
++ "fact",
++ "project_rule",
++ "procedure",
++ "decision",
++ "lesson"
++ ]
++ },
++ "scope": {
++ "type": "string",
++ "pattern": "^(user|project:[a-z0-9][a-z0-9._-]{0,63})$"
++ },
++ "status": {
++ "enum": [
++ "active",
++ "suggested",
++ "archived",
++ "conflict"
++ ]
++ },
++ "source": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 100
++ }
++ }
++}
ddiff --git a/contracts/catalog.json b/contracts/catalog.json
iindex f1b94fc4..26ec5459 100644
---- a/contracts/catalog.json
++++ b/contracts/catalog.json
@@@ -8236,6 +8236,33 @@
"visibility": "first-party",
"compatibility": "backward",
"status": "active"
++ },
++ {
++ "id": "ai.memory-item",
++ "version": "1.0.0",
++ "owner": "ai",
++ "schema": "ai/memory-item.v1.json",
++ "visibility": "first-party",
++ "compatibility": "backward",
++ "status": "active"
++ },
++ {
++ "id": "ai.memory-result",
++ "version": "1.0.0",
++ "owner": "ai",
++ "schema": "ai/memory-result.v1.json",
++ "visibility": "first-party",
++ "compatibility": "backward",
++ "status": "active"
++ },
++ {
++ "id": "ai.memory-write-request",
++ "version": "1.0.0",
++ "owner": "ai",
++ "schema": "ai/memory-write-request.v1.json",
++ "visibility": "first-party",
++ "compatibility": "backward",
++ "status": "active"
}
]
}
ddiff --git a/fixtures/ai.memory-item/invalid/absolute-path.json b/fixtures/ai.memory-item/invalid/absolute-path.json
nnew file mode 100644
iindex 00000000..11ed64fc
---- /dev/null
++++ b/fixtures/ai.memory-item/invalid/absolute-path.json
@@@ -0,0 +1,12 @@
++{
++ "id": "mem_01JZ0000000000000000000001",
++ "owner": "user:usr_01JZ0000000000000000000AAA",
++ "scope": "/home/ada/projects/openvibe",
++ "kind": "project_rule",
++ "text": "Run the Go tests with go test ./... before a commit.",
++ "source": "claude-code",
++ "status": "active",
++ "confidence": 1,
++ "created_at": "2026-10-30T09:00:00.000Z",
++ "updated_at": "2026-10-30T09:00:00.000Z"
++}
ddiff --git a/fixtures/ai.memory-item/valid/item.json b/fixtures/ai.memory-item/valid/item.json
nnew file mode 100644
iindex 00000000..c056db79
---- /dev/null
++++ b/fixtures/ai.memory-item/valid/item.json
@@@ -0,0 +1,19 @@
++{
++ "id": "mem_01JZ0000000000000000000001",
++ "owner": "user:usr_01JZ0000000000000000000AAA",
++ "scope": "project:openvibe-node",
++ "kind": "project_rule",
++ "text": "Run the Go tests with go test ./... before a commit.",
++ "source": "claude-code",
++ "source_ref": {
++ "path": ".claude/CLAUDE.md",
++ "heading": "Testing"
++ },
++ "status": "active",
++ "confidence": 1,
++ "seen_at": "2026-10-30T09:00:00.000Z",
++ "created_at": "2026-10-30T09:00:00.000Z",
++ "updated_at": "2026-10-30T09:00:00.000Z",
++ "machine": "dev_01JZ0000000000000000000N01",
++ "no_looks": false
++}
ddiff --git a/fixtures/ai.memory-result/invalid/item-without-text.json b/fixtures/ai.memory-result/invalid/item-without-text.json
nnew file mode 100644
iindex 00000000..f8f81cb0
---- /dev/null
++++ b/fixtures/ai.memory-result/invalid/item-without-text.json
@@@ -0,0 +1,13 @@
++{
++ "item": {
++ "id": "mem_01JZ0000000000000000000001",
++ "owner": "user:usr_01JZ0000000000000000000AAA",
++ "scope": "user",
++ "kind": "preference",
++ "source": "person",
++ "status": "active",
++ "confidence": 1,
++ "created_at": "2026-10-30T09:00:00.000Z",
++ "updated_at": "2026-10-30T09:00:00.000Z"
++ }
++}
ddiff --git a/fixtures/ai.memory-result/valid/items.json b/fixtures/ai.memory-result/valid/items.json
nnew file mode 100644
iindex 00000000..c7d7b1e5
---- /dev/null
++++ b/fixtures/ai.memory-result/valid/items.json
@@@ -0,0 +1,17 @@
++{
++ "items": [
++ {
++ "id": "mem_01JZ0000000000000000000001",
++ "owner": "user:usr_01JZ0000000000000000000AAA",
++ "scope": "user",
++ "kind": "preference",
++ "text": "Prefers short answers and a code block.",
++ "source": "person",
++ "status": "active",
++ "confidence": 1,
++ "created_at": "2026-10-30T09:00:00.000Z",
++ "updated_at": "2026-10-30T09:00:00.000Z"
++ }
++ ],
++ "count": 1
++}
ddiff --git a/fixtures/ai.memory-write-request/invalid/empty-batch.json b/fixtures/ai.memory-write-request/invalid/empty-batch.json
nnew file mode 100644
iindex 00000000..2feb2101
---- /dev/null
++++ b/fixtures/ai.memory-write-request/invalid/empty-batch.json
@@@ -0,0 +1,3 @@
++{
++ "items": []
++}
ddiff --git a/fixtures/ai.memory-write-request/valid/batch.json b/fixtures/ai.memory-write-request/valid/batch.json
nnew file mode 100644
iindex 00000000..fe80c38c
---- /dev/null
++++ b/fixtures/ai.memory-write-request/valid/batch.json
@@@ -0,0 +1,15 @@
++{
++ "items": [
++ {
++ "text": "Use the repo's formatter before a commit.",
++ "kind": "procedure",
++ "scope": "project:openvibe-node",
++ "source": "claude-code",
++ "source_ref": {
++ "path": ".claude/CLAUDE.md",
++ "heading": "Style"
++ },
++ "confidence": 1
++ }
++ ]
++}
ddiff --git a/generated/json-schema/bundle.json b/generated/json-schema/bundle.json
iindex 5f5378c0..923dda9a 100644
---- a/generated/json-schema/bundle.json
++++ b/generated/json-schema/bundle.json
@@@ -92431,6 +92431,319 @@
}
}
}
++ },
++ "ai.memory-item": {
++ "version": "1.0.0",
++ "owner": "ai",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/ai/memory-item.v1.json",
++ "title": "AiMemoryItem",
++ "description": "ai.memory-item@1 (OpenVibe.AI; Memory M2): one memory item as the person's own API reads it. Tenant is the owner (`user:usr_…`); the text is decrypted only inside AI's process and never logged, never in an error, a span or an event. `source_ref` is the file path relative to the scanned root and the heading, when the item came from a file.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "id",
++ "owner",
++ "scope",
++ "kind",
++ "text",
++ "source",
++ "status",
++ "confidence",
++ "created_at",
++ "updated_at"
++ ],
++ "properties": {
++ "id": {
++ "type": "string",
++ "pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "owner": {
++ "type": "string",
++ "pattern": "^user:usr_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "scope": {
++ "type": "string",
++ "pattern": "^(user|project:[a-z0-9][a-z0-9._-]{0,63})$",
++ "description": "`user` for the person's own notes, or `project:<slug>` for a repo or folder they chose. Never an absolute path."
++ },
++ "kind": {
++ "enum": [
++ "preference",
++ "fact",
++ "project_rule",
++ "procedure",
++ "decision",
++ "lesson"
++ ]
++ },
++ "text": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 8000,
++ "description": "The item text after the server-side redaction. Only the person's own routes and a granted agent search see it."
++ },
++ "source": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 100,
++ "description": "The adapter id (claude-code, cursor, …) or the service (actor, vibe, know, person)."
++ },
++ "source_ref": {
++ "type": [
++ "object",
++ "null"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "path": {
++ "type": "string",
++ "maxLength": 500
++ },
++ "heading": {
++ "type": "string",
++ "maxLength": 300
++ }
++ },
++ "description": "The path relative to the scanned root and the heading, when the item came from a file."
++ },
++ "status": {
++ "enum": [
++ "active",
++ "suggested",
++ "archived",
++ "conflict"
++ ]
++ },
++ "confidence": {
++ "type": "number",
++ "minimum": 0,
++ "maximum": 1
++ },
++ "seen_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "created_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "updated_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "machine": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 100,
++ "description": "The Node machine id it came from, when it came from one."
++ },
++ "no_looks": {
++ "type": "boolean",
++ "description": "True when the item was produced by an AI: the server ran noLooks on it (Memory M2 rule 5)."
++ }
++ }
++ }
++ },
++ "ai.memory-result": {
++ "version": "1.0.0",
++ "owner": "ai",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/ai/memory-result.v1.json",
++ "title": "AiMemoryResult",
++ "description": "ai.memory-result@1 (OpenVibe.AI; Memory M2): what the memory API answers: a list of items (GET /items, the batch import), one item (GET or PATCH /items/{id}), the cached profile (GET /profile), a count of deleted rows (DELETE) or the agent search's items (GET /search, at most 8, active only). The text is the person's own and is never logged.",
++ "type": "object",
++ "additionalProperties": false,
++ "properties": {
++ "items": {
++ "type": "array",
++ "maxItems": 200,
++ "items": {
++ "$ref": "memory-item.v1.json"
++ }
++ },
++ "item": {
++ "$ref": "memory-item.v1.json"
++ },
++ "profile": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "scope",
++ "text",
++ "items_hash",
++ "built_at"
++ ],
++ "properties": {
++ "scope": {
++ "type": "string",
++ "pattern": "^(user|project:[a-z0-9][a-z0-9._-]{0,63})$"
++ },
++ "text": {
++ "type": "string",
++ "maxLength": 4000,
++ "description": "The cached summary of the person's own notes for this scope. It passed noLooks before it was stored."
++ },
++ "items_hash": {
++ "type": "string",
++ "pattern": "^[0-9a-f]{64}$",
++ "description": "sha256 of the sorted item MACs the profile was built from."
++ },
++ "built_at": {
++ "type": "string",
++ "format": "date-time"
++ }
++ }
++ },
++ "deleted": {
++ "type": "integer",
++ "minimum": 0
++ },
++ "count": {
++ "type": "integer",
++ "minimum": 0
++ }
++ }
++ }
++ },
++ "ai.memory-write-request": {
++ "version": "1.0.0",
++ "owner": "ai",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/ai/memory-write-request.v1.json",
++ "title": "AiMemoryWriteRequest",
++ "description": "ai.memory-write-request@1 (OpenVibe.AI; Memory M2): the body of POST /api/v1/memory/items:batch (up to 200 items), PATCH /api/v1/memory/items/{id} (text, kind, scope or status) and DELETE /api/v1/memory/items?source= (the source to delete). Secret shapes are redacted again on the server, and an item that is only a secret is refused. AI-produced items are suggestions until the person accepts them.",
++ "type": "object",
++ "additionalProperties": false,
++ "properties": {
++ "items": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 200,
++ "items": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "text"
++ ],
++ "properties": {
++ "id": {
++ "type": "string",
++ "pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "text": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 8000
++ },
++ "kind": {
++ "enum": [
++ "preference",
++ "fact",
++ "project_rule",
++ "procedure",
++ "decision",
++ "lesson"
++ ]
++ },
++ "scope": {
++ "type": "string",
++ "pattern": "^(user|project:[a-z0-9][a-z0-9._-]{0,63})$"
++ },
++ "source": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 100
++ },
++ "source_ref": {
++ "type": [
++ "object",
++ "null"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "path": {
++ "type": "string",
++ "maxLength": 500
++ },
++ "heading": {
++ "type": "string",
++ "maxLength": 300
++ }
++ }
++ },
++ "status": {
++ "enum": [
++ "active",
++ "suggested",
++ "archived",
++ "conflict"
++ ]
++ },
++ "confidence": {
++ "type": "number",
++ "minimum": 0,
++ "maximum": 1
++ },
++ "machine": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 100
++ },
++ "no_looks": {
++ "type": "boolean"
++ },
++ "seen_at": {
++ "type": "string",
++ "format": "date-time"
++ }
++ }
++ }
++ },
++ "text": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 8000
++ },
++ "kind": {
++ "enum": [
++ "preference",
++ "fact",
++ "project_rule",
++ "procedure",
++ "decision",
++ "lesson"
++ ]
++ },
++ "scope": {
++ "type": "string",
++ "pattern": "^(user|project:[a-z0-9][a-z0-9._-]{0,63})$"
++ },
++ "status": {
++ "enum": [
++ "active",
++ "suggested",
++ "archived",
++ "conflict"
++ ]
++ },
++ "source": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 100
++ }
++ }
++ }
}
}
}
ddiff --git a/generated/openapi/actor.json b/generated/openapi/actor.json
iindex 8d13392a..8c70a361 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.251.0",
-- "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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/ai.json b/generated/openapi/ai.json
iindex ff985494..8ab9a859 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.251.0",
-- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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"
@@@ -1133,6 +1133,732 @@
}
}
},
++ "/api/v1/memory/items": {
++ "delete": {
++ "operationId": "delete_api_v1_memory_items",
++ "summary": "Store and change a person's memory in OpenVibe.AI (Memory M2): POST /api/v1/memory/items:batch imports up to 200 items, PATCH /items/{id} changes text, kind, scope or status, DELETE /items/{id} and DE",
++ "description": "**ai.memory.write** (first-party): Store and change a person's memory in OpenVibe.AI (Memory M2): POST /api/v1/memory/items:batch imports up to 200 items, PATCH /items/{id} changes text, kind, scope or status, DELETE /items/{id} and DELETE /items?source= remove rows. The person's own token or a service acting on_behalf_of them. Redaction runs again on the server (openvibe-sdk/redact), an item that is only a secret is refused, AI-produced items are suggestions until the person accepts them, and a delete removes the row (profiles that used it are rebuilt).",
++ "tags": [
++ "ai.memory"
++ ],
++ "x-openvibe-capabilities": [
++ "ai.memory.write"
++ ],
++ "x-openvibe-visibility": [
++ "first-party"
++ ],
++ "x-openvibe-quota-class": "ai-memory",
++ "security": [
++ {
++ "openvibeToken": [
++ "ai.memory.write"
++ ]
++ }
++ ],
++ "x-openvibe-input": {
++ "$ref": "#/components/schemas/ai.memory-write-request.v1"
++ },
++ "parameters": [
++ {
++ "name": "items",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 200,
++ "items": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "text"
++ ],
++ "properties": {
++ "id": {
++ "type": "string",
++ "pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "text": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 8000
++ },
++ "kind": {
++ "enum": [
++ "preference",
++ "fact",
++ "project_rule",
++ "procedure",
++ "decision",
++ "lesson"
++ ]
++ },
++ "scope": {
++ "type": "string",
++ "pattern": "^(user|project:[a-z0-9][a-z0-9._-]{0,63})$"
++ },
++ "source": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 100
++ },
++ "source_ref": {
++ "type": [
++ "object",
++ "null"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "path": {
++ "type": "string",
++ "maxLength": 500
++ },
++ "heading": {
++ "type": "string",
++ "maxLength": 300
++ }
++ }
++ },
++ "status": {
++ "enum": [
++ "active",
++ "suggested",
++ "archived",
++ "conflict"
++ ]
++ },
++ "confidence": {
++ "type": "number",
++ "minimum": 0,
++ "maximum": 1
++ },
++ "machine": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 100
++ },
++ "no_looks": {
++ "type": "boolean"
++ },
++ "seen_at": {
++ "type": "string",
++ "format": "date-time"
++ }
++ }
++ }
++ }
++ },
++ {
++ "name": "text",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 8000
++ }
++ },
++ {
++ "name": "kind",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "enum": [
++ "preference",
++ "fact",
++ "project_rule",
++ "procedure",
++ "decision",
++ "lesson"
++ ]
++ }
++ },
++ {
++ "name": "scope",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "type": "string",
++ "pattern": "^(user|project:[a-z0-9][a-z0-9._-]{0,63})$"
++ }
++ },
++ {
++ "name": "status",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "enum": [
++ "active",
++ "suggested",
++ "archived",
++ "conflict"
++ ]
++ }
++ },
++ {
++ "name": "source",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 100
++ }
++ }
++ ],
++ "responses": {
++ "2XX": {
++ "description": "Success",
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/ai.memory-result.v1"
++ }
++ }
++ }
++ },
++ "default": {
++ "description": "An error (RFC 9457 problem details)",
++ "content": {
++ "application/problem+json": {
++ "schema": {
++ "$ref": "#/components/schemas/errors.problem.v1"
++ }
++ }
++ }
++ }
++ }
++ },
++ "get": {
++ "operationId": "get_api_v1_memory_items",
++ "summary": "Read a person's memory from OpenVibe.AI (Memory M2): GET /api/v1/memory/items, /items/{id}, /profile and /search.",
++ "description": "**ai.memory.read** (first-party): Read a person's memory from OpenVibe.AI (Memory M2): GET /api/v1/memory/items, /items/{id}, /profile and /search. The person's own token reads their own items; a service with ai.memory.read acting on_behalf_of a person searches only the scopes its grant names (user always; project:* only for Codes runs in that project), gets active items only, at most 8, and is audited in memory_reads with item ids and never text. Suggested, archived and conflict items never reach an agent.",
++ "tags": [
++ "ai.memory"
++ ],
++ "x-openvibe-capabilities": [
++ "ai.memory.read"
++ ],
++ "x-openvibe-visibility": [
++ "first-party"
++ ],
++ "x-openvibe-quota-class": "ai-memory",
++ "security": [
++ {
++ "openvibeToken": [
++ "ai.memory.read"
++ ]
++ }
++ ],
++ "responses": {
++ "2XX": {
++ "description": "Success",
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/ai.memory-result.v1"
++ }
++ }
++ }
++ },
++ "default": {
++ "description": "An error (RFC 9457 problem details)",
++ "content": {
++ "application/problem+json": {
++ "schema": {
++ "$ref": "#/components/schemas/errors.problem.v1"
++ }
++ }
++ }
++ }
++ }
++ }
++ },
++ "/api/v1/memory/items{batch}": {
++ "post": {
++ "operationId": "post_api_v1_memory_itemsbatch",
++ "summary": "Store and change a person's memory in OpenVibe.AI (Memory M2): POST /api/v1/memory/items:batch imports up to 200 items, PATCH /items/{id} changes text, kind, scope or status, DELETE /items/{id} and DE",
++ "description": "**ai.memory.write** (first-party): Store and change a person's memory in OpenVibe.AI (Memory M2): POST /api/v1/memory/items:batch imports up to 200 items, PATCH /items/{id} changes text, kind, scope or status, DELETE /items/{id} and DELETE /items?source= remove rows. The person's own token or a service acting on_behalf_of them. Redaction runs again on the server (openvibe-sdk/redact), an item that is only a secret is refused, AI-produced items are suggestions until the person accepts them, and a delete removes the row (profiles that used it are rebuilt).",
++ "tags": [
++ "ai.memory"
++ ],
++ "x-openvibe-capabilities": [
++ "ai.memory.write"
++ ],
++ "x-openvibe-visibility": [
++ "first-party"
++ ],
++ "x-openvibe-quota-class": "ai-memory",
++ "security": [
++ {
++ "openvibeToken": [
++ "ai.memory.write"
++ ]
++ }
++ ],
++ "requestBody": {
++ "required": false,
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/ai.memory-write-request.v1"
++ }
++ }
++ }
++ },
++ "parameters": [
++ {
++ "name": "batch",
++ "in": "path",
++ "required": true,
++ "schema": {
++ "type": "string"
++ }
++ }
++ ],
++ "responses": {
++ "2XX": {
++ "description": "Success",
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/ai.memory-result.v1"
++ }
++ }
++ }
++ },
++ "default": {
++ "description": "An error (RFC 9457 problem details)",
++ "content": {
++ "application/problem+json": {
++ "schema": {
++ "$ref": "#/components/schemas/errors.problem.v1"
++ }
++ }
++ }
++ }
++ }
++ }
++ },
++ "/api/v1/memory/items/{id}": {
++ "delete": {
++ "operationId": "delete_api_v1_memory_items_id",
++ "summary": "Store and change a person's memory in OpenVibe.AI (Memory M2): POST /api/v1/memory/items:batch imports up to 200 items, PATCH /items/{id} changes text, kind, scope or status, DELETE /items/{id} and DE",
++ "description": "**ai.memory.write** (first-party): Store and change a person's memory in OpenVibe.AI (Memory M2): POST /api/v1/memory/items:batch imports up to 200 items, PATCH /items/{id} changes text, kind, scope or status, DELETE /items/{id} and DELETE /items?source= remove rows. The person's own token or a service acting on_behalf_of them. Redaction runs again on the server (openvibe-sdk/redact), an item that is only a secret is refused, AI-produced items are suggestions until the person accepts them, and a delete removes the row (profiles that used it are rebuilt).",
++ "tags": [
++ "ai.memory"
++ ],
++ "x-openvibe-capabilities": [
++ "ai.memory.write"
++ ],
++ "x-openvibe-visibility": [
++ "first-party"
++ ],
++ "x-openvibe-quota-class": "ai-memory",
++ "security": [
++ {
++ "openvibeToken": [
++ "ai.memory.write"
++ ]
++ }
++ ],
++ "x-openvibe-input": {
++ "$ref": "#/components/schemas/ai.memory-write-request.v1"
++ },
++ "parameters": [
++ {
++ "name": "id",
++ "in": "path",
++ "required": true,
++ "schema": {
++ "type": "string"
++ }
++ },
++ {
++ "name": "items",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 200,
++ "items": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "text"
++ ],
++ "properties": {
++ "id": {
++ "type": "string",
++ "pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "text": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 8000
++ },
++ "kind": {
++ "enum": [
++ "preference",
++ "fact",
++ "project_rule",
++ "procedure",
++ "decision",
++ "lesson"
++ ]
++ },
++ "scope": {
++ "type": "string",
++ "pattern": "^(user|project:[a-z0-9][a-z0-9._-]{0,63})$"
++ },
++ "source": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 100
++ },
++ "source_ref": {
++ "type": [
++ "object",
++ "null"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "path": {
++ "type": "string",
++ "maxLength": 500
++ },
++ "heading": {
++ "type": "string",
++ "maxLength": 300
++ }
++ }
++ },
++ "status": {
++ "enum": [
++ "active",
++ "suggested",
++ "archived",
++ "conflict"
++ ]
++ },
++ "confidence": {
++ "type": "number",
++ "minimum": 0,
++ "maximum": 1
++ },
++ "machine": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 100
++ },
++ "no_looks": {
++ "type": "boolean"
++ },
++ "seen_at": {
++ "type": "string",
++ "format": "date-time"
++ }
++ }
++ }
++ }
++ },
++ {
++ "name": "text",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 8000
++ }
++ },
++ {
++ "name": "kind",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "enum": [
++ "preference",
++ "fact",
++ "project_rule",
++ "procedure",
++ "decision",
++ "lesson"
++ ]
++ }
++ },
++ {
++ "name": "scope",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "type": "string",
++ "pattern": "^(user|project:[a-z0-9][a-z0-9._-]{0,63})$"
++ }
++ },
++ {
++ "name": "status",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "enum": [
++ "active",
++ "suggested",
++ "archived",
++ "conflict"
++ ]
++ }
++ },
++ {
++ "name": "source",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 100
++ }
++ }
++ ],
++ "responses": {
++ "2XX": {
++ "description": "Success",
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/ai.memory-result.v1"
++ }
++ }
++ }
++ },
++ "default": {
++ "description": "An error (RFC 9457 problem details)",
++ "content": {
++ "application/problem+json": {
++ "schema": {
++ "$ref": "#/components/schemas/errors.problem.v1"
++ }
++ }
++ }
++ }
++ }
++ },
++ "get": {
++ "operationId": "get_api_v1_memory_items_id",
++ "summary": "Read a person's memory from OpenVibe.AI (Memory M2): GET /api/v1/memory/items, /items/{id}, /profile and /search.",
++ "description": "**ai.memory.read** (first-party): Read a person's memory from OpenVibe.AI (Memory M2): GET /api/v1/memory/items, /items/{id}, /profile and /search. The person's own token reads their own items; a service with ai.memory.read acting on_behalf_of a person searches only the scopes its grant names (user always; project:* only for Codes runs in that project), gets active items only, at most 8, and is audited in memory_reads with item ids and never text. Suggested, archived and conflict items never reach an agent.",
++ "tags": [
++ "ai.memory"
++ ],
++ "x-openvibe-capabilities": [
++ "ai.memory.read"
++ ],
++ "x-openvibe-visibility": [
++ "first-party"
++ ],
++ "x-openvibe-quota-class": "ai-memory",
++ "security": [
++ {
++ "openvibeToken": [
++ "ai.memory.read"
++ ]
++ }
++ ],
++ "parameters": [
++ {
++ "name": "id",
++ "in": "path",
++ "required": true,
++ "schema": {
++ "type": "string"
++ }
++ }
++ ],
++ "responses": {
++ "2XX": {
++ "description": "Success",
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/ai.memory-result.v1"
++ }
++ }
++ }
++ },
++ "default": {
++ "description": "An error (RFC 9457 problem details)",
++ "content": {
++ "application/problem+json": {
++ "schema": {
++ "$ref": "#/components/schemas/errors.problem.v1"
++ }
++ }
++ }
++ }
++ }
++ },
++ "patch": {
++ "operationId": "patch_api_v1_memory_items_id",
++ "summary": "Store and change a person's memory in OpenVibe.AI (Memory M2): POST /api/v1/memory/items:batch imports up to 200 items, PATCH /items/{id} changes text, kind, scope or status, DELETE /items/{id} and DE",
++ "description": "**ai.memory.write** (first-party): Store and change a person's memory in OpenVibe.AI (Memory M2): POST /api/v1/memory/items:batch imports up to 200 items, PATCH /items/{id} changes text, kind, scope or status, DELETE /items/{id} and DELETE /items?source= remove rows. The person's own token or a service acting on_behalf_of them. Redaction runs again on the server (openvibe-sdk/redact), an item that is only a secret is refused, AI-produced items are suggestions until the person accepts them, and a delete removes the row (profiles that used it are rebuilt).",
++ "tags": [
++ "ai.memory"
++ ],
++ "x-openvibe-capabilities": [
++ "ai.memory.write"
++ ],
++ "x-openvibe-visibility": [
++ "first-party"
++ ],
++ "x-openvibe-quota-class": "ai-memory",
++ "security": [
++ {
++ "openvibeToken": [
++ "ai.memory.write"
++ ]
++ }
++ ],
++ "requestBody": {
++ "required": false,
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/ai.memory-write-request.v1"
++ }
++ }
++ }
++ },
++ "parameters": [
++ {
++ "name": "id",
++ "in": "path",
++ "required": true,
++ "schema": {
++ "type": "string"
++ }
++ }
++ ],
++ "responses": {
++ "2XX": {
++ "description": "Success",
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/ai.memory-result.v1"
++ }
++ }
++ }
++ },
++ "default": {
++ "description": "An error (RFC 9457 problem details)",
++ "content": {
++ "application/problem+json": {
++ "schema": {
++ "$ref": "#/components/schemas/errors.problem.v1"
++ }
++ }
++ }
++ }
++ }
++ }
++ },
++ "/api/v1/memory/profile": {
++ "get": {
++ "operationId": "get_api_v1_memory_profile",
++ "summary": "Read a person's memory from OpenVibe.AI (Memory M2): GET /api/v1/memory/items, /items/{id}, /profile and /search.",
++ "description": "**ai.memory.read** (first-party): Read a person's memory from OpenVibe.AI (Memory M2): GET /api/v1/memory/items, /items/{id}, /profile and /search. The person's own token reads their own items; a service with ai.memory.read acting on_behalf_of a person searches only the scopes its grant names (user always; project:* only for Codes runs in that project), gets active items only, at most 8, and is audited in memory_reads with item ids and never text. Suggested, archived and conflict items never reach an agent.",
++ "tags": [
++ "ai.memory"
++ ],
++ "x-openvibe-capabilities": [
++ "ai.memory.read"
++ ],
++ "x-openvibe-visibility": [
++ "first-party"
++ ],
++ "x-openvibe-quota-class": "ai-memory",
++ "security": [
++ {
++ "openvibeToken": [
++ "ai.memory.read"
++ ]
++ }
++ ],
++ "responses": {
++ "2XX": {
++ "description": "Success",
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/ai.memory-result.v1"
++ }
++ }
++ }
++ },
++ "default": {
++ "description": "An error (RFC 9457 problem details)",
++ "content": {
++ "application/problem+json": {
++ "schema": {
++ "$ref": "#/components/schemas/errors.problem.v1"
++ }
++ }
++ }
++ }
++ }
++ }
++ },
++ "/api/v1/memory/search": {
++ "get": {
++ "operationId": "get_api_v1_memory_search",
++ "summary": "Read a person's memory from OpenVibe.AI (Memory M2): GET /api/v1/memory/items, /items/{id}, /profile and /search.",
++ "description": "**ai.memory.read** (first-party): Read a person's memory from OpenVibe.AI (Memory M2): GET /api/v1/memory/items, /items/{id}, /profile and /search. The person's own token reads their own items; a service with ai.memory.read acting on_behalf_of a person searches only the scopes its grant names (user always; project:* only for Codes runs in that project), gets active items only, at most 8, and is audited in memory_reads with item ids and never text. Suggested, archived and conflict items never reach an agent.",
++ "tags": [
++ "ai.memory"
++ ],
++ "x-openvibe-capabilities": [
++ "ai.memory.read"
++ ],
++ "x-openvibe-visibility": [
++ "first-party"
++ ],
++ "x-openvibe-quota-class": "ai-memory",
++ "security": [
++ {
++ "openvibeToken": [
++ "ai.memory.read"
++ ]
++ }
++ ],
++ "responses": {
++ "2XX": {
++ "description": "Success",
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/ai.memory-result.v1"
++ }
++ }
++ }
++ },
++ "default": {
++ "description": "An error (RFC 9457 problem details)",
++ "content": {
++ "application/problem+json": {
++ "schema": {
++ "$ref": "#/components/schemas/errors.problem.v1"
++ }
++ }
++ }
++ }
++ }
++ }
++ },
"/api/v1/models": {
"get": {
"operationId": "get_api_v1_models",
@@@ -3480,6 +4206,298 @@
}
]
},
++ "ai.memory-item.v1": {
++ "title": "AiMemoryItem",
++ "description": "ai.memory-item@1 (OpenVibe.AI; Memory M2): one memory item as the person's own API reads it. Tenant is the owner (`user:usr_…`); the text is decrypted only inside AI's process and never logged, never in an error, a span or an event. `source_ref` is the file path relative to the scanned root and the heading, when the item came from a file.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "id",
++ "owner",
++ "scope",
++ "kind",
++ "text",
++ "source",
++ "status",
++ "confidence",
++ "created_at",
++ "updated_at"
++ ],
++ "properties": {
++ "id": {
++ "type": "string",
++ "pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "owner": {
++ "type": "string",
++ "pattern": "^user:usr_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "scope": {
++ "type": "string",
++ "pattern": "^(user|project:[a-z0-9][a-z0-9._-]{0,63})$",
++ "description": "`user` for the person's own notes, or `project:<slug>` for a repo or folder they chose. Never an absolute path."
++ },
++ "kind": {
++ "enum": [
++ "preference",
++ "fact",
++ "project_rule",
++ "procedure",
++ "decision",
++ "lesson"
++ ]
++ },
++ "text": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 8000,
++ "description": "The item text after the server-side redaction. Only the person's own routes and a granted agent search see it."
++ },
++ "source": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 100,
++ "description": "The adapter id (claude-code, cursor, …) or the service (actor, vibe, know, person)."
++ },
++ "source_ref": {
++ "type": [
++ "object",
++ "null"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "path": {
++ "type": "string",
++ "maxLength": 500
++ },
++ "heading": {
++ "type": "string",
++ "maxLength": 300
++ }
++ },
++ "description": "The path relative to the scanned root and the heading, when the item came from a file."
++ },
++ "status": {
++ "enum": [
++ "active",
++ "suggested",
++ "archived",
++ "conflict"
++ ]
++ },
++ "confidence": {
++ "type": "number",
++ "minimum": 0,
++ "maximum": 1
++ },
++ "seen_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "created_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "updated_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "machine": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 100,
++ "description": "The Node machine id it came from, when it came from one."
++ },
++ "no_looks": {
++ "type": "boolean",
++ "description": "True when the item was produced by an AI: the server ran noLooks on it (Memory M2 rule 5)."
++ }
++ }
++ },
++ "ai.memory-result.v1": {
++ "title": "AiMemoryResult",
++ "description": "ai.memory-result@1 (OpenVibe.AI; Memory M2): what the memory API answers: a list of items (GET /items, the batch import), one item (GET or PATCH /items/{id}), the cached profile (GET /profile), a count of deleted rows (DELETE) or the agent search's items (GET /search, at most 8, active only). The text is the person's own and is never logged.",
++ "type": "object",
++ "additionalProperties": false,
++ "properties": {
++ "items": {
++ "type": "array",
++ "maxItems": 200,
++ "items": {
++ "$ref": "#/components/schemas/ai.memory-item.v1"
++ }
++ },
++ "item": {
++ "$ref": "#/components/schemas/ai.memory-item.v1"
++ },
++ "profile": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "scope",
++ "text",
++ "items_hash",
++ "built_at"
++ ],
++ "properties": {
++ "scope": {
++ "type": "string",
++ "pattern": "^(user|project:[a-z0-9][a-z0-9._-]{0,63})$"
++ },
++ "text": {
++ "type": "string",
++ "maxLength": 4000,
++ "description": "The cached summary of the person's own notes for this scope. It passed noLooks before it was stored."
++ },
++ "items_hash": {
++ "type": "string",
++ "pattern": "^[0-9a-f]{64}$",
++ "description": "sha256 of the sorted item MACs the profile was built from."
++ },
++ "built_at": {
++ "type": "string",
++ "format": "date-time"
++ }
++ }
++ },
++ "deleted": {
++ "type": "integer",
++ "minimum": 0
++ },
++ "count": {
++ "type": "integer",
++ "minimum": 0
++ }
++ }
++ },
++ "ai.memory-write-request.v1": {
++ "title": "AiMemoryWriteRequest",
++ "description": "ai.memory-write-request@1 (OpenVibe.AI; Memory M2): the body of POST /api/v1/memory/items:batch (up to 200 items), PATCH /api/v1/memory/items/{id} (text, kind, scope or status) and DELETE /api/v1/memory/items?source= (the source to delete). Secret shapes are redacted again on the server, and an item that is only a secret is refused. AI-produced items are suggestions until the person accepts them.",
++ "type": "object",
++ "additionalProperties": false,
++ "properties": {
++ "items": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 200,
++ "items": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "text"
++ ],
++ "properties": {
++ "id": {
++ "type": "string",
++ "pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "text": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 8000
++ },
++ "kind": {
++ "enum": [
++ "preference",
++ "fact",
++ "project_rule",
++ "procedure",
++ "decision",
++ "lesson"
++ ]
++ },
++ "scope": {
++ "type": "string",
++ "pattern": "^(user|project:[a-z0-9][a-z0-9._-]{0,63})$"
++ },
++ "source": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 100
++ },
++ "source_ref": {
++ "type": [
++ "object",
++ "null"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "path": {
++ "type": "string",
++ "maxLength": 500
++ },
++ "heading": {
++ "type": "string",
++ "maxLength": 300
++ }
++ }
++ },
++ "status": {
++ "enum": [
++ "active",
++ "suggested",
++ "archived",
++ "conflict"
++ ]
++ },
++ "confidence": {
++ "type": "number",
++ "minimum": 0,
++ "maximum": 1
++ },
++ "machine": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 100
++ },
++ "no_looks": {
++ "type": "boolean"
++ },
++ "seen_at": {
++ "type": "string",
++ "format": "date-time"
++ }
++ }
++ }
++ },
++ "text": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 8000
++ },
++ "kind": {
++ "enum": [
++ "preference",
++ "fact",
++ "project_rule",
++ "procedure",
++ "decision",
++ "lesson"
++ ]
++ },
++ "scope": {
++ "type": "string",
++ "pattern": "^(user|project:[a-z0-9][a-z0-9._-]{0,63})$"
++ },
++ "status": {
++ "enum": [
++ "active",
++ "suggested",
++ "archived",
++ "conflict"
++ ]
++ },
++ "source": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 100
++ }
++ }
++ },
"ai.model.v1": {
"title": "AiModel",
"description": "ai.model@1: one model of a provider in OpenVibe.AI's registry (server/registry.js decodeModel): type, status, limits, per-million-token costs and what it supports.",
ddiff --git a/generated/openapi/bench.json b/generated/openapi/bench.json
iindex 3d8653c4..052999e0 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.251.0",
-- "description": "Routes of OpenVibe.Bench as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Bench as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 ab279bb8..a3ee41b5 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.251.0",
-- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 22d5352e..deea04d5 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.251.0",
-- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 ede9b18f..74c68bb7 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.251.0",
-- "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 320f987c..f1dca534 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.251.0",
-- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 5a57e766..c1c5a7db 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.251.0",
-- "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 3b7cfaa5..eeccf2cc 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.251.0",
-- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 3557504d..424d4610 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.251.0",
-- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 0429d3b4..e7c1683f 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.251.0",
-- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 c9a7cb3a..0e716924 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.251.0",
-- "description": "Routes of OpenVibe.Domains as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Domains as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 1250f638..f948951f 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.251.0",
-- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 59868f3f..a8e9e361 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.251.0",
-- "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 69f3c034..e20ee264 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.251.0",
-- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 98ebb698..d7c065e1 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.251.0",
-- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 f4ae5ad8..f077fe3e 100644
---- a/generated/openapi/index.json
++++ b/generated/openapi/index.json
@@@ -12,8 +12,8 @@
"service": "ai",
"name": "OpenVibe.AI",
"origin": "https://ai.openvibe.services",
-- "operations": 44,
-- "capabilities": 9
++ "operations": 52,
++ "capabilities": 11
},
{
"service": "bench",
ddiff --git a/generated/openapi/inventory.json b/generated/openapi/inventory.json
iindex a2c3148f..4d5f5c07 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.251.0",
-- "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 78c547e6..ca27c1ef 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.251.0",
-- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 b1dee444..7f67aab1 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.251.0",
-- "description": "Routes of OpenVibe.MediaHub as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.MediaHub as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 21bc317e..f39b581e 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.251.0",
-- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 b27e4d40..b5e90e78 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.251.0",
-- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 9719ee24..b2286cd4 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.251.0",
-- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 2a7d8826..18ddfb98 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.251.0",
-- "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 f945f30b..84b212a3 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.251.0",
-- "description": "Routes of OpenVibe.Play as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Play as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 c6ebd475..c384a381 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.251.0",
-- "description": "Routes of OpenVibe.Quest as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Quest as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 3db0afc3..6ff80d38 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.251.0",
-- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 625a7166..52f3b9ea 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.251.0",
-- "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 c68f94a7..6b887b6f 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.251.0",
-- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 cbeb0499..86298bad 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.251.0",
-- "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 10c9d525..44a024b3 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.251.0",
-- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 5c65e4b4..733e1faf 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.251.0",
-- "description": "Routes of OpenVibe.Space as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Space as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 5c028af5..89c2487c 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.251.0",
-- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 617d775a..654e7174 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.251.0",
-- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 51141665..3eea941b 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.251.0",
-- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 e231d4ce..484fa962 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.251.0",
-- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 12fa05c1..fcd6cbef 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.251.0",
-- "description": "Routes of OpenVibe.Vision as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Vision as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 5ae64be3..58fc44cf 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.251.0",
-- "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 410e086e..113ead9f 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.251.0",
-- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 96076228..b4db7827 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.251.0",
-- "description": "Routes of OpenVibe.Work as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Work as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 c2ed31a1..61a53ee7 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.251.0",
-- "description": "Routes of OpenVibe.Zone as the OpenVibe contracts describe them (openvibe-contracts 0.251.0): each operation lists the capabilities it performs; a token for 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.252.0",
++ "description": "Routes of OpenVibe.Zone as the OpenVibe contracts describe them (openvibe-contracts 0.252.0): each operation lists the capabilities it performs; a token for 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 5d456db7..24e9f29f 100644
---- a/generated/typescript/index.d.ts
++++ b/generated/typescript/index.d.ts
@@@ -267867,3 +267867,121 @@ export interface BenchRunV2 {
provenance: "verified" | "submitted";
created_at: string;
}
++
++/** [email protected] (owner: ai) */
++/**
++ * ai.memory-item@1 (OpenVibe.AI; Memory M2): one memory item as the person's own API reads it. Tenant is the owner (`user:usr_…`); the text is decrypted only inside AI's process and never logged, never in an error, a span or an event. `source_ref` is the file path relative to the scanned root and the heading, when the item came from a file.
++ */
++export interface AiMemoryItem {
++ id: string;
++ owner: string;
++ /**
++ * `user` for the person's own notes, or `project:<slug>` for a repo or folder they chose. Never an absolute path.
++ */
++ scope: string;
++ kind: "preference" | "fact" | "project_rule" | "procedure" | "decision" | "lesson";
++ /**
++ * The item text after the server-side redaction. Only the person's own routes and a granted agent search see it.
++ */
++ text: string;
++ /**
++ * The adapter id (claude-code, cursor, …) or the service (actor, vibe, know, person).
++ */
++ source: string;
++ /**
++ * The path relative to the scanned root and the heading, when the item came from a file.
++ */
++ source_ref?: {
++ path?: string;
++ heading?: string;
++ } | null;
++ status: "active" | "suggested" | "archived" | "conflict";
++ confidence: number;
++ seen_at?: string;
++ created_at: string;
++ updated_at: string;
++ /**
++ * The Node machine id it came from, when it came from one.
++ */
++ machine?: string | null;
++ /**
++ * True when the item was produced by an AI: the server ran noLooks on it (Memory M2 rule 5).
++ */
++ no_looks?: boolean;
++}
++
++/** [email protected] (owner: ai) */
++/**
++ * ai.memory-result@1 (OpenVibe.AI; Memory M2): what the memory API answers: a list of items (GET /items, the batch import), one item (GET or PATCH /items/{id}), the cached profile (GET /profile), a count of deleted rows (DELETE) or the agent search's items (GET /search, at most 8, active only). The text is the person's own and is never logged.
++ */
++export interface AiMemoryResult {
++ /**
++ * @maxItems 200
++ */
++ items?: AiMemoryItem[];
++ item?: AiMemoryItem;
++ profile?: {
++ scope: string;
++ /**
++ * The cached summary of the person's own notes for this scope. It passed noLooks before it was stored.
++ */
++ text: string;
++ /**
++ * sha256 of the sorted item MACs the profile was built from.
++ */
++ items_hash: string;
++ built_at: string;
++ };
++ deleted?: number;
++ count?: number;
++}
++
++/** [email protected] (owner: ai) */
++/**
++ * ai.memory-write-request@1 (OpenVibe.AI; Memory M2): the body of POST /api/v1/memory/items:batch (up to 200 items), PATCH /api/v1/memory/items/{id} (text, kind, scope or status) and DELETE /api/v1/memory/items?source= (the source to delete). Secret shapes are redacted again on the server, and an item that is only a secret is refused. AI-produced items are suggestions until the person accepts them.
++ */
++export interface AiMemoryWriteRequest {
++ /**
++ * @minItems 1
++ * @maxItems 200
++ */
++ items?: [
++ {
++ id?: string;
++ text: string;
++ kind?: "preference" | "fact" | "project_rule" | "procedure" | "decision" | "lesson";
++ scope?: string;
++ source?: string;
++ source_ref?: {
++ path?: string;
++ heading?: string;
++ } | null;
++ status?: "active" | "suggested" | "archived" | "conflict";
++ confidence?: number;
++ machine?: string | null;
++ no_looks?: boolean;
++ seen_at?: string;
++ },
++ ...{
++ id?: string;
++ text: string;
++ kind?: "preference" | "fact" | "project_rule" | "procedure" | "decision" | "lesson";
++ scope?: string;
++ source?: string;
++ source_ref?: {
++ path?: string;
++ heading?: string;
++ } | null;
++ status?: "active" | "suggested" | "archived" | "conflict";
++ confidence?: number;
++ machine?: string | null;
++ no_looks?: boolean;
++ seen_at?: string;
++ }[]
++ ];
++ text?: string;
++ kind?: "preference" | "fact" | "project_rule" | "procedure" | "decision" | "lesson";
++ scope?: string;
++ status?: "active" | "suggested" | "archived" | "conflict";
++ source?: string;
++}
ddiff --git a/manifests/capabilities/ai.memory.read.json b/manifests/capabilities/ai.memory.read.json
nnew file mode 100644
iindex 00000000..87260328
---- /dev/null
++++ b/manifests/capabilities/ai.memory.read.json
@@@ -0,0 +1,24 @@
++{
++ "id": "ai.memory.read",
++ "version": "1.0",
++ "owner": "ai",
++ "status": "active",
++ "visibility": "first-party",
++ "description": "Read a person's memory from OpenVibe.AI (Memory M2): GET /api/v1/memory/items, /items/{id}, /profile and /search. The person's own token reads their own items; a service with ai.memory.read acting on_behalf_of a person searches only the scopes its grant names (user always; project:* only for Codes runs in that project), gets active items only, at most 8, and is audited in memory_reads with item ids and never text. Suggested, archived and conflict items never reach an agent.",
++ "permissions": [
++ "ai:memory:read"
++ ],
++ "resourceConstraints": [
++ "owner"
++ ],
++ "quotaClass": "ai-memory",
++ "events": [],
++ "implementedBy": [
++ "GET /api/v1/memory/items",
++ "GET /api/v1/memory/items/:id",
++ "GET /api/v1/memory/profile",
++ "GET /api/v1/memory/search"
++ ],
++ "inputSchema": "common.no-body@1",
++ "outputSchema": "ai.memory-result@1"
++}
ddiff --git a/manifests/capabilities/ai.memory.write.json b/manifests/capabilities/ai.memory.write.json
nnew file mode 100644
iindex 00000000..40c50ba0
---- /dev/null
++++ b/manifests/capabilities/ai.memory.write.json
@@@ -0,0 +1,24 @@
++{
++ "id": "ai.memory.write",
++ "version": "1.0",
++ "owner": "ai",
++ "status": "active",
++ "visibility": "first-party",
++ "description": "Store and change a person's memory in OpenVibe.AI (Memory M2): POST /api/v1/memory/items:batch imports up to 200 items, PATCH /items/{id} changes text, kind, scope or status, DELETE /items/{id} and DELETE /items?source= remove rows. The person's own token or a service acting on_behalf_of them. Redaction runs again on the server (openvibe-sdk/redact), an item that is only a secret is refused, AI-produced items are suggestions until the person accepts them, and a delete removes the row (profiles that used it are rebuilt).",
++ "permissions": [
++ "ai:memory:write"
++ ],
++ "resourceConstraints": [
++ "owner"
++ ],
++ "quotaClass": "ai-memory",
++ "events": [],
++ "implementedBy": [
++ "POST /api/v1/memory/items:batch",
++ "PATCH /api/v1/memory/items/:id",
++ "DELETE /api/v1/memory/items/:id",
++ "DELETE /api/v1/memory/items"
++ ],
++ "inputSchema": "ai.memory-write-request@1",
++ "outputSchema": "ai.memory-result@1"
++}
ddiff --git a/manifests/services/ai.json b/manifests/services/ai.json
iindex 1c890d04..c21c0681 100644
---- a/manifests/services/ai.json
++++ b/manifests/services/ai.json
@@@ -28,7 +28,9 @@
"ai.run.read",
"ai.usage.read",
"ai.workflow.manage",
-- "ai.actions.read"
++ "ai.actions.read",
++ "ai.memory.read",
++ "ai.memory.write"
],
"eventsProduced": [
"ai.run.queued",
@@@ -77,14 +79,14 @@
],
"window": "automatic only while ovhost waits for readiness after the restart (30 s in host.example.json); manual afterwards, as long as no blocker applies",
"blockers": {
-- "none": "the schema code only adds (CREATE … IF NOT EXISTS, ADD COLUMN; no DROP, RENAME or table rebuild), which an older release ignores"
++ "none": "the schema code only adds (CREATE \u2026 IF NOT EXISTS, ADD COLUMN; no DROP, RENAME or table rebuild), which an older release ignores"
}
},
"contracts": {
"range": ">=0.6.0 <1.0.0"
},
"leases": {
-- "none": "no claims: one process owns its PostgreSQL database (ov_ai); a run is taken with a compare-and-set on its status (queued → running)"
++ "none": "no claims: one process owns its PostgreSQL database (ov_ai); a run is taken with a compare-and-set on its status (queued \u2192 running)"
}
},
"notes": "Providers, models, routing profiles, versioned prompt templates and workflows, runs, request logs, citations, scoped cache, quotas and audit. Workflow output is a draft/evidence package attributed to workflow + model + run. ai.run.queued|succeeded|failed|cached have payload contracts (v0.30.0, status planned): AI publishes them once its Events client is wired in; it publishes none today. ai.run.create takes ai.run-request@1 and returns ai.run@1.",
ddiff --git a/package-lock.json b/package-lock.json
iindex 0513990e..618470bb 100644
---- a/package-lock.json
++++ b/package-lock.json
@@@ -1,12 +1,12 @@
{
"name": "openvibe-contracts",
-- "version": "0.249.0",
++ "version": "0.252.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "openvibe-contracts",
-- "version": "0.249.0",
++ "version": "0.252.0",
"license": "AGPL-3.0-only",
"dependencies": {
"ajv": "^8.17.1",
ddiff --git a/package.json b/package.json
iindex 0893d60d..a4d458fa 100644
---- a/package.json
++++ b/package.json
@@@ -1,6 +1,6 @@
{
"name": "openvibe-contracts",
-- "version": "0.251.0",
++ "version": "0.252.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",