---
title: Public contract reference
description: Every public export of every @patronage/ads-sync entry point, with written contracts for the load-bearing functions.
---

This page lists every public export of every `@patronage/ads-sync` entry point. Each export has a contract. The load-bearing functions get inputs, outputs, invariants, failure modes, and the tests that pin them.

For working compositions, run [`configure-connections.ts`](https://github.com/patronage/agentic-marketing-connectors/blob/main/packages/ads-sync/src/tutorials/configure-connections.ts), [`prepare-bounded-run.ts`](https://github.com/patronage/agentic-marketing-connectors/blob/main/packages/ads-sync/src/tutorials/prepare-bounded-run.ts), and [`run-historical-comparison.ts`](https://github.com/patronage/agentic-marketing-connectors/blob/main/packages/ads-sync/src/tutorials/run-historical-comparison.ts).

## entry points

| entry point | purpose |
| --- | --- |
| `@patronage/ads-sync` | Configuration, protocol, provider registry, canary, comparison, and SQL surface |
| `@patronage/ads-sync/instance` | Ads Sync Reference Deployment instance spec and mode transitions |
| `@patronage/ads-sync/providers` | Provider registry and provider-neutral dispatch |
| `@patronage/ads-sync/google-ads` | Google Ads provider module and configured catalog |
| `@patronage/ads-sync/google-search-console` | Google Search Console provider module, catalog, and token builder |
| `@patronage/ads-sync/meta-ads` | Meta Ads provider module, catalog, and token builder |
| `@patronage/ads-sync/sql` | Control-store and reporting SQL text |
| `@patronage/ads-sync/credentials` | The tenant credential vocabulary: roles, handles, and placements |
| `@patronage/ads-sync/run` | The Qualified Run seam |

The package stores nothing itself. Storage identity follows ADR 0011: Cloudflare-native by identity, Postgres-generic by contract. Secret custody follows the Custody Gate in `docs/adr/0047`: the run seam never reads a deployment environment field itself.

## contracted functions

### `compileDestinationInput`

Compiles source connector stdout into the exact message stream the destination container accepts.

| aspect | contract |
| --- | --- |
| Inputs | `text`: source stdout. Optional `limits` with `maxDestinationInputBytes` and `maxLines`. |
| Outputs | A `DestinationInput` with `messages`, `droppedLines`, and an `AirbyteMessageSummary`. |
| Invariants | Keeps `RECORD` messages, `STATE` messages, and `TRACE` messages whose trace type is `STREAM_STATUS`. Keeps source order. Re-serializes each kept message. Ends a non-empty result with one newline. Counts every other line, and every unparsable line, in `droppedLines`. |
| Failure modes | Throws when the compiled byte count exceeds `maxDestinationInputBytes`. Throws when the non-empty line count exceeds `maxLines`. It never truncates. |

Contract tests: `compileDestinationInput` > "keeps only RECORD, STATE, and STREAM_STATUS trace messages in source order", "returns an empty destination input for empty source stdout", and "throws instead of truncating when the compiled input exceeds a limit" in `src/public-contract.test.ts`; `compileDestinationInput` > "passes record, state, and stream status trace messages to the destination" and "enforces destination input byte and line limits before writes" in `src/core.test.ts`.

### `enforceTextArtifactLimits`

Rejects a text artifact that is above the configured bounds.

| aspect | contract |
| --- | --- |
| Inputs | `label` for the error text, `text`, and `limits` with `maxSourceStdoutBytes` and `maxLines`. |
| Outputs | None. The function returns `undefined` when the text is inside both bounds. |
| Invariants | Measures UTF-8 bytes, not characters. Counts only non-empty lines. Text at the exact limit passes. |
| Failure modes | Throws an `Error` that names the label, the measured size, and the limit. One byte or one line above a limit is enough to throw. |

Contract tests: `enforceTextArtifactLimits` > "accepts text at the exact byte and line limits", "throws with the label when one byte or one line exceeds the limit", and "counts UTF-8 bytes, not characters" in `src/public-contract.test.ts`; "enforces source artifact limits" in `src/core.test.ts`.

### `committedStateAfterSuccessfulDestinationWrite`

Selects the state the control store may commit after the destination write succeeded.

| aspect | contract |
| --- | --- |
| Inputs | `destinationStdout`, then source stdout. The second argument is accepted and ignored. |
| Outputs | An array with the latest state message per stream descriptor, or `null`. |
| Invariants | Reads state only from destination stdout. Keeps the last state for each stream descriptor. Global and legacy states each collapse to one entry. |
| Failure modes | Returns `null` when the destination emitted no state, even when the source emitted state. Non-JSON destination lines are skipped, not thrown. |

`committedStateAfterDestinationResult` wraps this function with the write outcome. It returns `null` for a failed write.

Contract tests: `committedStateAfterSuccessfulDestinationWrite` > "returns the last destination STATE and ignores source stdout" and "returns null when the destination emitted no STATE, even if the source did" in `src/public-contract.test.ts`; `committedStateAfterSuccessfulDestinationWrite` > "prefers destination-emitted state after a successful write" and "does not fall back to source state when the destination emits no state", plus `committedStateAfterDestinationResult` > "does not expose state for commit when the destination write failed", in `src/core.test.ts`.

### `destinationConfigForProvider`

Routes one provider's destination write to that provider's isolated Airbyte schema.

| aspect | contract |
| --- | --- |
| Inputs | The destination `config` value, a Supported Provider id, and an optional `schema` override. |
| Outputs | A structured clone of the config with `schema` set. |
| Invariants | The default schema is the provider module default. An explicit schema wins over the default. The input object is never mutated. |
| Failure modes | A non-object config comes back unchanged, without a schema field. An unknown provider id throws when the `schema` argument is omitted, because the default-schema lookup fails. |

Contract tests: `destinationConfigForProvider` > "returns a copy with the provider default schema and leaves the input unchanged", "uses an explicit schema over the provider default", and "returns a non-object config unchanged" in `src/public-contract.test.ts`; `destinationConfigForProvider` > "routes provider writes to provider-specific Airbyte schemas" in `src/core.test.ts`.

### `supportedImageVersions`

The pinned container images the Ads Sync Reference Deployment runs.

| aspect | contract |
| --- | --- |
| Inputs | None. It is an `as const` literal record; the package does not freeze it at runtime. |
| Outputs | One `destination` image plus one image per Supported Provider id. |
| Invariants | Every value pins a digest with `@sha256:`. Each provider value equals that provider module's `sourceImage`. |
| Failure modes | None at runtime. A drifted pin fails the package tests, not a call. |

Contract tests: "supported image versions" > "pins every image by digest" and "lists one destination plus the source image of every Supported Provider" in `src/public-contract.test.ts`; "exports curated image versions for deployments to assert" in `src/core.test.ts`.

### `createQualifiedRunAdapter`

The Qualified Run entry point, from `@patronage/ads-sync/run`.

| aspect | contract |
| --- | --- |
| Inputs | One `QualifiedRunDependencies` object: `artifacts`, `containers`, `custody`, `connections.configuredCatalog`, and `sql`. Optional `limits`, `coldStart`, `runWindow`, `onSucceeded`, `onFailed`, `progress`, and `streamLeaseRefreshIntervalMs`. |
| Outputs | A `QualifiedRunAdapter` with exactly `prepare`, `acquireLease`, `readSource`, `compileDestinationInput`, `writeDestination`, `commitState`, `recordGeneration`, `finalizeSucceeded`, `finalizeFailed`, `releaseLease`, and `run`. `run` returns a `QualifiedRunSummary`. |
| Invariants | A source container must report the exact `connectorImage` and `wrapperVersion` pin before the seam uses it. State commits only after a successful destination write and a fresh lifecycle check. Every secret comes from the custody adapter, never from an environment object. Connector output, R2 persistence, destination-input compilation, and destination upload are streaming. Diagnostic lines are redacted while RECORD and STATE lines stay byte-identical. Every completed artifact has byte, line, message, and SHA-256 metadata; an interrupted upload is deleted. Artifacts above `DEFAULT_ARTIFACT_LIMITS` fail with an explicit bound. Failure text and warning logs are redacted, then bounded. |
| Failure modes | A wrong image pin throws `ContainerQualificationError` with reason `metadata_mismatch`, without retry. An unavailable container retries a bounded number of times, then throws with reason `unavailable`. A failed lifecycle check throws `RunLifecycleError` and skips the commit. A secret name outside the managed set throws `CustodyFenceError`. |

Contract tests: `createQualifiedRunAdapter` > "exposes the run entry point and every documented phase" and "defaults artifact limits to the documented bounds" in `src/public-contract.test.ts`; `createQualifiedRunAdapter` covers state ordering, lifecycle refusal, image qualification, bounded failures, custody, artifact bounds, redaction, and interrupted-upload cleanup in `src/run.test.ts`; `transformArtifactStream` covers chunk-boundary preservation, deterministic manifests, large destination compilation, and individual-line bounds in `src/run-artifacts.test.ts`.

## configuration

`defineAdsSyncConfig()` parses an object with a required, non-empty `connections` array.

| connection field | input | default or effect |
| --- | --- | --- |
| `catalog` | required unknown value | Configured Airbyte catalog |
| `catalogRef` | optional non-empty string | Generated `ads-sync.config.ts#<connection>.catalog` reference |
| `connectionId` | optional non-empty string | `<provider>_default` |
| `displayName` | optional non-empty string | Provider display name plus stream group |
| `destinationSchema` | optional non-empty string | Provider default Airbyte schema |
| `provider` | `google_ads`, `google_search_console`, or `meta_ads` | Required |
| `reportingEnabled` | boolean | `true` |
| `scheduleCron` | `null` | `null` |
| `scheduleEveryMinutes` | positive integer or `null` | `360` |
| `selectedStreams` | optional array of non-empty strings | Streams found in the catalog |
| `sourceConfigSecret` | required non-empty string | Secret name, never a credential value |
| `stateSecret` | optional non-empty string | Curated provider state secret name |
| `streamGroup` | optional non-empty string | Provider default stream |
| `streamName` | optional non-empty string | Provider default stream |

`syncConnectionDefinitionFromConfig()` also requires the resolved source configuration value. It returns a `SyncConnectionDefinition` with source identity and hashes, catalog hash and reference, schedule, selected streams, state reference, and destination schema. `validateDestinationSchemaIsolation()` rejects two enabled connections that share a destination schema.

## curated provider definitions

| provider | source image | default schema | backfill policy | rate limit policy |
| --- | --- | --- | --- | --- |
| `google_ads` | `airbyte/source-google-ads:6.1.0@sha256:dea39deedba0a095f60159d808dfb47fa778e304846396d2ab2f04c951b480ed` | `airbyte_google_ads` | 7-day steps, 8 windows per run | none |
| `google_search_console` | `airbyte/source-google-search-console:2.1.9@sha256:3ee78d227a25ec01a31b9f131b1b8d80afd6e3aaf0c0c2f1b09c7973190465b3` | `airbyte_google_search_console` | 30-day steps, 4 windows per run | none |
| `meta_ads` | `airbyte/source-facebook-marketing:5.2.11@sha256:4d6c916b29862ded4b5b94feea0b8ef75899f34c364e4884312e50414b6d447c` | `airbyte_meta_ads` | 3-day steps, 4 windows per run | stop on code 17, 3600-second cooldown |

The pinned destination image is `airbyte/destination-postgres:3.0.13@sha256:0b310bd46ba0e006757ea3dc1d3b8ef8e3bcf51c3a96f5460a836653b5ac4f4c`. `defineProvider()` is an advanced definition helper. Calling it does not register a provider, add a catalog, build a Container image, or add a reporting view. The shipped supported set is Google Ads, Google Search Console, and Meta Ads.

## configured catalogs and access-token builders

Each provider module ships one fully configured catalog and, where the pinned image allows it, one access-token-only source-config builder. The catalog and builder exports are reachable through the provider entry points only. The root `@patronage/ads-sync` entry point does not re-export them.

| provider | catalog export | builder export |
| --- | --- | --- |
| `google_ads` | `googleAdsConfiguredCatalog` from `@patronage/ads-sync/google-ads` | none |
| `google_search_console` | `googleSearchConsoleConfiguredCatalog` from `@patronage/ads-sync/google-search-console` | `googleSearchConsoleAccessTokenSourceConfig` |
| `meta_ads` | `metaAdsConfiguredCatalog` from `@patronage/ads-sync/meta-ads` | `metaAdsAccessTokenSourceConfig` |

Google Ads has no access-token builder. Its pinned source image requires OAuth refresh-token credentials.

`configuredCatalogForProvider(provider)` returns the same catalog object the provider module ships. `accessTokenSourceConfigForProvider(provider, input)` builds the source configuration for one provider. `accessTokenSourceConfigProviders` lists exactly `google_search_console` and `meta_ads`, and `AccessTokenSourceConfigProvider` is the matching type. Both dispatch helpers come from `@patronage/ads-sync/providers`.

The builder input is an `AccessTokenSourceConfigInput`:

| field | contract |
| --- | --- |
| `accessToken` | Bearer access token. The builder copies it into the source configuration. |
| `accountIds` | Provider account identity. Ad account ids for Meta Ads, such as `act_0000000000`. Site URLs for Google Search Console, such as `https://example.org/`. |
| `startDate` | Required ISO `YYYY-MM-DD` date. |
| `endDate` | Optional ISO `YYYY-MM-DD` date. The bound is exclusive. |

Invariants: a builder never reads an environment variable or a secret store. A builder never contacts a provider API. A shipped catalog carries no run generation, so `generation_id`, `minimum_generation_id`, and `sync_id` are all zero until a run stamps them.

Failure modes: a `startDate` or `endDate` that is not an ISO date throws. `accessTokenSourceConfigForProvider()` throws for a provider that ships no builder, so a caller never sends a configuration the pinned image rejects.

The Google Search Console token-only configuration requires the derived image built with `GSC_AUTH_MODE=access_token`. See `deploy/images/patch-gsc-manifest-auth.py`. The Meta Marketing API source reads one long-lived access token, so its pinned image needs no patch.

The catalog types are `ConfiguredCatalog`, `ConfiguredCatalogStream`, and `AccessTokenSourceConfigInput`. They are declared in the provider contract and re-exported from `@patronage/ads-sync/providers` and each provider entry point (`google-ads`, `google-search-console`, `meta-ads`).

Each provider entry point also owns the non-secret source-identity wire shape persisted in a Sync Connection row. Callers supply semantic manifest values; the builder emits the provider keys:

| provider | identity builder | input | output |
| --- | --- | --- | --- |
| `google_ads` | `googleAdsSourceIdentity` | `customerId`, optional `managerCustomerId` | `customer_id`, `login_customer_id` |
| `google_search_console` | `googleSearchConsoleSourceIdentity` | `siteUrls` | `site_urls` |
| `meta_ads` | `metaAdsSourceIdentity` | `accountIds` | `account_ids` |

These builders copy non-secret account identifiers only. They do not read a client manifest, environment variable, secret store, or provider API.

## canary request

`parseAdsSyncCanaryRequest()` accepts exactly:

| field          | contract                                               |
| -------------- | ------------------------------------------------------ |
| `connectionId` | lowercase identifier matching `^[a-z][a-z0-9_]{2,63}$` |
| `provider`     | `google_ads`, `google_search_console`, or `meta_ads`   |
| `windowStart`  | string accepted by the JavaScript `Date` parser        |
| `windowEnd`    | accepted date string after the start                   |

The window must be no longer than 24 hours. `adsSyncCanaryRequestSha256()` hashes the canonical request with ISO-normalized dates.

## storage and state

`controlSchemaSql` defines Postgres runtime tables for Sync Connections, Backfill Plans, Sync Run Windows, runs, stream runs, committed state, artifacts, catalog snapshots, errors, generations, and stream leases. The package emits SQL and primitives; the operator owns migration authorization and execution.

`artifactKeys()` returns a prefix and keys for configured catalog, source stdout and stderr, optional state input, destination input, destination stdout and stderr, and summary. The package does not write R2 objects. `committedStateAfterDestinationResult()` returns no state after a failed destination write.

## historical comparison

`runHistoricalComparisonGate()` reads provider rows and warehouse rows over the same bounded half-open window `[startDate, endDate)`. The provider's read spec chooses the entity grain, and neither grain is aggregated into the other:

- `campaign` (Google Ads, Meta Ads) reads `ads_sync_reporting.ads_campaign_daily` and covers impressions, clicks, spend, conversions, and conversion value at the account, campaign, and day grain.
- `query_page` (Google Search Console) reads `ads_sync_reporting.gsc_query_page_daily` and covers impressions, clicks, CTR, and average position at the exact property, search type, Pacific reporting date, query, and page grain. The comparison declares a `queryPageScope`, and both sides are bound to that same property and search type.

Missing rows, duplicate rows, failed tolerances, an unstable window, a declared source limitation, or a per-row data issue all result in `"review"`. At either grain, a row raises a data issue rather than being compared when it drops a dimension its identity needs or falls outside the window; a warehouse row the reporting view returned without a complete identity is reported the same way instead of failing the whole run. A `query_page` row raises one additionally when it falls outside the compared property and search type, or when its CTR is not its own clicks divided by its own impressions within the CTR tolerance.

Default absolute or relative tolerance is zero for impressions and clicks, `0.01` absolute or `0.001` relative for spend, conversions, conversion value, and average position, and `0.00001` absolute or `0.001` relative for CTR. A known delta needs an exact identity, date, metric, and reason; the identity is account and campaign at the `campaign` grain, and property, search type, query, and page at the `query_page` grain.

## reference deployment

The nested `packages/ads-sync/deploy` workspace is private to npm packaging but present in the public repository tree. It is the Ads Sync Reference Deployment: one Worker, one Sync Connection from `ads-sync.config.ts`, one Cron trigger, and the four connector Container classes. Its Worker serves:

| operation | auth | local effect | remote effect | output |
| --- | --- | --- | --- | --- |
| `GET /health` | none | none | none | `{ ok: true, service }` |
| `GET /` | none | none | none | service name, the configured connection, route list, and supported provider summaries |
| `POST /runs` | bearer | writes `sync_runs`, `sync_schedule_ticks` | one Qualified Run in the background | `200 { result: "no_new_final_data", runId, watermark, horizon, readMode, orphanedRunIds }`, `200 { result: "already_active", runId, status, horizon, readMode, orphanedRunIds }`, or `202 { result: "queued", execution: "durable_object_alarm", runId, window, horizon, readMode, orphanedRunIds }` |
| `GET /runs` | bearer | reads | none | the last 20 runs plus the committed watermark |
| `GET /runs/:runId` | bearer | reads | none | one run, or `404` |
| Cron `0 6 * * *` (UTC) | Cloudflare | same as `POST /runs` | one Qualified Run | one row in `sync_schedule_ticks` per tick |

`POST /runs` and the Cron trigger run the same tick: plan one window from the committed watermark to the provider's Final-Data Horizon, hand the queued run to a Durable Object alarm (`RunDispatcher`, one object per Sync Connection), execute the Qualified Run through `@patronage/ads-sync/run`, and commit the watermark inside the seam's success transaction. Both entry points only plan; the alarm executes, so a run never depends on the request or the Cron invocation that planned it. `execution: "durable_object_alarm"` names that path in the `202` body. A tick is idempotent while a run is in flight: when a run of the connection is `queued` or `running`, `POST /runs` answers `200 { result: "already_active", runId, status }` with that run, records a `sync_schedule_ticks` row with `result = 'already_active'` and the in-flight `run_id`, and enqueues nothing. Just before the alarm starts the seam it re-reads the committed watermark; when the watermark moved after the plan, the run finishes as `no_new_final_data` (`error_type = 'stale_window'`) and starts no Containers.

Every tick first fails closed the orphans of earlier ticks. Liveness comes from the seam's stream lease, not from age: a run whose lease is still valid is never swept, whatever its age. A run still `queued` or `running` after 20 minutes that holds no unexpired lease has lost its executor; the tick marks it `failed` (`error_type = 'orphaned'`), releases its lease, and reports it in `orphanedRunIds`. `orphanedRunIds` is the only operator-visible evidence of that sweep. Bearer routes require `Authorization: Bearer <ADS_SYNC_RUNNER_TOKEN>` (the Ads Sync Deployment Token) and answer `503` when the secret is not set. The Worker has no migration, canary, or backfill endpoint; the [quickstart](/tutorial/quickstart) applies the schema with `psql`.

Its `check` command runs type checking, tests, and the public-import boundary check. Its `build` command performs a Wrangler deployment dry run after building the package. `dev` starts local Wrangler. `deploy` builds the connector images with Docker and publishes the Worker; it mutates Cloudflare resources and requires operator authorization.

## export index

Every export below is public. The docs test fails when one of them is missing from this page.

### `@patronage/ads-sync`

Configuration exports:

| export | kind | contract |
| --- | --- | --- |
| `adsSyncConnectionConfigSchema` | value | Zod schema for one declared connection. |
| `adsSyncConfigSchema` | value | Zod schema for the whole Ads Sync Declarative Config. |
| `AdsSyncConnectionConfig` | type | Parsed connection config, with defaults applied. |
| `AdsSyncConfig` | type | Parsed config object. |
| `AdsSyncConfigInput` | type | Config shape before defaults. |
| `defineAdsSyncConfig` | value | Parses a config input and throws on any schema violation. |
| `adsSyncConnectionsForProviders` | value | Filters parsed connections to the requested providers. |
| `syncConnectionDefinitionFromConfig` | value | Resolves one connection config plus its source config into a `SyncConnectionDefinition`. |
| `SupportedProviderDefinition` | type | Curated provider summary: images, schema, policies, and reporting views. |
| `defineProvider` | value | Identity helper that types a provider definition. It registers nothing. |
| `supportedProviderDefinitions` | value | Curated definition for each Supported Provider. |
| `supportedImageVersions` | value | Pinned destination and source images, each with a digest. |

Protocol and state exports:

| export | kind | contract |
| --- | --- | --- |
| `AirbyteMessageSummary` | type | Message counts, per-stream record counts, and record timestamps. |
| `ArtifactKeys` | type | Object keys for one stream run's artifacts. |
| `ArtifactLimitConfig` | type | Byte and line bounds for run artifacts. |
| `ArtifactManifest` | type | Size, counts, digest, and timestamps for one artifact. |
| `DestinationInput` | type | Compiled destination messages, dropped-line count, and summary. |
| `StateCommitInput` | type | Destination stdout, source stdout, and the write outcome. |
| `SyncConnectionDefinition` | type | One Sync Connection at an exact version. |
| `BackfillWindowDispatchAction` | type | One of `ignore`, `start`, or `wait`. |
| `backfillWindowDispatchAction` | value | Maps a Sync Run Window status and run id to a dispatch action. |
| `createRunId` | value | Builds a run id from an ISO timestamp and a random UUID. |
| `artifactKeys` | value | Builds artifact keys under a provider, stream, and run id prefix. |
| `summarizeAirbyteMessages` | value | Counts records, states, logs, traces, and invalid lines in a message stream. |
| `extractLastStateInput` | value | Returns the latest state per stream descriptor, or `null`. |
| `committedStateAfterSuccessfulDestinationWrite` | value | Selects committable state from destination stdout. See the contract above. |
| `committedStateAfterDestinationResult` | value | Returns `null` for a failed write, otherwise the destination state. |
| `progressEventPayload` | value | Adds an `emittedAt` timestamp to a progress event record. |
| `compileDestinationInput` | value | Compiles the destination message stream. See the contract above. |
| `artifactManifestForText` | value | Builds an `ArtifactManifest`, including a SHA-256 digest. |
| `enforceTextArtifactLimits` | value | Rejects an oversized text artifact. See the contract above. |
| `truncateTextArtifact` | value | Bounds a text artifact that must persist even when oversized, such as connector stderr: keeps the leading text inside `maxSourceStdoutBytes` and `maxLines` and ends a cut artifact with a marker line naming the dropped byte count. |
| `stampConfiguredCatalog` | value | Stamps generation ids onto a cloned catalog for one run. |
| `firstConfiguredStreamGeneration` | value | Reads generation metadata from the first stream, with a fallback. |
| `destinationConfigForProvider` | value | Sets the destination schema for one provider. See the contract above. |
| `sourceConfigStateKeyInput` | value | Redacts credential fields before a source-config fingerprint. |
| `defaultConnectionId` | value | Returns `<provider>_default`. |
| `defaultSyncConnectionDefinition` | value | Builds the default connection definition for a provider, catalog, and source config. |
| `configuredCatalogForSelectedStreams` | value | Filters a catalog to the selected streams; throws when one is missing. |
| `validateDestinationSchemaIsolation` | value | Throws when two enabled connections share an Airbyte schema. |

Provider contract and registry exports:

| export | kind | contract |
| --- | --- | --- |
| `AdsSyncProvider` | type | One of the three Supported Provider ids. |
| `AdsSyncProviderModule` | type | The interface every provider module implements. |
| `CampaignDailyRecord` | type | The normalized campaign-day row shape. |
| `CatalogDriftIssue` | type | A missing stream, missing field, or type change in a catalog. |
| `ProviderBackfillPolicy` | type | Window step days and maximum windows per run. |
| `ProviderRateLimitPolicy` | type | Optional stop code and cooldown seconds. |
| `ReportingFieldRequirement` | type | One required reporting field and its allowed types. |
| `ReportingStreamRequirement` | type | Required fields for one reporting stream. |
| `SourceIdentity` | type | String, string-array, or null identity fields for a source. |
| `SourceReportingWindow` | type | Optional reporting window overrides, including the Meta-only pair. |
| `isRecord` | value | Type guard for a plain object. |
| `isAdsSyncProvider` | value | Type guard for a Supported Provider id. |
| `normalizeCampaignDailyRecord` | value | Normalizes one provider record into a `CampaignDailyRecord`. |
| `ProviderDefinition` | type | Schema, display name, secret names, and stream name for one provider. |
| `providerDefinitions` | value | `ProviderDefinition` for each Supported Provider. |
| `providerModule` | value | Returns the provider module for one provider id. |
| `providerModules` | value | The provider id to module registry. |
| `requestedProviders` | value | Resolves `"all"`, one id, or an id array into provider ids; throws otherwise. |
| `sourceConfigForReporting` | value | Applies the reporting window to a cloned source config. |
| `supportedProviders` | value | The Supported Provider ids, in registry order. |
| `validateCatalogForReporting` | value | Returns the catalog drift issues for one provider catalog. |
| `googleAdsProvider` | value | The Google Ads provider module. |
| `googleSearchConsoleProvider` | value | The Google Search Console provider module. |
| `metaAdsProvider` | value | The Meta Ads provider module. |
| `GOOGLE_SEARCH_CONSOLE_QUERY_PAGE_STREAM` | value | The custom report stream name that joins query and page. |
| `GOOGLE_SEARCH_CONSOLE_QUERY_PAGE_DIMENSIONS` | value | The dimensions of that custom report. The source adds `date`. |

Canary exports:

| export | kind | contract |
| --- | --- | --- |
| `AdsSyncCanaryRequest` | type | Connection id, provider, and a parsed window. |
| `parseAdsSyncCanaryRequest` | value | Parses and bounds a canary request. See the canary section. |
| `canonicalAdsSyncCanaryRequest` | value | Returns the canonical request with ISO dates. |
| `adsSyncCanaryRequestSha256` | value | SHA-256 hex digest of the canonical request. |

Historical Comparison Gate exports:

| export | kind | contract |
| --- | --- | --- |
| `HistoricalComparisonMetric` | type | One of impressions, clicks, spend, conversions, conversions value, CTR, or average position. |
| `HistoricalComparisonMetrics` | type | The metric values one comparison row carries. |
| `HistoricalComparisonEntity` | type | `campaign` or `query_page`. |
| `HistoricalComparisonWindow` | type | Start date, exclusive end date, and optional stable-as-of date. |
| `HistoricalComparisonQueryPageScope` | type | The exact property and search type one `query_page` comparison covers. |
| `HistoricalComparisonCampaignIdentity` | type | Account, campaign, and the `campaign` entity tag. |
| `HistoricalComparisonQueryPageIdentity` | type | Property, search type, query, page, and the `query_page` entity tag. |
| `HistoricalComparisonIdentity` | type | Either comparison identity. |
| `HistoricalComparisonCampaignRow` | type | One account, campaign, and day row with metrics. |
| `HistoricalComparisonQueryPageRow` | type | One property, search type, Pacific reporting date, query, and page row with metrics. |
| `HistoricalComparisonRow` | type | Either comparison row. |
| `HistoricalComparisonTolerance` | type | Absolute and relative tolerance for one metric. |
| `HistoricalComparisonTolerances` | type | Tolerance per comparison metric. |
| `HistoricalComparisonKnownDelta` | type | An accepted delta with identity, date, metric, and reason. |
| `HistoricalComparisonSourceLimitation` | type | A declared reason one side's evidence is incomplete; any limitation disqualifies the gate. |
| `HistoricalComparisonInput` | type | Rows, window, provider, scope, tolerances, known deltas, and declared limitations. |
| `HistoricalComparisonRunInput` | type | Gate input plus the provider and warehouse read adapters. |
| `HistoricalComparisonStabilityPolicy` | type | Minimum stable days and policy name. |
| `HistoricalComparisonMetricResult` | type | Per-metric API value, warehouse value, deltas, identity, and pass flag. |
| `HistoricalComparisonMissingRow` | type | A row present on one side only. |
| `HistoricalComparisonDuplicateRow` | type | A duplicated identity and day. |
| `HistoricalComparisonWindowIssue` | type | A stability policy violation for the window. |
| `HistoricalComparisonDataIssue` | type | An empty, unusable, or out-of-scope row set from one side. |
| `HistoricalComparisonProviderReadSpec` | type | Entity, metrics, notes, reporting time zone, row limit, and window guidance. |
| `HistoricalComparisonProviderReadRequest` | type | Provider, entity, scope, read spec, and window given to the API adapter. |
| `HistoricalComparisonWarehouseReadRequest` | type | SQL, parameters, provider, entity, scope, and window given to the warehouse adapter. |
| `HistoricalComparisonProviderEvidence` | type | Provider rows plus any declared limitations. |
| `HistoricalComparisonWarehouseEvidence` | type | Warehouse rows plus any declared limitations. |
| `SourceComparisonArtifact` | type | The comparison sidecar artifact and its readiness recommendation. |
| `defaultHistoricalComparisonTolerances` | value | The default tolerance per metric. |
| `historicalComparisonEntityMetrics` | value | The compared metrics per entity grain, in report order. |
| `historicalComparisonStabilityPolicies` | value | Minimum stable days per provider. |
| `historicalProviderApiReadSpecs` | value | Entity, metrics, notes, reporting time zone, row limit, and window guidance per provider. |
| `GOOGLE_SEARCH_CONSOLE_COMPARISON_ROW_LIMIT` | value | The maximum rows one Search Analytics request returns per page. |
| `warehouseCampaignDailyComparisonQuery` | value | Returns the campaign reporting SQL and its parameters for one window. |
| `warehouseGscQueryPageDailyComparisonQuery` | value | Returns the query and page reporting SQL bound to one property, search type, and window. |
| `runHistoricalComparisonGate` | value | Reads both sides and returns a `SourceComparisonArtifact`. |
| `buildHistoricalComparisonArtifact` | value | Builds the artifact from rows already read. |
| `validateHistoricalComparisonWindow` | value | Returns the stability issues for a provider window. |
| `normalizeWarehouseCampaignDailyRow` | value | Normalizes one warehouse row; throws without a campaign id and date. |
| `normalizeWarehouseGscQueryPageDailyRow` | value | Normalizes one warehouse row; throws without property, search type, query, page, and date. |

SQL exports, also available from `@patronage/ads-sync/sql`:

| export | kind | contract |
| --- | --- | --- |
| `controlSchemaSql` | value | DDL text for the `ads_sync` control schema. |
| `controlSchemaCatalogSnapshotSql` | value | DDL text for catalog snapshot tables. |
| `reportingViewSql` | value | DDL text for the Ads Sync Reporting Contract views. |
| `requiredReportingViewTables` | value | Tables a deployment must provision before the views. It is currently empty. |

### `@patronage/ads-sync/instance`

| export | kind | contract |
| --- | --- | --- |
| `adsSyncInstanceModeSchema` | value | Zod enum for `provisioning`, `disabled`, `canary`, `backfill`, and `scheduled`. |
| `adsSyncConnectionProfileSchema` | value | Zod enum of the shipped connection profiles. |
| `adsSyncAccountsSchema` | value | Zod schema for a one-off instance descriptor's provider-account snapshot: Google Ads customer ids, Search Console properties, and Meta ad account ids. Shared-runtime tenants carry no such block. |
| `adsSyncInstanceSpecSchema` | value | Zod schema for a `schemaVersion` 4 instance spec: identity that rejects placeholder values, plus a required `accounts` snapshot. It is the only one-off descriptor shape; versions 1 and 2 are retired. |
| `AdsSyncInstanceMode` | type | One instance mode. |
| `AdsSyncConnectionProfile` | type | One shipped connection profile id. |
| `AdsSyncAccounts` | type | Parsed one-off instance provider-account snapshot. |
| `AdsSyncInstanceSpec` | type | Parsed instance spec. |
| `AdsSyncInstanceSpecInput` | type | Spec shape before defaults. |
| `defineAdsSyncInstance` | value | Parses a spec; throws on a duplicate connection profile, on a declared connection with no matching descriptor account, and on duplicate account ids within one provider list. |
| `resolveAdsSyncInstanceDeployment` | value | Derives Worker, Workflow, R2, cron, and secret names from a spec. |
| `AdsSyncModeTransitionEvidence` | type | Canary, backfill, and comparison evidence flags. |
| `planAdsSyncModeTransition` | value | Allows a supported mode transition with its required evidence; throws otherwise. |

### `@patronage/ads-sync/providers`

| export | kind | contract |
| --- | --- | --- |
| `providerModules` | value | The provider id to module registry. |
| `providerModule` | value | Returns one provider module by id. |
| `supportedProviders` | value | The Supported Provider ids. |
| `isAdsSyncProvider` | value | Type guard for a provider id. |
| `requestedProviders` | value | Resolves a provider selection into ids; throws on an unknown value. |
| `ProviderDefinition` | type | Schema, display name, secret names, and stream name for one provider. |
| `providerDefinitions` | value | `ProviderDefinition` per provider. |
| `sourceConfigForReporting` | value | Applies a reporting window to a cloned source config. |
| `ConfiguredCatalog` | type | A configured Airbyte catalog: a `streams` array. |
| `ConfiguredCatalogStream` | type | One configured stream: sync modes, cursor, primary key, generation fields, and the stream schema. |
| `AccessTokenSourceConfigInput` | type | Builder input: `accessToken`, `accountIds`, `startDate`, optional exclusive `endDate`. |
| `configuredCatalogForProvider` | value | Returns the configured catalog the provider module ships. |
| `AccessTokenSourceConfigProvider` | type | The provider ids whose module ships a token-only builder. |
| `accessTokenSourceConfigProviders` | value | Those provider ids at runtime. |
| `accessTokenSourceConfigForProvider` | value | Builds the token-only source config; throws for a provider without a builder. |
| `normalizeCampaignDailyRecord` | value | Normalizes one provider record through its module. |
| `validateCatalogForReporting` | value | Returns catalog drift issues for one provider catalog. |
| `tenantSourceTemplateForProvider` | value | Builds the non-secret half of a source config for one tenant. It is the inverse of `sourceIdentity`: the control row's account coordinate, read back into a config the pinned source image accepts. |
| `TenantSourceTemplateInput` | type | Builder input: the control row's `identity`, a `startDate`, and an optional exclusive `endDate`. |
| `campaignDailyPerformanceGaql` | value | The Google Ads custom query that fills the `campaign_daily_performance` stream. Re-exported from the provider module. |

### `@patronage/ads-sync/google-ads`

| export | kind | contract |
| --- | --- | --- |
| `googleAdsProvider` | value | The Google Ads provider module. |
| `ConfiguredCatalog` | type | A configured Airbyte catalog: a `streams` array. |
| `ConfiguredCatalogStream` | type | One configured stream: sync modes, cursor, primary key, generation fields, and the stream schema. |
| `AccessTokenSourceConfigInput` | type | Builder input: `accessToken`, `accountIds`, `startDate`, optional exclusive `endDate`. |
| `GoogleAdsSourceIdentityInput` | type | Semantic Google Ads manifest values: `customerId` and optional `managerCustomerId`. |
| `googleAdsConfiguredCatalog` | value | The configured catalog for the `campaign_daily_performance` custom query. It appends on full refresh. |
| `campaignDailyPerformanceGaql` | value | The custom query that fills that stream. `sourceConfigForReporting` rewrites its date predicate for a run window; the literal is the unwindowed default. |
| `googleAdsSourceIdentity` | value | Builds the provider-owned `customer_id` and `login_customer_id` identity shape. |

### `@patronage/ads-sync/google-search-console`

| export | kind | contract |
| --- | --- | --- |
| `googleSearchConsoleProvider` | value | The Google Search Console provider module. |
| `ConfiguredCatalog` | type | A configured Airbyte catalog: a `streams` array. |
| `ConfiguredCatalogStream` | type | One configured stream: sync modes, cursor, primary key, generation fields, and the stream schema. |
| `AccessTokenSourceConfigInput` | type | Builder input: `accessToken`, `accountIds`, `startDate`, optional exclusive `endDate`. |
| `GoogleSearchConsoleSourceIdentityInput` | type | Semantic Search Console manifest values: `siteUrls`. |
| `googleSearchConsoleConfiguredCatalog` | value | The configured catalog for the query and page custom report. It deduplicates on site, search type, date, query, and page. |
| `googleSearchConsoleAccessTokenSourceConfig` | value | Builds the token-only source config. It needs the derived image. |
| `googleSearchConsoleSourceIdentity` | value | Builds the provider-owned `site_urls` identity shape. |
| `GOOGLE_SEARCH_CONSOLE_QUERY_PAGE_STREAM` | value | The custom report stream name. |
| `GOOGLE_SEARCH_CONSOLE_QUERY_PAGE_DIMENSIONS` | value | The report dimensions. The source adds `date`. |

### `@patronage/ads-sync/meta-ads`

| export | kind | contract |
| --- | --- | --- |
| `metaAdsProvider` | value | The Meta Ads provider module. |
| `ConfiguredCatalog` | type | A configured Airbyte catalog: a `streams` array. |
| `ConfiguredCatalogStream` | type | One configured stream: sync modes, cursor, primary key, generation fields, and the stream schema. |
| `AccessTokenSourceConfigInput` | type | Builder input: `accessToken`, `accountIds`, `startDate`, optional exclusive `endDate`. |
| `MetaAdsSourceIdentityInput` | type | Semantic Meta Ads manifest values: `accountIds`. |
| `metaAdsConfiguredCatalog` | value | The configured catalog for the custom campaign daily performance insights stream. |
| `metaAdsAccessTokenSourceConfig` | value | Builds the token-only source config and derives custom insights from the catalog. |
| `metaAdsSourceIdentity` | value | Builds the provider-owned `account_ids` identity shape. |

### `@patronage/ads-sync/sql`

| export | kind | contract |
| --- | --- | --- |
| `controlSchemaSql` | value | DDL text for the control schema. |
| `controlSchemaCatalogSnapshotSql` | value | DDL text for catalog snapshot tables. |
| `reportingViewSql` | value | DDL text for the reporting views, rendered for a single deployment that owns its whole database. |
| `requiredReportingViewTables` | value | Tables required before the views. It is currently empty. |
| `tenantDestinationSchemaSql` | value | DDL text that creates one tenant's schemas under its migration role. |
| `tenantDestinationDefaultPrivilegesSql` | value | DDL text that grants the runtime role read on the tables the connector creates later. |
| `TenantDestinationPlan` | type | One tenant's schema names and the three database roles. |
| `TenantConnectionSchemas` | type | The raw and final schema names of one Sync Connection. |
| `POSTGRES_IDENTIFIER_PATTERN` | value | The identifier shape a derived schema name must match. |
| `POSTGRES_IDENTIFIER_MAX_LENGTH` | value | 63, the Postgres identifier limit a derived name stays inside. |

Tenant schema naming. A schema name is derived, never typed, and the derivation lives beside the statements that create and grant these schemas so the attended migration lane, the shared runtime, and the tenant descriptor reader all read one definition:

| export | kind | contract |
| --- | --- | --- |
| `TENANT_SCHEMA_PREFIX` | value | `t_`. Every schema a tenant owns starts with it, so a name never starts with a digit and the boundary is readable in `information_schema`. |
| `TENANT_SCHEMA_SEPARATOR` | value | `__`. It separates the tenant boundary from the schema role inside it. |
| `CONNECTION_SCHEMA_TOKENS` | value | The Airbyte Direct Load schema token for each connection profile. |
| `AdsSyncConnectionProfileKey` | type | One connection profile key. |
| `ADS_SYNC_CONNECTION_PROFILE_KEYS` | value | Every profile key, as a non-empty tuple a schema can enumerate. |
| `adsSyncConnectionProfileKey` | value | Reads a connection id back as a profile key, or `undefined`. |
| `CONNECTION_PROFILE_PROVIDERS` | value | The Supported Provider each profile syncs. |
| `adsSyncConnectionProfileProvider` | value | The provider of one profile. |
| `tenantSchemaPrefix` | value | One tenant's schema prefix. |
| `tenantSchemaName` | value | One tenant schema, from the prefix and a role. |
| `tenantControlSchema` | value | One tenant's control schema. |
| `tenantReportingSchema` | value | One tenant's reporting schema. |
| `tenantConnectionFinalSchema` | value | One Sync Connection's Airbyte Direct Load schema. |
| `tenantConnectionRawSchema` | value | The raw records schema of the same connection. |
| `tenantProvisioningLockKey` | value | The advisory lock subject that serializes one tenant's provisioning. |

The Reporting Contract, as one definition rendered per destination. A single deployment and a shared-runtime tenant differ only in the schema names the same view bodies are rendered with:

| export | kind | contract |
| --- | --- | --- |
| `REPORTING_CONTRACT_VIEWS` | value | Each Reporting Contract view and the connection profiles it reads. Each profile names `required` Direct Load relations that gate its branch and `optional` enrichment relations that join when available; later optional-table arrival requires a refresh. |
| `REPORTING_CONTRACT_VIEW_NAMES` | value | Every contract view name, as a non-empty tuple. |
| `ReportingContractViewName` | type | One contract view name. |
| `reportingViewProfiles` | value | The connection profiles one view can read. |
| `reportingContractViewsForProfiles` | value | The views a set of enrolled profiles materializes. A deployment that syncs only Search Console gets `gsc_query_page_daily` and nothing that would advertise an ad platform it does not sync. |
| `tenantReportingViewRelation` | value | The schema-qualified relation one tenant's view is read from, derived from the Client Key. |
| `tenantReportingViewsSql` | value | DDL text that refreshes one tenant's Reporting Contract views and the reporting reader's grants on them. It is idempotent and requires the tenant's reporting schema to exist, so it converges a live tenant rather than provisioning one. |
| `TENANT_REPORTING_VIEW_LOCK_SUFFIX` | value | The advisory lock subject suffix a reporting refresh takes, distinct from the provisioning subject. |

Shared-warehouse control boundary exports (ADR 0054, 2026-08-25 amendment):

| export | kind | contract |
| --- | --- | --- |
| `TENANT_SCOPED_CONTROL_TABLES` | value | The control tables that carry one tenant's rows. Deployment-wide tables are not in the list. |
| `TENANT_CONTROL_BOUNDARY_SQL` | value | DDL text for the row-level boundary: a `client_key` column that defaults from the session, forced row-level security, and the two policies. It is already part of `controlSchemaSql`. |
| `TENANT_CLIENT_KEY_SETTING` | value | `ads_sync.client_key`, the session setting that names the tenant a control statement acts for. |
| `TENANT_TENANCY_SETTING` | value | `ads_sync.tenancy`, the session setting that names which tenancy the caller runs under. An absent setting reads as single-tenant. |
| `RETIRED_CONTROL_TABLES` | value | Deployment-wide control tables from the retired hosted one-off runtime. `controlSchemaSql` drops them, and the shared-control bootstrap observes the list before it reports convergence. |
| `RETIRED_CONTROL_FUNCTIONS` | value | Control-schema functions from the retired hosted one-off runtime. `controlSchemaSql` drops them, and the shared-control bootstrap observes the list before it reports convergence. |
| `SHARED_CONTROL_RUNTIME_GRANTS` | value | The exact privilege list the shared runtime identity holds on each control table. |
| `sharedControlRuntimeGrantSql` | value | DDL text that takes back any prior grant and states that exact grant set. It states no `ALTER ROLE`. |
| `revokePublicSchemaUsageSql` | value | DDL text that takes back the schema `public` usage Postgres grants to the `PUBLIC` pseudo-role. |
| `controlSchemaMigrationLedgerSql` | value | DDL text that creates `ads_sync.schema_migrations`, the migration ledger the runtime drift guard reads. Both bootstraps create the table from this one definition. It is not part of `controlSchemaSql`. It creates the table only; the row is written by `recordControlSchemaMigrationSql`. |
| `controlSchemaMigrationInput` | value | The exact string every drift guard hashes: `controlSchemaSql`, a newline, then `controlSchemaCatalogSnapshotSql`. |
| `controlSchemaSha256` | value | The hash of that string. A bootstrap records it and the runtime refuses to dispatch when it reads a different one. |
| `CONTROL_SCHEMA_MIGRATION_ID` | value | `control-schema`, the ledger row every drift guard reads. |
| `recordControlSchemaMigrationSql` | value | DDL text that records one hash in the ledger with the catalog the database holds now. It reads the catalog on the server and upserts, so a re-run refreshes a stale row. It refuses a hash that is not a sha256 digest. The recorded snapshot carries schema and relation ACLs, so it must run after every grant. |
| `TENANT_POLICY_NAME` | value | `ads_sync_tenant_rows`, the policy that admits one tenant's control rows. |
| `SINGLE_TENANT_POLICY_NAME` | value | `ads_sync_single_tenant_rows`, the policy that admits a one-off deployment's unowned rows. |
| `dropSingleTenantPolicySql` | value | DDL text that removes the single-tenant policy from every tenant-scoped control table. A shared warehouse runs it, so the tenant policy is the only way a control row is reachable there. |
| `tenantDestinationGrantMatrix` | value | Every grant one tenant's provisioning makes, as data. The DDL is rendered from it and the migration lane reads it back, so the SQL and the check cannot drift. |
| `tenantConnectionGrantMatrix` | value | The grants one Sync Connection's two Airbyte schemas carry. `tenantDestinationGrantMatrix` is this set plus the tenant's reporting-schema grant, so provisioning a tenant and adding a connection later render their DDL from one matrix. |
| `tenantConnectionSchemaSql` | value | DDL text that adds one Sync Connection's two schemas and their grants to a tenant that already exists. It creates the connection's schemas only, and refuses inside its own lock when the tenant's own schemas are absent or the connection's are already present. It refuses a plan that states more than one connection. It waits on the tenant's own provisioning lock subject, so adding a connection cannot race provisioning. |
| `TenantSchemaGrant` | type | One principal's grants on one of a tenant's schemas. |
| `TenantPrincipalRole` | type | Which of a tenant's two principals a grant is stated for. |

### `@patronage/ads-sync/credentials`

The credential vocabulary a deployment plan and a run both derive from. It resolves nothing and reads nothing, so a deploy script can import it without carrying a database driver or a container client.

| export | kind | contract |
| --- | --- | --- |
| `TENANT_SOURCE_CREDENTIAL_ROLES` | value | The source Credential Roles each Supported Provider's credential set declares. |
| `TENANT_DESTINATION_CREDENTIAL_ROLES` | value | The destination Credential Roles every plan states. |
| `OPTIONAL_TENANT_DESTINATION_CREDENTIAL_ROLES` | value | Destination roles a plan may state beyond the required ones. The reporting reader is the only one. |
| `WORKER_SECRET_CUSTODY_ROLE` | value | The one role whose material exceeds the Secrets Store entry cap and rides as a Worker secret. |
| `PROVIDER_HANDLE_SUBJECTS` | value | The Logical Secret Handle subject each provider's credential set uses. |
| `DESTINATION_HANDLE_SUBJECT` | value | The subject every warehouse credential uses. |
| `ADS_SYNC_HANDLE_OPERATION` | value | The operation every Ads Sync credential set is read under. |
| `CLIENT_SCOPED_ROLES` | value | The roles that are a tenant's own material. Every other role is Patronage-owned and derives the global handle. |
| `SOURCE_PLACEMENT_PATHS` | value | Where each source role's value lands in the source connector config. |
| `tenantCredentialHandle` | value | Derives one role's Logical Secret Handle from the Client Key and the subject. Scope is a property of the role, so a caller cannot name another tenant's handle. |
| `dispatchPinnedRole` | value | The one source Credential Role a dispatch request pins: the tenant's own source material where the provider has any, and the shared service account for Google Search Console. |
| `tenantCredentialCoordinates` | value | Every Credential Role one connection binds, with the handle and property each store entry name derives from. |
| `TenantCredentialCoordinates` | type | One Credential Role at the coordinates its store entry name derives from. |
| `assertClientKey` | value | Holds a Client Key to one spelling: lowercase letters, digits, and hyphens. The handle-to-entry-name transform is not injective, so an unchecked key could otherwise derive another tenant's entry names. |
| `CLIENT_KEY_PATTERN` | value | The Client Key grammar `assertClientKey` enforces. |
| `tenantCredentialHandleKey` | value | Derives the environment-key half of a store entry name from a Logical Secret Handle. |

### `@patronage/ads-sync/run`

Seam entry point and shapes:

| export | kind | contract |
| --- | --- | --- |
| `createQualifiedRunAdapter` | value | Builds the Qualified Run adapter. See the contract above. |
| `QualifiedRunAdapter` | type | The eleven adapter methods, including `run`. |
| `QualifiedRunDependencies` | type | Bindings and policy hooks the caller supplies. |
| `QualifiedRunParams` | type | Connection id and run id for one run. |
| `QualifiedRunWindow` | type | Window id, start, and end for a backfill window. |
| `PreparedQualifiedRun` | type | Resolved connection, hashes, generation metadata, and artifact keys. |
| `QualifiedRunSummary` | type | Source, destination, destination input, and state commit results. |
| `SourceReadResult` | type | Source summary plus stdout and stderr manifests. |
| `DestinationInputResult` | type | Destination input manifest, dropped lines, and summary. |
| `DestinationWriteResult` | type | Destination summary, manifests, and the state commit result. |
| `StateCommitResult` | type | Either a commit, or no commit with reason `no_state`. |
| `ArtifactBucket` | type | The streaming R2 subset used by a Qualified Run: `get`, `put`, and `delete`, with object bodies exposed as `ReadableStream`. |
| `DEFAULT_ARTIFACT_LIMITS` | value | 2 GiB source and destination artifacts and 10000000 lines; each line is additionally bounded to 8 MiB. |
| `sanitizeAirbyteStdout` | value | Redacts every Airbyte stdout line that is not a RECORD or STATE message; data lines stay byte-identical. |

Container exports:

| export | kind | contract |
| --- | --- | --- |
| `ConnectorContainerHandle` | type | A Cloudflare Container stub, or any object with the same shape. |
| `ConnectorArtifactSession` | type | A qualified connector session whose stdout and stderr are opened as streams and deleted after its consumer returns. |
| `ConnectorSessionReceipt` | type | Small connector result metadata with session id, byte counts, and SHA-256 digests; artifact bodies are separate streams. |
| `ContainerImagePin` | type | The exact `connectorImage` and `wrapperVersion` an image must report. |
| `ContainerKind` | type | A provider id, or `destination`. |
| `ColdStartRetryPolicy` | type | Maximum attempts, retry delay, and an injectable sleep. |
| `DEFAULT_COLD_START_RETRY` | value | 5 attempts, 2000 ms apart. |
| `ContainerQualificationError` | value | Error with reason `metadata_mismatch` or `unavailable`. |
| `assertContainerImagePin` | value | Verifies the running image pin before use; retries only an unavailable image. |
| `readSourceArtifact` | value | Runs one source read and stops the container afterward. |
| `writeDestinationContainer` | value | Runs one destination write and stops the container afterward. Sends `content-length` and `x-airbyte-content-length` so wrapper version `ads-sync-wrapper-v0.5` can decode a chunked destination body against that exact length. |
| `connectorContainerIdForStreamRun` | value | Builds the container id for one stream run. |
| `sanitizeConnectorFailureText` | value | Redacts secret values in connector failure text: JSON and escaped-JSON pairs, Python repr pairs and kwargs or dataclass reprs (`refresh_token='…'`, unquoted until a delimiter), mixed-quote pairs, bare `key=value`, `Authorization: Bearer <token>` headers, and credentials in URIs (`scheme://user:secret@host`). |
| `boundedFailureText` | value | Redacts first, then bounds, so truncation can never expose a secret prefix. |
| `MAX_FAILURE_TEXT_BYTES` | value | 4096 bytes, the upper bound for stored failure text. |

Control-store exports:

| export | kind | contract |
| --- | --- | --- |
| `ControlSql` | type | A postgres.js client or transaction client. |
| `SyncConnectionRow` | type | The raw control-store connection row. |
| `StreamLease` | type | Lease key, run id, and stream run id. |
| `RunLifecycleError` | value | Error thrown when a run may no longer commit. |
| `connectionRunAdmissionLockKey` | value | Derives the transaction-lock identity shared by run admission and attended connection-state changes; rejects a blank connection id. |
| `syncConnectionFromRow` | value | Maps a control row to a `SyncConnectionDefinition`. |
| `loadEnabledConnection` | value | Loads one enabled connection; throws when it is absent. |
| `normalizedSourceIdentity` | value | Validates identity values as strings, string arrays, or null. |
| `acquireStreamLease` | value | Takes the stream lease; throws when a sync already runs. |
| `extendStreamLease` | value | Refreshes a held lease; throws when the lease was lost. |
| `releaseStreamLease` | value | Deletes the lease for this run and stream run. |
| `releaseRunLeases` | value | Releases leases for a run and marks its runs and streams failed. |
| `loadCommittedState` | value | Returns the latest committed state, or `undefined`. |
| `assertRunMayCommit` | value | Fresh lifecycle check before a state commit. |
| `insertArtifact` | value | Records one artifact row for a stream run. |

Custody exports (ADR 0047):

| export | kind | contract |
| --- | --- | --- |
| `QualifiedRunCustodyAdapter` | type | Resolves source config, destination config, and seed state per connection. |
| `workerSecretsCustodyAdapter` | value | Single-tenant custody over Worker secrets or the local Wrangler dev vars file. |
| `ADS_SYNC_MANAGED_SECRET_NAMES` | value | Every managed secret name, derived from the Supported Provider modules. |
| `ADS_SYNC_RUNNER_TOKEN_SECRET_NAME` | value | The Ads Sync Deployment Token secret name. |
| `POSTGRES_DESTINATION_CONFIG_SECRET_NAME` | value | The destination configuration secret name. |
| `assertManagedSecretName` | value | Throws `CustodyFenceError` for a name outside the managed set. |
| `requireManagedJsonSecret` | value | Reads and parses one managed JSON secret; throws when it is absent. |
| `optionalManagedJsonSecret` | value | Reads one managed JSON secret, or returns nothing. |
| `CustodyFenceError` | value | Error thrown when a connection routes the seam outside the fence. |

Multi-tenant custody exports (ADR 0047 Loop mode, mechanics in ADR 0054):

| export | kind | contract |
| --- | --- | --- |
| `tenantSecretsCustodyAdapter` | value | Multi-tenant custody for one connection. Resolves every pinned ref once, assembles the source and destination configs, and emits one Binding Receipt before it returns material. |
| `TenantCustodyPlan` | type | The qualification coordinates, the pinned credentials, and the non-secret config templates of one Qualified Run. |
| `TenantCustodyContext` | type | Tenant key, connection id, connection version, provider, and property. |
| `TenantCredentialBinding` | type | One Credential Role: its handle, property, Secret Ref, placements, and target. |
| `CredentialPlacement` | type | A config path, and an optional `select` that derives the placed value from the stored value. |
| `SecretRef` | type | The complete triple store id, secret name, secret version. |
| `TenantSecretStore` | type | Reads one immutable, version-pinned store entry. |
| `TenantCustodyOptions` | type | The receipt sink, and an optional clock. |
| `BindingReceipt` | type | The non-secret custody record of one Qualified Run. |
| `BindingReceiptEntry` | type | One role and its complete Secret Ref. |
| `BINDING_RECEIPT_SCHEMA_VERSION` | value | 1, the receipt shape this package emits. |
| `SECRET_REF_NAME_PATTERN` | value | The derived store entry name shape, `<handle-key>__<property>__v<n>`. |
| `TENANT_SOURCE_CREDENTIAL_ROLES` | value | The source Credential Roles each Supported Provider declares. |
| `TENANT_DESTINATION_CREDENTIAL_ROLES` | value | The destination Credential Roles every plan states. |
| `OPTIONAL_TENANT_DESTINATION_CREDENTIAL_ROLES` | value | Destination roles a plan may state beyond the required ones. |
| `assertTenantCustodyPlan` | value | Fails a plan closed before any read: an unpinned ref, an undeclared role, a missing role, or a template that already carries material at a credential path. |
| `assertVersionPinnedRef` | value | Throws unless a ref's name, property, and stated version agree. |
| `assertReceiptCarriesNoValue` | value | Throws instead of emitting a receipt that carries resolved material. |
| `TENANT_SECRET_CUSTODY_SURFACES` | value | The two read paths a ref may name: the Secrets Store, and the Worker-secret hybrid-custody exception. |
| `TenantSecretCustodySurface` | type | One of those two surfaces. |
| `secretRefCustody` | value | The read path a ref names, with the store applied as the default. |
| `WORKER_SECRET_CUSTODY_ROLE` | value | The one role the Worker-secret surface is allowed for. Any other role that claimed it is refused. |

Runtime custody planning exports (ADR 0054 decisions 1 and 2; the runtime that executes a Qualified Run plans that run's custody from the entries it binds):

| export | kind | contract |
| --- | --- | --- |
| `planRuntimeTenantCustody` | value | Plans custody for one dispatched Qualified Run from the request's coordinates and a ref source, or states why it refuses. It reads no store entry and emits no receipt. |
| `RuntimeTenantCustodyInput` | type | The tenant, the connection at its version, the request's pinned ref, the two non-secret templates, and the ref source. |
| `RuntimeCustodyPlanResult` | type | A plan, or a named refusal. |
| `RuntimeCustodyRefusal` | type | The tenant, the connection, the reason, and the detail. |
| `RuntimeCustodyRefusalReason` | type | Why a plan was refused: an unbound role, an ambiguous pin, a ref the run derives for no role, an unplaceable role, or a plan the seam rejects. |
| `RuntimeTenantCustodyDependencies` | type | The Google Search Console access-token exchange. |
| `TenantCustodyRefSource` | type | Answers with the exact pin this deployment binds for one role, or nothing. |
| `tenantDestinationTemplate` | value | The non-secret destination connector config for one tenant connection. The host, database, username, and password are absent: custody places all four from the tenant's writer entry. |
| `PLANETSCALE_POSTGRES_PORT` | value | 5432. It is stated rather than derived because the connector reads a number and a placement produces a string. |
| `connectionStringField` | value | Reads one field of a PlanetScale connection string, checking the exact TLS parameters on every read and decoding the user information once. |
| `planetScalePostgresJsConnection` | value | Converts a reviewed PlanetScale libpq URL into the postgres.js form. Returns `{ connectionString, options }` with `prepare: false` and `ssl: "verify-full"`; libpq-only query parameters never reach the driver startup packet. Throws `CustodyFenceError` unless the URL states `sslmode=verify-full` and `sslrootcert=system` with no extra query parameters. |
| `mintGoogleServiceAccountAccessToken` | value | Exchanges a Google service-account key for one bounded access token. The key never reaches a container; the token does. |
| `parseGoogleServiceAccountKey` | value | Reads the client email and private key out of a service-account key. Its error text names the missing field, never the document. |
| `GOOGLE_SEARCH_CONSOLE_READONLY_SCOPE` | value | The only scope an Ads Sync run needs. It reads; it never writes. |
| `GoogleServiceAccountKey` | type | The two fields the exchange needs. |
| `MintGoogleAccessTokenOptions` | type | An optional fetch, clock, and scope. |

Qualified Run dispatch contract exports (ADR 0053; the orchestrator plans a run and the runtime executes it):

| export | kind | contract |
| --- | --- | --- |
| `QUALIFIED_RUN_DISPATCH_CONTRACT_VERSION` | value | 2, the dispatch contract version both halves implement. |
| `QualifiedRunRequestSchema` | value | The schema one planned Qualified Run parses against. |
| `QualifiedRunRequest` | type | One planned run: its tenant, connection, connection version, credential ref, provider, property, trigger, bounded window, and run key. |
| `parseQualifiedRunRequest` | value | Parses a request, or throws `DispatchContractError`. |
| `QualifiedRunAttemptRequestSchema` | value | Extends one planned request with Loop's durable dispatch-attempt identity. |
| `QualifiedRunAttemptRequest` | type | One exact transport attempt. The attempt id changes across retries while the run key stays stable. |
| `parseQualifiedRunAttemptRequest` | value | Parses an exact transport attempt, or throws `DispatchContractError`. |
| `QUALIFIED_RUN_PROTOCOL_PATH` | value | `/qualified-runs/protocol`, the authenticated non-executing runtime identity endpoint. |
| `QUALIFIED_RUN_RUNTIME_SERVICE` | value | The stable shared-runtime service identity. |
| `QualifiedRunProtocolSchema` | value | The runtime identity, contract version, and tenancy proof schema. |
| `QualifiedRunProtocol` | type | The authenticated runtime protocol proof. |
| `parseQualifiedRunProtocol` | value | Parses a runtime protocol proof, or throws `DispatchContractError`. |
| `QUALIFIED_RUN_RECONCILIATION_PATH` | value | `/qualified-runs/reconcile`, the authenticated non-executing exact-attempt lookup. |
| `QualifiedRunReconciliationSchema` | value | The exact-attempt reconciliation receipt schema, including completion evidence for terminal runs. |
| `QualifiedRunReconciliation` | type | An accepted exact attempt with its runtime status, or an exact not-found result. |
| `parseQualifiedRunReconciliation` | value | Parses a reconciliation receipt, or throws `DispatchContractError`. |
| `QUALIFIED_RUN_COMPLETION_PATH` | value | `/ads-sync/qualified-runs/complete`, the authenticated Loop endpoint a runtime reports completion to. |
| `QualifiedRunCompletionSchema` | value | The schema a successful runtime's completion report parses against. |
| `QualifiedRunCompletion` | type | One completion report: tenant, connection id and version, provider, property, run id and key, trigger, the bounded window, whether state was committed, and the planning watermark used as the completion compare-and-swap pre-image. |
| `parseQualifiedRunCompletion` | value | Parses a completion report, or throws `DispatchContractError`. |
| `QualifiedRunCompletionAcknowledgementSchema` | value | The schema of Loop's attributable acknowledgement of one completion report. |
| `QualifiedRunCompletionAcknowledgement` | type | Echoes the run id and key, whether the acknowledgement changed state, and the resulting watermark. |
| `parseQualifiedRunCompletionAcknowledgement` | value | Parses a completion acknowledgement, or throws `DispatchContractError`. |
| `QualifiedRunDispatchWindowSchema` | value | The schema a bounded dispatch window parses against. |
| `QualifiedRunDispatchWindow` | type | The half-open window a planned run covers. |
| `ClientKeySchema` | value | The schema a Client Key parses against. |
| `ClientKey` | type | The tenant coordinate a request states and a control row carries. |
| `CredentialRefSchema` | value | The schema a credential reference parses against. |
| `CredentialRef` | type | The secret name and version a run resolves. It never carries a value. |
| `QualifiedRunSubject` | type | The tenant coordinates the runtime holds for one connection: Client Key, provider, and property. |
| `bindQualifiedRunSubject` | value | The fence. Holds a request's stated Client Key against the connection the runtime loaded, and refuses instead of starting another tenant's run. |
| `QUALIFIED_RUN_REFUSAL_REASONS` | value | Every named reason a dispatch is refused. |
| `QualifiedRunRefusalReason` | type | One of those reasons. |
| `QualifiedRunRefusal` | type | A named refusal: its reason, its run key, and a non-secret detail. |
| `QUALIFIED_RUN_TRIGGERS` | value | Why one Qualified Run was planned: `scheduled` or `attended_backfill`. |
| `QualifiedRunTrigger` | type | One of those triggers. |
| `DISPATCH_ACKNOWLEDGEMENT_RESULTS` | value | Every attributable dispatch outcome: `queued`, `already_active`, `no_new_final_data`, or `reconciled`. |
| `DispatchAcknowledgementResult` | type | One of those outcomes. |
| `DispatchAcknowledgementSchema` | value | The schema an acknowledgement parses against. |
| `DispatchAcknowledgement` | type | What the runtime did with one planned run. `runId` is present exactly when a run exists. |
| `parseDispatchAcknowledgement` | value | Parses an acknowledgement, or throws `DispatchContractError`. |
| `acknowledgedRunId` | value | The run id an acknowledgement names, or nothing when it names no run. |
| `DispatchContractError` | value | Error thrown when a request or an acknowledgement does not meet the contract. |

Tenant session scope exports (ADR 0054, 2026-08-25 amendment):

| export | kind | contract |
| --- | --- | --- |
| `AdsSyncTenancy` | type | The tenancy a deployment runs under: `multi-tenant` or `single-tenant`. |
| `TenantSessionScope` | type | What one control transaction acts for. A multi-tenant scope always names a Client Key; a single-tenant scope never does. |
| `tenantSessionScope` | value | Resolves the scope, and fails closed when a multi-tenant deployment has no bound Client Key. |
| `applyTenantSessionScope` | value | States the scope on the current transaction with `SET LOCAL`, so a pooled connection cannot carry it into the next transaction. |
| `withTenantSession` | value | Runs control work in one transaction that states its tenant before any control statement. |
| `tenantScopedSql` | value | Returns a control client whose statements run inside the stated tenant transaction; single-tenant deployments keep the original client. |

Tenant reporting custody exports (ADR 0054):

| export | kind | contract |
| --- | --- | --- |
| `TENANT_REPORTING_HANDLE_SUBJECT` | value | `planetscale`, the Logical Secret Handle subject for shared-warehouse credentials. |
| `TENANT_REPORTING_HANDLE_OPERATION` | value | `report-read`, the reporting reader operation. |
| `TENANT_REPORTING_READER_ROLE` | value | The reporting-reader Credential Role. |
| `SECRETS_STORE_VALUE_MAX_BYTES` | value | Maximum UTF-8 byte size accepted from the secrets store. |
| `secretsStoreValueByteLength` | value | Measures a stored value in UTF-8 bytes without exposing it. |
| `TENANT_REPORTING_REFUSAL_REASONS` | value | Every named reason the reporting lane refuses to open a tenant connection. |
| `TenantReportingRefusalReason` | type | One reporting refusal reason. |
| `TenantReportingCustodyError` | value | A value-free error carrying one reporting refusal reason. |
| `tenantReportingHandle` | value | Derives the tenant reader's Logical Secret Handle from a validated Client Key. |
| `tenantReportingHandleKey` | value | Derives the lowercased store-entry handle key. |
| `tenantReportingEntryName` | value | Derives the immutable store entry name for one tenant reader and exact version. |
| `TenantReportingCredentialSource` | type | Resolves the deployment-owned Secret Ref for one tenant reader, never its value. |
| `TenantReportingContext` | type | Client Key, connection id, and run id echoed by the receipt. |
| `TENANT_REPORTING_RECEIPT_SCHEMA_VERSION` | value | 1, the reporting receipt shape this package emits. |
| `TenantReportingReceipt` | type | Non-secret record of the exact tenant reader entry resolved for one run. |
| `TenantReportingConnection` | type | One opened reporting SQL client and its close operation. |
| `TenantReportingAccessOptions` | type | Connection factory, qualification context, receipt sink, credential source, store, and optional clock. |
| `TenantGscQueryPageDailyInput` | type | The Client Key, exact property and search type, half-open date window, and bounded row limit for the curated GSC query-page read. |
| `TenantReportingQuery` | type | A fixed SQL statement paired with its positional string and number parameters. |
| `tenantGscQueryPageDailyQuery` | value | Builds the one curated GSC query-page-daily reader query against the relation derived from the Client Key. Request values remain positional parameters, and the query reads one extra row to prove truncation. |
| `resolveTenantReportingCredential` | value | Resolves and validates the exact tenant reader, emits its value-free receipt, and returns the URL only inside the custody boundary. |
| `withTenantReportingConnection` | value | Opens one tenant reader after receipt emission, runs one read, and always closes the connection. |
| `assertPinnedReportingRef` | value | Refuses a Secret Ref unless its store, derived name, property, and exact version agree. |
| `assertReportingValueFitsStoreCap` | value | Refuses an oversized stored value without including the value or its length in the error. |
