Skip to main content
A reconciliation is a fact about your data, which makes it a good thing to block a release on. This page covers wiring one into a pipeline, and the credential constraints that apply when nobody is at the keyboard.

The shape of a gate

--wait blocks until the run completes and exits with a code your pipeline can act on:
Each code has one meaning, so a pipeline can use them. Local runs use 1 for both. See exit codes. If you need “the data is wrong” to be a different outcome from “the check could not run”, use a backend run.
Two more flags shape the wait:

Choosing what fails the build

--fail-on takes the result statuses that must fail the build, separated by commas (--fail-on mismatched,failed), or one status per flag. The list replaces the default, which is mismatched and failed. An unknown status stops the command before it starts a run.
The inverted canary is more useful than it sounds. A reconciliation that compares a table against a deliberately-modified copy should always report a mismatch; if it ever passes, your reconciliation is not actually comparing what you think it is. It is a test for the test.

Where a gate belongs

1

Before a cutover

Migrating a warehouse, or switching a consumer from one table to another. Promote a suite comparing old against new, and make the cutover step depend on it passing. This is the highest-value use: the alternative is a spot check and a hope.
2

After a backfill

Run the reconciliation as the last step of the backfill job. A backfill that reports a mismatch has not finished, whatever the row count says.
3

On a schedule, with the pipeline reading the result

Often the better pattern for a nightly pipeline: let the schedule own the run and have your job read the outcome. No coordination, no duplicate runs, and the run appears in the app whether or not the pipeline looked.
For the third pattern, read the result rather than triggering it:
The outcome is one of AUDIT_OUTCOME_PASSED, AUDIT_OUTCOME_MISMATCHED_WITHIN_THRESHOLD, AUDIT_OUTCOME_MISMATCHED or AUDIT_OUTCOME_FAILED. The same names, minus the prefix, are what --status and --fail-on accept.

Scopes and credentials

Each operation needs a scope, and each scope is carried by a role: You can select all three scopes when you create an API client or token. Thus every command works from an unattended pipeline with client credentials or QUALITY_TOKEN. No command needs the browser login of a developer. Credentials resolve in a fixed order, so an automated pipeline never silently picks up a developer’s browser login:
1

Client credentials

--client-id / --client-secret, or QUALITY_CLIENT_ID / QUALITY_CLIENT_SECRET, or the synq: block in the suite.
2

A pre-issued token

QUALITY_TOKEN. It has no YAML equivalent, because it is a CI credential and not suite configuration.
3

The cached browser login

From synq-recon auth login, refreshed automatically.

Choosing the deployment

--region names a deployment; --endpoint (or QUALITY_API_ENDPOINT) points at a specific host, for a staging or self-hosted one. Both are root flags, so they work on every command. You rarely need either in CI. synq-recon auth login --region <region> records the deployment and later commands resolve to it; synq-recon auth use <region> switches between deployments you are already logged in to, and auth use --clear returns to the default. The one that you set also selects the stored credential of that region. A token for one region is never sent to a different region. The full resolution order:
The --synq--prefixed flags and SYNQ_-prefixed variables also work, as aliases. Use the names above, which every Coalesce Quality CLI shares.
Give a pipeline the narrowest set that covers what it does. A CI gate that only reads results needs SCOPE_RECON_READ alone; one that uploads a suite and triggers it needs SCOPE_RECON_EDIT and SCOPE_RECON_PROMOTE as well.

Running in a container

The published image needs nothing installed on the runner:
Notes for a pipeline:
  • Pass secrets as environment variables, and reference them in the suite as ${VAR}. Never bake a credentials file into an image.
  • Pin the tag. :latest moves; a pipeline should name a version.
  • type: duckdb works in the image, so a pipeline can validate against DuckDB fixtures with no warehouse. If it fails with a driver error, the image is older than DuckDB support. Pull a newer tag.
  • AGENTS.md ships inside the image at /opt/synq-recon/AGENTS.md, so an agent working in a container has the operating guide without fetching anything.

Validating a suite in CI

This is the cheapest useful check, and the first one to add. It costs nothing and finds a renamed column before a scheduled run does:
Set strict_time_references: true in suites you validate in CI. It turns the NOW() / CURRENT_DATE warning into an error, so the class of bug that produces phantom mismatches cannot reach production.

Triggering without the CLI

trigger is a thin wrapper over the public API, so any HTTP or gRPC client can do the same thing. The deployment must be active, triggerable by API, and not paused. The service is synq.agent.recon.v1.SuiteDeploymentService: TriggerDeployment starts a run, and GetSuiteDeployment reads a deployment. AuditLogService and RunStateService give the results. See the gRPC API reference and scopes. Make submissions idempotent by supplying your own invocation id, so a retried pipeline step does not start a second run:

Next

Workspace suites

Schedules, deployments, and what an edit preserves.

Agent workflow

The same operations, as an operating procedure for a coding agent.