openvibers/openvibe.contracts Commits

v0.33.1: CHANGELOG, README, ADR-027 status (tools.tool.read active; the run API still planned) and version 0.33.1

OP OpenVibers committed 23 Sept 2026 · 238c0ea2af · 5 files, +112 −13


Changes

ddiff --git a/CHANGELOG.md b/CHANGELOG.md
iindex 369863ba..37cf18ca 100644
---- a/CHANGELOG.md
++++ b/CHANGELOG.md
@@@ -4,6 +4,91 @@ All notable changes to `openvibe-contracts`. Releases are git tags (`vX.Y.Z`) th
from `https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/<tag>`. Before v0.30.0,
the notes were in the tag and commit messages (`git tag -n1`).
++## 0.33.1 — 2026-09-23
++
++Additive: `compat.js` reports no breaking change against v0.33.0.
++
++Follow-ups to the Tools registry, which OpenVibe.Tools now serves in production (`GET /api/v1/tools`,
++`/api/v1/tools/:id` and `/api/v1/tools/:id/schema` on openvibe.tools and every satellite).
++
++**Capabilities and manifests**
++
++- `tools.tool.read` is `active` (it was `planned`). The gateway answers for all 169 tools, and the img,
++ audio, docs, text, yt, maps and food satellites answer for their own. Its description now says what
++ the routes answer: CORS for any origin, ETag and 304, `$defs.input: false` for a tool without an API,
++ `400 tools.query.invalid` and `404 tools.tool.not_found`.
++- `tools.tool.run` and `tools.net.probe` stay `planned` until Tools serves the run API.
++- Tools 0.4.1: its notes say the registry is served.
++
++**`tools.tool@1` 1.0.0 → 1.1.0.** Two optional fields, so every v0.33.0 descriptor stays valid:
++
++- `keywords`: the catalogue's search terms (`GET /api/catalog.json` `tools[].keywords`), which
++ `GET /api/v1/tools?q=` matches beside the id, name and summary. Unique, trimmed, non-empty phrases.
++- `examples`: `[{ title?, input, files?: [{ name?, mime, url? }] }]`, sample runs that the docs and the
++ generated OpenAPI document will publish. Each input is valid against the tool's input schema. The
++ schema refuses examples on a tool without an API.
++
++The descriptions now also say:
++
++- `output.schema` describes `result.data` whatever the execution. For a job tool, that is the data of
++ the run's result and of its job's result, which are the same object.
++- `GET /api/v1/tools/:id/schema` has `$defs.input: false` when `api` is false.
++- There is no `planned` status. A planned catalogue entry is not a tool: it has no descriptor and is
++ not listed. Neither is a mirror (a second build of another tool). Both answer
++ `404 tools.tool.not_found`, with a detail that says the id is planned or names the tool it mirrors.
++ `tools.tool-list@1` says the same, and that `family`, `execution` and `status` take comma lists.
++
++A consumer that validates descriptors against v0.33.0 refuses `keywords` and `examples`
++(`additionalProperties: false`). Tools should start serving them only after it moves its pin to this
++release, and so should any service that validates descriptors it reads.
++
++**`contracts.tools.checkDescriptor`** now checks each example:
++
++- its input against the tool's input schema, when the schema is embedded (errors point at
++ `/examples/<i>/input/…`);
++- its size as JSON against `limits.maxInputBytes`;
++- its files against `files`: the count within `min` and `max`, and each `mime` allowed by `accept`
++ (`image/*` takes `image/heic`).
++
++An input given as `{ $ref }` (the list form) is not fetched, so its examples are checked where the
++schema is embedded: `GET /api/v1/tools/:id` and the Tools registry test. When there are examples to
++check, an embedded input schema that does not compile is reported. All 169 of Tools' current
++descriptors pass, and so do they with their catalogue keywords and their own example inputs added.
++
++**Problem codes Tools emits.** They are listed with the routes that answer them, as every service's are
++(`errors.problem@1` carries any code).
++
++- Registry (`tools.tool@1`, `tools.tool-list@1`, `tools.tool.read`):
++ - `400 tools.query.invalid`: an unknown `execution` or `status` value, or an `api` that is not
++ `true` or `false`;
++ - `404 tools.tool.not_found`: an unknown id, and a planned or mirror id, with a detail saying which.
++- `tools.run-request@1` and `tools.job-request@1`:
++ - `503 tools.unavailable`: a program or upstream the tool needs is missing. A job submission is
++ refused then, rather than failing later. `503 tools.tool.unavailable` is still the run API's
++ refusal for a tool whose descriptor status is `unavailable`.
++ - Coming with the shared guard, not emitted yet: `429 tools.quota.exceeded` (the caller's allowance
++ in the quota class is spent) and `503 tools.busy` (every slot for that kind of work is taken).
++ Both carry `Retry-After`. The run request still lists `quota.exceeded` beside the new code.
++- Codes a tool chooses, carried as the error of a failed run or job (`tools.run@1`, `tools.job@1`,
++ `tools.job.failed`): `413 tools.pdf.too_many_pages` (over `limits.maxPages`) and
++ `422 tools.pdf.wrong_password`.
++
++**Fixtures and tests**
++
++- The valid png, dns, jsonminify and port descriptors carry keywords and examples, and the list fixture
++ carries keywords.
++- New invalid descriptors: an example whose input the tool's schema refuses, an example file that
++ `files.accept` does not allow, examples on a page-only tool, and a blank keyword.
++- `test/run.js` checks the `tools.tool` and `tools.tool-list` fixtures with `checkDescriptor` and
++ `checkList`, not only the schema, so an invalid fixture can break a rule that JSON Schema cannot
++ express. It also checks:
++ - that a v0.33.0 descriptor, without the new fields, is still valid;
++ - each example rule;
++ - that `tools.tool.read` is `active` while the run capabilities stay `planned`;
++ - that there is no `planned` status;
++ - that each new code is a valid problem code and is listed with its status;
++ - that `tools.quota.exceeded` and `tools.busy` carry `Retry-After`.
++
## 0.33.0 — 2026-09-23
Additive: `compat.js` reports no breaking change against v0.32.0.
ddiff --git a/README.md b/README.md
iindex 6b607b42..8dc0bd7f 100644
---- a/README.md
++++ b/README.md
@@@ -2,7 +2,7 @@
> Machine-readable contracts for the whole OpenVibe network.
--**Status:** alpha, v0.33.0 (first released in Wave 1). 95 schemas (66 of them event payloads), 30 service manifests, 176 capability manifests and 6 namespace manifests. 23 repositories run `openvibe-contracts-check` in CI, and deployed services verify service and app tokens with `serviceAuth` in production. Deployed consumers pin different tags (Games v0.8.0, the rest v0.11.0 to v0.29.0); Network, which serves the registry, pins v0.28.0. No N/N-1 compatibility fixtures exist yet.
++**Status:** alpha, v0.33.1 (first released in Wave 1). 95 schemas (66 of them event payloads), 30 service manifests, 176 capability manifests and 6 namespace manifests. 23 repositories run `openvibe-contracts-check` in CI, and deployed services verify service and app tokens with `serviceAuth` in production. Deployed consumers pin different tags (Games v0.8.0, the rest v0.11.0 to v0.29.0); Network, which serves the registry, pins v0.28.0. No N/N-1 compatibility fixtures exist yet.
**Plan:** OpenVibe Development Roadmap, Wave 1 (implementation plan rev 3, §3.1 and §18.11).
**License:** AGPL-3.0 (same as every OpenVibe service).
@@@ -133,7 +133,9 @@ openvibe-sdk and the docs all read it. It says:
- whether the API exposes it (`api`), and how to call it (`run`);
- its input schema, files, output, limits and auth;
- its quota class and cost;
--- whether it fetches hosts the caller chose (`egress`).
++- whether it fetches hosts the caller chose (`egress`);
++- optionally (v0.33.1), its catalogue `keywords`, which `?q=` searches, and `examples` of runs for the
++ docs and the OpenAPI document.
| Route (openvibe.tools) | Capability | Contract |
|---|---|---|
@@@ -143,11 +145,20 @@ openvibe-sdk and the docs all read it. It says:
A run is answered inline, or with its job (202 + `Location`) while a job tool is still working.
Callers are tiered: anonymous < session < user < app/service. Quotas count each tool's `cost` within
--its `quotaClass`. yt is page-only (`api: false`). The registry routes and the run route are `planned`
--until Tools serves them.
++its `quotaClass`. yt is page-only (`api: false`). Only real tools have descriptors: there is no
++`planned` status, and a planned or mirror id is `404 tools.tool.not_found`. The registry routes are
++served on the gateway and every satellite (`tools.tool.read` is `active` since v0.33.1); the run route
++and `tools.net.probe` are `planned` until Tools serves them.
`contracts.tools.checkDescriptor(d)` and `checkList(list)` apply the rules that JSON Schema cannot
--express, such as `run.path` being the tool's own. `jobInput(d, input)` builds a job tool's job input.
++express, such as `run.path` being the tool's own, and check each example's input against an embedded
++input schema. `jobInput(d, input)` builds a job tool's job input.
++
++Tools' problem codes are listed with the routes that answer them (`tools.run-request@1`,
++`tools.job-request@1`, `tools.tool-list@1`, `tools.tool@1`). They include `400 tools.query.invalid`,
++`404 tools.tool.not_found`, `413 tools.pdf.too_many_pages`, `422 tools.pdf.wrong_password`,
++`503 tools.unavailable` (a program or upstream a tool needs is missing), and, with `Retry-After`,
++`429 tools.quota.exceeded` and `503 tools.busy`.
## Versioning and compatibility
ddiff --git a/docs/adr/ADR-027-tools-platform-api.md b/docs/adr/ADR-027-tools-platform-api.md
iindex e2c9b30f..f8a9848e 100644
---- a/docs/adr/ADR-027-tools-platform-api.md
++++ b/docs/adr/ADR-027-tools-platform-api.md
@@@ -1,7 +1,8 @@
# ADR-027: Tools platform API
--**Status:** Accepted 2026-09-23. Contracts in openvibe-contracts v0.33.0; the registry and run routes
--are `planned` until OpenVibe.Tools serves them.
++**Status:** Accepted 2026-09-23. Contracts in openvibe-contracts v0.33.0. Tools serves the registry
++routes since 2026-09-23, so `tools.tool.read` is `active` in v0.33.1; the run route and
++`tools.net.probe` stay `planned` until Tools serves them.
## Context and current evidence
@@@ -35,9 +36,11 @@ OpenVibe.Tools that day found:
- **`tools.tool@1` describes each tool.** It gives `id` (the catalogue id), `family`, `name`,
`summary`, `status` (`stable` | `beta` | `preview` | `unavailable`, and `statusReason` when a tool
is unavailable), `execution` (`client` | `sync` | `job`), `api`, `run`, `input` (JSON Schema),
-- `files`, `output`, `limits`, `auth`, `quotaClass`, `cost`, `egress`, `hosts` and `docs`. Tools
-- builds the descriptors from each tool's own code, which retires the three copies. The page, the
-- run API, `openvibe-sdk/tools`, the OpenAPI document and the docs all read them.
++ `files`, `output`, `limits`, `auth`, `quotaClass`, `cost`, `egress`, `hosts` and `docs`, and
++ optionally (v0.33.1) the catalogue's `keywords` and `examples` of runs, each valid against the
++ input schema. There is no `planned` status: a planned entry is not a tool and has no descriptor.
++ Tools builds the descriptors from each tool's own code, which retires the three copies. The page,
++ the run API, `openvibe-sdk/tools`, the OpenAPI document and the docs all read them.
- **Registry routes** (capability `tools.tool.read`, public). `GET /api/v1/tools` answers
`tools.tool-list@1`, with schemas as `$ref`. `GET /api/v1/tools/:id` answers the descriptor with
its schemas embedded. `GET /api/v1/tools/:id/schema` answers
ddiff --git a/package-lock.json b/package-lock.json
iindex c32a41dd..0183b340 100644
---- a/package-lock.json
++++ b/package-lock.json
@@@ -1,12 +1,12 @@
{
"name": "openvibe-contracts",
-- "version": "0.33.0",
++ "version": "0.33.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "openvibe-contracts",
-- "version": "0.33.0",
++ "version": "0.33.1",
"license": "AGPL-3.0-only",
"dependencies": {
"ajv": "^8.17.1",
ddiff --git a/package.json b/package.json
iindex 0d4c22ce..40e62b37 100644
---- a/package.json
++++ b/package.json
@@@ -1,6 +1,6 @@
{
"name": "openvibe-contracts",
-- "version": "0.33.0",
++ "version": "0.33.1",
"description": "Machine-readable contracts for the OpenVibe network: schemas, manifests, ids, error envelope, capability checks.",
"main": "index.js",
"types": "generated/typescript/index.d.ts",