From a local file to a scheduled production deployment — Development, Production, and what each step preserves
A suite that only runs on your machine is a useful tool. A suite in your workspace is a monitored one: versioned, runnable by anyone with access, schedulable, and wired into assets, checks, issues and alerts.Two stages, in the app under Health → Reconciliations:
Stage
What lives there
How a run starts
Development
Stored, versioned suites. The shared draft.
On demand only
Production
Deployments — immutable snapshots with a schedule and run settings.
Development suites → New suite opens a four-step wizard: Data Sources, Comparison, Suite Info, Review. It searches your catalog, so you can pick a table you have already catalogued rather than typing warehouse coordinates.Upload Suite Config takes a whole suite as pasted or uploaded YAML — which is how you get anything the wizard does not cover. What the wizard covers is the map.
Every save creates a new version. The change summary is what makes the version history readable six months later.
synq-recon suite listsynq-recon suite versions <suite-id>synq-recon suite yaml <suite-id> > suite.yaml # read it back as editable YAMLsynq-recon suite delete <suite-id> # soft delete
suite yaml is the round-trip that makes a stored suite editable again — including one someone else created in the wizard. Fetch it, edit the file, upload-config it back. This is also the recipe for copying a suite between workspaces.
In the app this is the Bind suite connections to integrations dialog.
N connection(s) could not be bound to an integration means a suite connection has no matching integration, or the integration is not enabled for reconciliation. Check the names with connections remote list --recon-deployable, or bind explicitly with --map.
Read connection vs integration once if that distinction is new — the same YAML key means two different things in the two stages, and it is the most common source of confusion.
The run is asynchronous. --wait blocks until it finishes and sets a meaningful exit code; without it, poll with synq-recon audit-logs get <invocation-id>.--invocation-id <id> makes submission idempotent — re-submitting with the same id will not start a duplicate run, which is what you want from a retrying pipeline.
Development → Run on the suite. The run options dialog carries the same drill and timeout settings.
Pass --drill=false explicitly if you do not want a drill. Omitting the flag does not mean “off”.Unlike promote, where an omitted flag preserves the stored setting, an ad-hoc run has no deployment to inherit from — so an omitted --drill falls through to each reconciliation’s own bisection.enabled in the YAML, which defaults to on. On a suite with genuinely many differences that is the difference between a two-minute run and a fifteen-minute one with nothing usable at the end.
Promoting creates a deployment: an immutable snapshot of the suite plus its schedule, bindings, run settings and annotations.
CLI
App
synq-recon promote <suite-id> \ --schedule "0 */4 * * *" \ --timezone UTC \ --triggerable-by-api \ --drill=false \ --execution-timeout 30m \ --annotation team=data-platform \ --change-summary "Every four hours, no drill"
Promote to production on the suite card. The dialog covers the schedule and the run settings, and shows a diff of what is about to change against what production is running today.
Once promoted, each reconciliation in the deployment becomes a platform asset that produces a check on every run — so it appears in search and lineage, participates in check categorisation, and opens issues that route through your existing alerts and ownership.
Both take --timezone (for example UTC, Europe/Warsaw); --ical additionally accepts --dtstart as an anchor. Use iCal for the schedules cron cannot express — last Thursday of the month, the second Tuesday, business-day patterns.
--timeout and --execution-timeout are unrelated, and mixing them up is easy:
--timeout is a per-query budget for locally executed commands. Default 5m.
--execution-timeout is the whole-run wall-clock budget for a backend run, set on a deployment or per trigger. The server clamps it to its supported range.
Deployment edits preserve what you omit. deployment update always behaves this way, and so does a re-promote — so refreshing a suite snapshot never silently unschedules the deployment or turns off API triggers.
synq-recon deployment update <suite-id> --execution-timeout 45m # changes only thatsynq-recon deployment update <suite-id> --clear # remove the schedulesynq-recon promote <suite-id> --clear-schedule # same, while re-promoting
Removing a schedule is therefore always explicit.
A fresh promote applies defaults, and one of them may surprise you. With no existing deployment to preserve from, a promote defaults to: no schedule, not triggerable by API, the server-default execution timeout — and drill-down on.If you want a scheduled production run that never drills, pass --drill=false on the first promote. Do not rely on omission.
A deployment is a snapshot, not a pointer. Editing the suite in Development changes nothing in production until you re-promote. The app says so on the suite card — “Dev has unpromoted changes” versus “Up to date with prod” — and it is worth checking that line before concluding that a fix did not work.
A deployment’s id is part of every reconciliation’s asset path. Rebuilding a deployment from scratch under a new id re-homes its checks and drops their history.Re-promoting the same suite reuses its id automatically, so this is only a concern if you are rebuilding deliberately — in which case pin it:
Pause is for a planned maintenance window: the deployment stays configured and stops running. Unpromote deactivates it entirely; its history is kept, and re-promoting brings it back under the same id.
deployment is not active; re-promote to modify means the deployment was unpromoted. Re-promote before changing or tearing it down.
synq-recon runs list --status in_progresssynq-recon runs list --trigger scheduled --suite <suite-id> --limit 20synq-recon runs cancel <suite-id> <run-id>synq-recon audit-logs list --status mismatchedsynq-recon audit-logs get <invocation-id> -o jsonsynq-recon deployment get <suite-id> -o yaml # schedule, bindings, run settingssynq-recon deployment history <suite-id> # every promote, pause, edit
A run’s --trigger says how it started, which is often the first thing you want to know:
Trigger
Means
adhoc
Submitted against a Development suite (run-remote, or Run in the app).
scheduled
A schedule fired.
api
An explicit trigger — the Run button on a promoted suite, or an external caller such as a CI job.
deployment history is append-only and records every promote, unpromote, schedule change, binding change, annotation edit, pause and resume. When production behaviour changed and nobody remembers why, it is the first place to look.
The app hides controls whose call would be refused, so a missing scope shows up as a missing button rather than an error. CI/CD and automation maps these to roles and to the credentials an unattended caller uses.