verified is a conclusion, not a trust class. There is no trust class named verified, and no evidence class entitles a call to that conclusion on its own — a plan’s completion predicate has to name the specific (claim, trust) pair that satisfies it.
The five trust classes
Obol assigns trust from the configured route and the evidence source. An upstream payload cannot select or upgrade its own class, and neither can a worker, a remote MCP server, or a catalog broker.
Two asymmetries in that table are deliberate.
Only
gateway_observed and vendor_signed may contradict. A hostile or broken federated upstream must not be able to raise a customer-visible alarm about a real effect. Everything below that line can fail to prove a claim; it cannot disprove one.
untrusted can do neither. Schema validation rejects any completion predicate that would let untrusted evidence reach verified, so this is not a runtime convention you can configure around — it is refused at publication.
Which tier reaches which class
Trust is derived per evidence source, not per stage, so one receipt can carry gateway-observed transport facts beside connector-attested derived fields without either laundering the other (ADR-0025). The trusted-worker column is the ADR-0024 target, not today’s behavior. That protocol is unimplemented and no worker deployable exists; on the shipped ADR-0014 pathWorkerExecutor stamps connector_attested on the whole observation, so its transport
facts do not reach gateway_observed — the gap ADR-0025’s per-source trust exists to
close. See Trusted workers.
An MCP readback is
broker_attested even against an Obol-custodied connection, because an MCP server is by construction an authenticated intermediary rather than the originating vendor, and Obol validated no vendor signature there.
The contract above is wider than what the runtime currently admits. Readback stages are admitted only on a native, Obol-custody, OpenAPI connection; MCP and broker readbacks are rejected at admission. See per-tier limits.
What this means for a federated route
A federated connector executes through a catalog broker that holds the customer’s vendor credential and constructs the vendor request. Obol did not observe the hop, so:- A federated read concludes
not_required— reads are not verified because there is no effect to prove. - A federated write concludes
inconclusive. Its immediate facts areuntrusted, which cannot satisfy the authoritative-trust check, andbroker_attestedwebhook evidence still has to satisfy a completion predicate that names it. - A federated route can never read
verified, and nevercontradicted.
Where the assignment happens
The gateway normalizes each executor’s result into a non-serializableDispatchObservation carrying dispatch state, evidence trust, the numeric vendor status, safe ids, a response digest, and temporarily selected evidence. A deterministic in-process verifier turns that into the receipt’s verification summary. There is no I/O, no clock, no randomness, and no policy lookup in the verifier (ADR-0019).
Workers return a bounded, versioned wire report that the gateway converts into that observation. A worker cannot declare a call verified on any path. ADR-0024 additionally requires that it never see a vendor credential and never call a vendor; that protocol is unimplemented, and the shipped path still hands the credential over (ADR-0014). No worker deployable exists to exercise either.
Readback probes
A readback stage carries a closed, taggedReadbackProbe union restricted to transports the gateway already speaks: http (a GET or HEAD) and mcp (a tools/call on a bundle-declared read tool). Database, message-broker, filesystem, gRPC, and object-store probes are refused permanently, not deferred — reading a queue means consuming it, which competes with the customer’s real consumer.
A probe never carries a host, URL, or connection string. It names a probe_target_id resolved only against the pinned bundle, and its inputs are restricted to:
- the invocation’s safe upstream id,
- a bundle-authored literal, or
- for HTTP path and query parameters only, a JSON Pointer into the canonical arguments that resolves to a scalar.
Proving a deletion
An HTTP probe declares which statuses constitute a decisive negative for its resource, and only404 and 410 are admissible (ADR-0035). A response matching one of them is an observation the verifier evaluates, not an errored probe. Any other non-success status is an errored probe and resolves assertions to missing.
403 means the caller may not look, 401 that it did not authenticate, 422 that the request was malformed, and a 5xx that the vendor failed. Each is consistent with the resource being intact, so none may be declared. An absent assertion is legal only on a delete effect.
Delete readback stage
Screening a broker’s response
The gateway’s federated connect-session hop asks Nango or Composio to open a hosted authorization link, and reads exactly one value out of the answer: the URL to send the operator to. That response is screened for authority-shaped keys at any depth —target, policy, evidence, receipt, idempotency, idempotency_key, retry, credential — and the call fails if one is present. Every other field is ignored (ADR-0038).
The distinction matters. Refusing a body because a vendor added a benign field couples every federated connection in the fleet to that vendor’s changelog and buys no security. Refusing a body because a broker tried to assert authority is invariant 9 enforced: a broker that offers Obol a receipt, a trust level, a policy decision, a target, or an idempotency key is confused or hostile, and that is worth failing on rather than parsing and quietly filtering.
Mutations with no evidence path
Some vendors offer nothing to verify against: an empty200 on success, no read-by-id endpoint, and no signed webhook any reviewed signature profile can express. A rule that forbids saying so produces fabricated assertions — an http_status == 200 check against an accepted range of 200..=299 proves nothing and yet passes, which is worse than an empty claim.
So a mutation may declare no_evidence with a closed reason (ADR-0036):
The rules are validated:
no_evidence is legal only on a mutation, a tool declaring it must declare verification: none, and the reason must come from the enum. Such a tool concludes permanently inconclusive — never verified, never contradicted — which is the honest verdict. The connector UI has to render it at connect time.
Related
Connector tiers
Native, trusted worker, and federated, and what each one can prove.
EffectSpec
The required per-tool contract that declares assertions and evidence policy.