Documentation Index
Fetch the complete documentation index at: https://docs.synq.io/llms.txt
Use this file to discover all available pages before exploring further.
Checks arrive from many tools, each with its own naming. A dbt not_null
test, a dbt not_null_proportion test, an elementary test, a SQLMesh audit,
and a hand-written SQL assertion can all be checking the same thing — that a
column has no missing values — yet none of them share a name. Left as-is,
there’s no way to ask “how well is completeness covered across my stack?”
without knowing every tool’s vocabulary.
Check categorisation solves this. Coalesce Quality categorises every check
(dbt tests, SQLMesh audits, custom assertions, …) as it is ingested, mapping
each one onto a consistent taxonomy regardless of which tool produced it.
That shared vocabulary is what powers the analytics dashboards, coverage
reports, and filtering across the product — so a check only shows up in the
right place if it is categorised correctly.
Categorisation happens along two independent dimensions:
| Dimension | Answers | Example values | Primarily used by |
|---|
| Governance | What is the purpose of this check? | Completeness, Accuracy, Validity, Timeliness, Uniqueness | Data governance teams tracking coverage against governance requirements |
| Technical | What kind of check is this, mechanically? | nullness, uniqueness, referential integrity, freshness | Analysts and developers navigating and organising checks |
The governance dimension maps onto the
data quality dimensions you see in Analytics.
The technical dimension groups checks by their validation logic — for example
every not_null variant across dbt, SQLMesh and custom SQL collapses into a
single nullness group.
A check carries one category per dimension. The two are resolved
independently, so a single check can be Completeness for governance and
nullness for technical at the same time.
Where categories come from
For each dimension, a check’s effective category is resolved from three
sources, in descending priority:
- Admin override — a per-check category set by a workspace admin from the
Checks tab (see Per-check overrides). Overrides
always win.
- Producer-explicit category — set directly by the producer, or carried on
the source asset as a
synq.check_category / synq.governance_category
annotation.
- Computed category — derived by the categorisation engine from the
categorisation rules described below. A matching workspace rule wins
over a matching global rule.
If none of these produces a value the check is Uncategorised for that
dimension. When a higher tier supplies the value, the UI still shows which rule
would have matched — so you can see what an override or explicit value is
masking.
Categorisation rules
A categorisation rule says “checks matching this predicate get this
category”. Rules are managed under Health → Check categorisation, which has
a section per dimension (Governance, Technical) plus a Checks
section for inspecting how individual checks were categorised.
Each rule has:
- a category — the value assigned to checks it matches (free-form, e.g.
completeness or nullness);
- a priority — when several rules match the same check, the
highest-priority rule wins;
- a predicate — either a structured predicate or a
CEL expression, never both.
Rules created in the app are workspace rules — they apply only to your
workspace and win over the global, Coalesce Quality-provided rules on a
priority tie. Global rules are maintained by Coalesce Quality administrators.
Structured predicate
The structured predicate matches on the facts a check already carries. A check
matches when every non-empty group below contains the check’s value — an
empty group matches anything.
| Group | Matches against | Example |
|---|
| Platforms | The platform the check comes from | dbt, SQLMesh |
| Asset types | The check’s asset type | dbt test, SQLMesh audit |
| Packages | The package providing the check | dbt-utils, elementary |
| Kinds | The check’s validation-logic kind | not_null, unique, accepted_values |
| Names | Glob patterns against the check’s name | freshness_* |
| Annotation predicates | Key/value annotations on the check | dbt.tag equals pii |
For example, a rule with Platforms = dbt and Kinds = not_null,
not_null_proportion matches every dbt not-null-style test and nothing else.
Names use * as a wildcard for any sequence of characters (every other
character is literal); multiple patterns are OR-ed.
Annotation predicates match a check’s annotations by key, with one of four
modes per key:
| Mode | Matches when the annotation… |
|---|
| exists | …is present, regardless of value |
| equals | …equals a given value |
| is one of | …equals any value in a list |
| matches regex | …matches a regular expression |
The platform and asset-type dropdowns are populated from checks actually present
in your workspace and narrow as you pick, so you only ever see real values.
CEL expressions
When the structured predicate isn’t expressive enough — string prefixes,
regular expressions, combining conditions with || — switch the predicate to a
CEL expression. The rule matches a check when the expression evaluates to
true.
CEL (Common Expression Language) is a
small, safe expression language. The following variables are available:
| Variable | Type | Description |
|---|
platform | string | Platform name, e.g. PLATFORM_DBT |
asset_type | string | Asset type name, e.g. ASSET_TYPE_DBT_TEST |
package | string | Package providing the check, may be empty |
kind | string | Validation-logic kind, e.g. not_null |
name | string | Short name of the check |
description | string | Human-readable description, may be empty |
is_platform_native | bool | true for checks built into the platform (vs. custom or third-party) |
annotations | map<string, string> | Key/value annotations on the check |
PLATFORM_* and ASSET_TYPE_* enum names are exposed as string constants, so
you can compare against them directly.
# every dbt not-null-style test
platform == PLATFORM_DBT && kind.startsWith("not_null")
# checks the source asset tagged as PII
annotations["dbt.tag"] == "pii"
# anything matching a naming convention, on any platform
name.matches("(?i)^freshness_.*")
# custom assertions that are not platform-native
asset_type == ASSET_TYPE_CUSTOM_TEST && !is_platform_native
Prefer the structured predicate when it can express your rule — it’s easier to
read at a glance and cheaper to evaluate. Reach for CEL only for the cases it
can’t cover.
Live impact preview
While you edit a rule, the dialog runs a live impact preview against the
checks in your workspace, showing how many checks the rule would match before
you save. A rule with no predicate (an empty structured predicate and no CEL
expression) is flagged as a catch-all — it would match every check at its
priority — and the preview is skipped until you add at least one condition.
Per-check overrides
The Checks section lists every check with its resolved Technical and
Governance categories and the source that produced each one. Workspace admins
can pin a category on an individual check with Set explicit category, which
sets a Technical and/or Governance value that takes precedence over both the
producer-explicit value and any rule match. Clearing both dimensions removes the
override, and the check falls back to its underlying category.
You can also create a rule straight from a check — the rule dialog opens
prefilled with that check’s platform, asset type, package, and kind so it
matches checks shaped like it.
Recategorisation
Whenever you add, edit, or delete a rule, Coalesce Quality enqueues a
recategorisation sweep that re-evaluates existing checks against the
updated rule set. The Check categorisation page shows the sweep’s progress;
new checks are categorised as they are ingested.