Published in openvibe-contracts v0.97.0 (docs/adr/ADR-046-universal-adaptive-fabric.md), rendered as is.

ADR-046: The universal adaptive fabric — offers, requirements, placement, trust classes and signed plans

Status: Proposed 2026-10-03 (plan track T1 step 3, for the owner's review). Builds on ADR-034 §5 (control plane and data plane; cells) and ADR-042 (the events fabric, the first placed workload class).

Context and current evidence

Decision

1. Offers, requirements, a result and a plan

Every placer is openvibe-sdk/placement. A service states requirements and reads results; it does not rank offers.

2. Health and cost

An offer whose health is neither up nor degraded is excluded before ranking (excluded()); provider state and rate cards then price the remaining candidates (marginalCost, forecast).

3. Telemetry and usage

4. Trust classes

resource-offer.trust is one of five classes, in this order; workload-requirements.trust lists the classes allowed to run the work:

| Class | Meaning | | --- | --- | | first-party | Hosts and accounts the OpenVibe network operates itself (its own servers and provider accounts). | | user-owned | A person's own node or machine (an OpenVibe.Node they run), offered for their own workloads. | | partner | An organisation under a written agreement with the network, bound by its data and uptime terms. | | community | Capacity volunteered by community members, without a contract; best effort, no private data. | | external | A third-party provider used through its public API under its own terms (a cloud or AI vendor). |

user-owned is not in the default trust set. When a requirement names no trust, the eligible classes are first-party, partner, community and external (the SDK's TRUST_ORDER). A user-owned offer is eligible only for a workload whose requirements list "user-owned" explicitly. Adding the class to the contracts therefore widens no existing caller's eligible set, and the SDK must not add it to its default list.

5. Worker capability names a Node advertises

An OpenVibe.Node that runs jobs advertises one worker:<class> capability in its resource-offer.capabilities for each platform.runtime-class@1 class it runs: worker:function (a declared function artifact) and worker:code (submitted code in a sandbox) today, and worker:browser, worker:linux, worker:desktop and worker:gpu as Node gains them. These six names are reserved for the Node job worker ($defs.reservedWorkerCapabilities in platform.resource-offer@1); every other worker: name (worker:ffmpeg, worker:ai-gpu) is an ordinary capability. A requirement asks for a class by listing the same name in its capabilities.

6. Control plane and data plane

7. The reference consumer

T6 (OpenVibe.AI) is the reference consumer: it states ai.run requirements, places each run across first-party nodes, external AI providers and, when the request names it, the person's own user-owned node, and records a placement result, telemetry and usage samples for every run. Other services adopt the fabric after it.

Consequences

Open questions for the owner

  1. May a user-owned node run other users' workloads (as a community-style contributor), or only its owner's? Until answered, only its owner's, and only when the requirement names user-owned.
  2. What is the consent and revocation rule for a user-owned node: how its owner opts each workload class in, how they withdraw (immediately, or after running jobs drain), and what the placer does with work in flight when consent is revoked?

What this ADR does not claim