openvibers/openvibe.contracts AGENTS.md
AGENTS.md
AGENTS.md — OpenVibe.Contracts
Project overview
The machine-readable contract layer of the whole OpenVibe network: schemas, ids, the HTTP/error
envelope, capability checks, service/namespace/topic manifests, the staff capability map and the
compatibility aliases. A library, not a service: no runtime, no database, no ports, no deploy.
- Package
openvibe-contracts,main[index.js](index.js), version in [package.json](package.json)
(currently0.410.0, released as the git tagv0.410.0). - Every service pins a release tarball and verifies service/app tokens with
serviceAuthin
production; the service repositories runopenvibe-contracts-checkand the pin-drift check in CI. - Scale at this release: 1261 schemas in [contracts/catalog.json](contracts/catalog.json), 67 service
manifests, 523 capability manifests, 14 namespace manifests and the staff map.
What it owns
- Contract IDs, semantic versions, owners, visibility and deprecation state.
SubjectRef(user|guest|service|app|mod|system+ stable id) and the legacy identity map shape.- The request/error envelope:
traceparent,X-OpenVibe-Request-Id,Idempotency-Key, RFC 9457
problem details, resourcerevision/ETag. - The capability contract (id, owner, input/output schema, permissions, resource constraints, quota
class, events), namespace and topic manifests, and compatibility aliases/deprecations. - Service manifests (what each service runs, its routes and events) and the staff capability map.
- Generated JSON Schema, TypeScript and OpenAPI artifacts, and the estate map.
Not owned: any runtime behaviour, a database, identity issuance (Network), or the implementation of a
capability (the owning service).
How a service consumes it
const contracts = require('openvibe-contracts');
contracts.validate('identity.subject-ref@1', { type: 'user', id: 'usr_…' }); // { valid, errors }
contracts.ids.newId('user'); // usr_<ULID>
contracts.http.problem(403, 'capability.denied'); // RFC 9457 body
contracts.capabilities.check(claims, 'media.object.read', { namespace: 'live' });
contracts.resource.parse('ovrn:media:prj_…:object/med_…');
serviceAuth.requireCapability(...) judges a request that presents a Bearer token on that token
alone; a bad token is never rescued by a legacy header. It verifies RS256, issuer, audience and
expiry, and grants a capability only by exact id or a family.* grant. Production services must use it.
Repository map
- Public API: [index.js](index.js) —
catalog,resolve,validate,assertValid,schema,
ids,http,capabilities,services,products,serviceAuth,modules,tools,zones,
usage,resources,staff,openapi. - Implementation: [lib/](lib/) —
registry.js(catalog loading/resolution),ids.js,http.js,
capabilities.js,services.js,products.js,service-auth.js,modules.js,tools.js,
zones.js,usage.js,resources.js,staff.js,openapi.js,money-reasons.js. - Schemas: [contracts/](contracts/) grouped by area (
actor/,agent/,ai/,bench/,billing/,
blog/, …), indexed by [contracts/catalog.json](contracts/catalog.json). - Fixtures: [fixtures/](fixtures/) — each contract has
valid/andinvalid/examples. - Manifests: [manifests/](manifests/) — services, capabilities, namespaces, topics, policy
(manifests/policy/staff-roles.jsonis the one source for staff gates). - Compatibility: [compatibility/](compatibility/) —
aliases.json,deprecations.json,
corrections.json,capability-schema-gaps.json,compat.js. - Generated: [generated/](generated/) —
json-schema/,typescript/,openapi/; never hand-edit. - Scripts: [scripts/generate.js](scripts/generate.js), [scripts/compat.js](scripts/compat.js),
[scripts/estate.js](scripts/estate.js), [scripts/docs-currency.js](scripts/docs-currency.js). - Service check: [bin/check-service.js](bin/check-service.js) →
openvibe-contracts-check. - Governance/ADRs: [governance/](governance/), [docs/adr/](docs/adr/), [docs/](docs/).
Commands
npm ci
npm test # every check in test/ (schemas, fixtures, manifests, compatibility, docs)
npm run generate # regenerate generated/json-schema, generated/typescript, generated/openapi
npm run estate # regenerate docs/ESTATE.md and manifests/repositories/
node scripts/estate.js --check # fail on drift against the estate checkouts
node scripts/docs-currency.js <root> # check every checkout's README/STATUS against its code
node --check <file.js>
The repository is consumed, never started; there is nothing to npm start.
Adding or changing a contract (the release round)
- Add the schema under the owning area in [contracts/](contracts/) with its
$id, version, owner and
@1/next-version id, and add it to [contracts/catalog.json](contracts/catalog.json). - Add [fixtures/<id>/valid/](fixtures/) and
invalid/examples; the suite validates both. - Add or update the capability/namespace/service manifest if the change introduces a capability.
npm run generateand commit the regenerated files together with the schema (never by hand).- Raise
package.json's version above main's newest version, add the CHANGELOG entry, commit and tag
vX.Y.Z.scripts/compat.jsbases its comparison ongit describe HEAD^, so a release needs its
own commit after the merge — do not tag a merge commit that main has moved past. - Consumers bump their pinned tarball tag; a new capability id must ship here before the service
that uses it, or the service refuses every caller (unknown ids fail closed).
Versioning and compatibility
- Schemas and capabilities are semver'd: additive fields/ids are a minor, a breaking shape is a new
@2contract (never an edit to@1), with a migration path and a deprecation entry. - [compatibility/](compatibility/) records aliases, deprecations and corrections; the suite checks them
against the catalog. - A released tag is immutable: do not rewrite or re-tag it, and do not edit a released schema in place.
Security
serviceAuthverifies the token alone (no legacy header rescue), RS256, issuer, audience and expiry;
capabilities are exact-id orfamily.*.- The staff capability map ([manifests/policy/staff-roles.json](manifests/policy/staff-roles.json)) is
the single source for staff gates; do not duplicate it in a service. - Schemas carry no secrets and no personal data; fixtures use fake values, and gitleaks scans history
in CI. Dependencies areajvandajv-formatsonly — adding one needs a reason.
Tests
npm test runs [test/run.js](test/run.js), which loads every test/*.test.js check (the run aggregates
sub-scripts for schema validation, fixtures, capability schemas, manifests, compatibility, changelog
history, docs currency, estate). It is plain Node assert, no framework. A check that cannot run
prints <label>: skipped (<why>); --strict (or OV_TEST_STRICT=1) makes a skip fail. npm run
estate and node scripts/docs-currency.js <root> are separate drift checks used in CI. ov test runs
the harness's shard.
Pitfalls
- Never hand-edit [generated/](generated/). Run
npm run generate; a generated diff you cannot
reproduce is a bug. - Every schema needs fixtures and a catalog entry. A schema outside
catalog.jsondoes not exist to
consumers; a fixture-less schema is untested. - Do not reuse or renumber an id. Consumers key on the exact id and version; a change is a new
version, a deprecation and an alias where needed. - Do not tag before the release commit.
scripts/compat.jslooks atHEAD^; tag after the version
commit, and bump in the same commit as the generated output. - A capability must be released before a service guards a route with it; an unknown id is refused,
never allowed. docs/ESTATE.mdandmanifests/repositories/are generated from the estate checkouts; run
npm run estateand commit the result, or--checkfails.scripts/docs-currency.jstrusts the checkouts it is given; run it with the estate root, not a
single repository, when checking a pin round.serviceAuthis deliberately strict. Do not add a compatibility shim that accepts an unsigned or
wrong-audience token to make an old caller work.
Documentation
- [README.md](README.md) — the API, contract groups, versioning and purpose.
- [docs/ESTATE.md](docs/ESTATE.md) — the generated estate map.
- [docs/adr/](docs/adr/) — every architecture decision (ADR-012 money, ADR-019 publishing, ADR-035
data, ADR-043 Bot, ADR-044 Actor, ADR-050 Codes, ADR-057 Connect, …). - [docs/sharing.md](docs/sharing.md), [docs/locker.md](docs/locker.md),
[docs/space-problem-codes.md](docs/space-problem-codes.md). - [governance/](governance/) — contract governance process.