Skip to content

How a check runs

The same path every time, whichever provider is involved.

ConfigResolver ──> Adapter#fetch ──> Adapter#normalize ──> ProviderFetchRun ──> Projector

                                                            EntityCheck

1. Resolve the configuration

ProviderFetchRuns::ConfigResolver decides, for a given check type and entity, which provider is used, what the lookup identifier is, which adapter runs, and how the result should be projected.

This is where preconditions are enforced: an other-registrations check for a passport-only person is refused here with an explicit message, rather than sent and failed.

2. Fetch

The adapter calls the provider. Clients build the request, apply credentials from configuration, and raise a typed error on failure. Every provider client's Error descends from a common Providers::Error, which is what lets the capture step catch them all — including providers added later, without anyone remembering to extend a list.

3. Normalise

The adapter turns the provider's shape into Verity's. Normalisation is deliberately conservative:

  • Missing is nil, not a default
  • An empty collection means the provider said it was empty, not that we did not ask
  • A positive claim requires a positive signal in the payload

4. Capture

ProviderFetchRun.capture! records the run either way:

OutcomeRecorded
SuccessRaw response, normalised summary, sanitised request/response snapshot, succeeded
FailureError message and class, whatever snapshots exist, failed

Credentials are filtered from the snapshot before storage.

5. Project

Some checks write into Verity's own records. The commercial registration projector fills in legal name, status, dates, activities, parties and relationships. Others — commercial contract, employment, other registrations — are normalisation-only and project nothing: their value is the evidence itself.

6. Publish the result

The check exposes a sanitised public result: the provider's payload with credentials and internal keys stripped. This is what the entity page renders and what the API returns.

Idempotency and reuse

Each run carries a request fingerprint, so a repeated identical call can be recognised. Runs are succeeded, reused or failed; both of the first two count as evidence.

Adding a provider

See Adding a provider check.