Skip to main content
One page, so the rest of this section can use these words without re-explaining them. If you are reading a run, an audit log or an API response and a term is unfamiliar, it is here.

The building blocks

A YAML file — and, once uploaded, a stored, versioned object in your workspace — holding one or more reconciliations plus the connections they use. A suite is the unit you save, version, run and promote. It has a name, a title, and optionally a description.
One comparison of one dataset against one other dataset. A suite contains reconciliations, keyed by name under reconciliations:. This is the unit that passes or fails, that becomes an asset when promoted, and that --include / --exclude select.
One side of a reconciliation: source: or target:. A dataset names a connection plus either a table: or a query:, and optionally narrows it with columns:, exclude_columns: or where:.
The name a dataset refers to when it says which database to read from. Locally, a connection holds credentials. In a workspace suite, the same name binds to an integration. See connection vs integration below — this distinction causes more confusion than anything else here.
The column — or tuple of columns — that identifies a row. Declared as key_column: or key_columns:; both accept a string or a list. Key columns must be unique, and ideally indexed: the drill-down orders and range-filters on them, so a matching index is what keeps a drill cheap.
How the two sides are compared: row_count, row_checksum or aggregate. See Comparison modes.

Running and inspecting

Stage one of a run: one aggregate query per side returning counts and checksums. Answers “do they agree?” without locating anything. synq-recon run-check runs this stage alone.
Stage two: recursively narrowing the difference. In row_count and row_checksum modes it bisects the key space into segments; in aggregate mode it walks down the group_columns hierarchy. Only what mismatched is drilled. synq-recon run-drill runs this stage, and synq-recon run --auto-drill runs both.
A segment is a key range the drill-down compared as a unit. A mismatch leaf is a segment where the two sides disagree and drilling stopped — because it hit the row threshold, the depth limit, or could not be split further. Leaves are the actionable output of a run: each one carries the key range, why drilling stopped, and SQL that returns the rows.
One execution of a suite. A run has a status, a trigger, timings, and per-reconciliation results. Runs executed by our backend also have an invocation id, which is how you fetch the run later.
The full record of a run: every query as it was actually executed, every count, checksum, timing and mismatch leaf. Written locally with --audit-log <path>, and stored in the workspace for backend runs. Its shape is published as the audit-log schema. It records connection names, never credentials.
Why a run started: adhoc (submitted on demand against a Development suite), scheduled (a schedule fired), or api (an explicit trigger — which covers both the Run button on a promoted suite and an external caller such as a CI job).

Development, Production and deployments

The stage a suite lands in when you save it to the workspace with upload-config, or create it in the app’s new-suite wizard. Stored and versioned, runnable on demand, not scheduled. This is the shared draft.
The stage a suite reaches when you promote it. Its results become platform assets and checks, and it can run on a schedule or be triggered through the API.
The object promoting creates: an immutable snapshot of the suite, plus its schedule, connection bindings, run settings and annotations. A deployment is a snapshot, not a pointer — editing the suite in Development changes nothing in Production until you re-promote.
Every upload-config creates a new version of the stored suite, with an optional --change-summary. synq-recon suite versions <id> lists them; the app has a version picker. Promoting captures one specific version into the deployment.

Connection vs integration

The same YAML key means two different things depending on where the suite runs. This is worth reading once, carefully.
  • A connection is the name a reconciliation refers to. It is always just a name.
  • An integration is a warehouse credential your workspace already manages, with a UUID. Backend runs use integrations; they never see the credentials in your YAML.
When a suite runs on our backend, each connection name is bound to an integration. By default binding is by identity — a connection named warehouse binds to the integration whose id is warehouse. Override it explicitly:
The practical consequence: keep credentials out of the suite entirely. Put them in a git-ignored .connections.yaml keyed by the same connection names, and the same suite file runs locally against your credentials and in the workspace against integrations, with nothing to change between them. Authoring suites shows the layout.

Replaying a finished run

Re-execute a finished run’s queries and report what moved. The question it answers is “did the difference go away?” — after a backfill, a pipeline fix, or a redeploy. synq-recon recheck <run>; in the app, Re-check on the run detail page.
Continue a finished run’s drill-down from where it stopped, at a finer threshold or through another grouping column. synq-recon drill-deeper <run>; in the app, Drill deeper.
Both replay the queries recorded in the audit log rather than re-deriving them, which is what makes “did it move?” a meaningful comparison. Investigating results covers the consequences.

You may also see

Older suites, stored YAML and API payloads sometimes use different spellings. All of these still work; the left column is what the documentation uses.