> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trdrs.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Provider self-check

> Prove your provider adapter follows the contract, before anyone connects a real account to it.

This is a different ruleset from the [API-consumer conformance](/partner-platform/conformance/requirements).
That one measures an integration CALLING the trdrs API. This one measures a provider service
IMPLEMENTING the provider contract — the thing an adapter developer writes so that trdrs can reach a
venue.

You can run it before you have a vendor account, a certificate, or a network. The reference provider
in this repository implements the contract exactly, and the suite passes against it; run the suite
against your own service and the differences are your work list.

## What it measures

Fourteen rules. Each one exists because getting it wrong loses or duplicates somebody's trade, and
the reason travels with the result — a provider that only learns *what* failed tends to make the
check pass rather than make the behaviour right.

| Rule                            | What it requires                                                                                                                                          |
| ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `manifest`                      | The manifest parses under the contract parser and does not declare execution without generation fencing.                                                  |
| `grant_echoes_authority`        | A session grant repeats the connection, environment, scope and account it was asked for, so it cannot be replayed against another.                        |
| `acquisition_idempotent`        | The same acquisition request returns the same grant. A retrying reader must not hold two identities for one intent.                                       |
| `fencing_revokes_older`         | A higher generation revokes the older session. The loser of that race keeps a grant that still looks valid to it; you are the only place the truth lives. |
| `fencing_refuses_older_acquire` | A generation below the highest cannot acquire. Otherwise a restarted reader silently takes an account back.                                               |
| `payload_hash_verified`         | A command whose hash does not match its canonical body is refused. A mismatch means the bytes and the stated intent disagree.                             |
| `command_idempotent`            | The same command id and payload returns the same receipt, so a retry after a lost response recovers the first outcome instead of trading again.           |
| `command_conflict`              | The same command id with a *different* payload is refused. Two intents wearing one name; the first stands.                                                |
| `absence_is_not_rejection`      | A command you have no record of reads as no evidence, not as rejected. A caller reading absence as refusal submits the order again.                       |
| `events_ordered`                | Cursors and account sequences strictly increase.                                                                                                          |
| `events_resume`                 | Resuming after a cursor returns exactly the events after it — not one either side.                                                                        |
| `unknown_cursor_declared`       | An unrecognised cursor is declared, never replayed from zero. Starting again quietly is how a consumer re-applies a day of trading.                       |
| `coverage_only_when_complete`   | A snapshot page claims coverage only when it completes the account. A partial page claiming coverage makes an unfinished read look like proof of flat.    |
| `account_isolation`             | A session scoped to one account cannot read another. An account id is not a credential.                                                                   |

## Running it

```ts theme={null}
import { runProviderSelfCheck } from '@trdrs/reference-provider'

const evidence = await runProviderSelfCheck(
  async ({ method, path, query, body }) => {
    const url = new URL(path, 'https://your-provider.example.com')
    for (const [key, value] of Object.entries(query ?? {})) url.searchParams.set(key, value)
    const response = await fetch(url, { method, headers: { 'content-type': 'application/json' }, body: body ? JSON.stringify(body) : undefined })
    const text = await response.text()
    return response.headers.get('content-type')?.includes('event-stream')
      ? { status: response.status, stream: text.split('\n\n').filter(Boolean).map(frame => JSON.parse(frame.replace(/^data: /, ''))) }
      : { status: response.status, body: text ? JSON.parse(text) : undefined }
  },
  {
    connectionId: 'your-connection',
    environment: 'sandbox',
    authorizationRef: 'your-authorization',
    tradableAccountId: 'ACCOUNT-1',
    otherAccountId: 'ACCOUNT-2',
    order: { instrumentId: 'ES-MAR26', providerSymbol: 'ESH6', quantity: '1' },
  },
)
```

## The evidence

`runProviderSelfCheck` returns the artifact directly; write it to a file and it is the evidence
bundle. It never contains your `authorizationRef`.

```json theme={null}
{
  "suite": "provider-contract-v1",
  "providerVersion": "your-provider-v1",
  "passed": false,
  "skipped": ["coverage_only_when_complete"],
  "results": [
    { "id": "payload_hash_verified", "outcome": "fail", "detail": "a forged payload hash was accepted with 200", "why": "..." }
  ]
}
```

Three outcomes, and the third one matters:

* **pass** — the rule was observed to hold.
* **fail** — the rule was observed not to hold, with what was seen.
* **skipped** — the rule could not be attempted. No tradable account was supplied, or your account
  fits in one page so there was no partial page to check.

`passed` is true only when every rule passed. A skipped rule does not count toward it, because
certifying a provider for behaviour nobody observed is worse than reporting nothing at all.

The suite runs every rule even when the first one fails, and a provider it cannot reach at all comes
back as failures rather than a crash. One run should give you the whole list, not the first item on it.

## What it does not measure

It is not a certification and it is not a market. There is no book, no slippage and no latency
anywhere in the reference, and passing every rule says nothing about whether your venue fills the
way you expect under load. It says your service follows the contract's rules about identity,
ordering and evidence — which is the part that, when wrong, loses money silently.
