---
title: Verify a bounded run
description: Prepare canary evidence, review backfill bounds, and compare stable history.
---

This guide is for an Ads Sync operator who already has an operator runner built around the public package. The Ads Sync Reference Deployment ships `POST /runs` for one scheduled Sync Connection (see the [quickstart](/tutorial/quickstart)); it does not ship canary or backfill endpoints, so these steps do not claim that `POST /backfill-plans` exists there.

## prepare one canary

Start with one exact connection and a positive window no longer than 24 hours:

```ts
const request = parseAdsSyncCanaryRequest({
  connectionId: "meta_ads_performance",
  provider: "meta_ads",
  windowStart: "2026-05-01T00:00:00.000Z",
  windowEnd: "2026-05-02T00:00:00.000Z",
});
```

Hash the canonical request with `adsSyncCanaryRequestSha256()`. Bind that hash to the operator runner's reviewed request and evidence. The package parser rejects extra keys, unsupported providers, invalid connection ids, reversed windows, and windows over 24 hours.

Run the detailed [`prepare-bounded-run.ts` source tutorial](https://github.com/patronage/agentic-marketing-connectors/blob/main/packages/ads-sync/src/tutorials/prepare-bounded-run.ts). It prints the canonical request hash, curated Meta backfill policy, and deterministic R2 artifact keys.

## bound the backfill

Use the curated provider defaults as a starting policy:

| provider     | window step | maximum windows per run |
| ------------ | ----------: | ----------------------: |
| `google_ads` |      7 days |                       8 |
| `meta_ads`   |      3 days |                       4 |

The package exposes these values through `supportedProviderDefinitions`. Durable `backfill_plans` and `sync_run_windows` tables are part of `controlSchemaSql`, but plan creation, leases, scheduling, retries, and HTTP operations belong to the operator runner. Keep windows idempotent and serialize work that shares a connection lease.

## inspect stored evidence

`artifactKeys()` partitions replay data by provider, stream, and run id. An operator runner can use those keys for configured catalog, source output, state input, destination input and output, stderr logs, and summary data.

R2 object persistence and retention are deployment responsibilities. Postgres is runtime authority for connections, plans, run windows, committed state, artifact metadata, and leases. Commit state only after a successful destination write.

## compare stable history

Use `runHistoricalComparisonGate()` after warehouse rows exist. Its provider and warehouse adapters read the same bounded half-open window `[startDate, endDate)` at the entity grain the provider declares. Google Ads needs a window at least 30 days behind `stableAsOf`; Meta Ads needs at least 28 days.

```ts
const artifact = await runHistoricalComparisonGate({
  provider: "meta_ads",
  window: {
    startDate: "2026-04-01",
    endDate: "2026-04-02",
    stableAsOf: "2026-07-25",
  },
  readProviderRows,
  readWarehouseRows,
});
```

Google Search Console compares the `query_page` grain instead. Pass a `queryPageScope` naming the exact property and search type, and needs a window at least 7 days behind `stableAsOf`:

```ts
const artifact = await runHistoricalComparisonGate({
  provider: "google_search_console",
  queryPageScope: { property: "sc-domain:example.org", searchType: "web" },
  window: {
    startDate: "2026-04-01",
    endDate: "2026-04-02",
    stableAsOf: "2026-07-25",
  },
  readProviderRows,
  readWarehouseRows,
});
```

Accept the gate only when `summary.passed` is `true` and `readinessRecommendation` is `"ready"`. An adapter that could not return the complete bounded result must say so in `limitations`; a declared limitation always lands the gate on `"review"`. Preserve the resulting Source Comparison Artifact without exposing account data or credentials.

Run [`run-historical-comparison.ts`](https://github.com/patronage/agentic-marketing-connectors/blob/main/packages/ads-sync/src/tutorials/run-historical-comparison.ts) for a complete in-memory adapter example:

```bash
pnpm --filter @patronage/ads-sync build
node --experimental-strip-types packages/ads-sync/src/tutorials/run-historical-comparison.ts
```
