Canonical metric bindings
A binding (contracts/metrics/<metric>.yaml) resolves a logical metric name to exactly one owning definition:
AMBIGUOUS/UNRESOLVED error listing candidates, so the caller can refuse-and-ask instead of picking wrong.
Beyond single: composable metrics
Not every metric is one measure on one table. The binding’s kind selects a compilation strategy for metrics built from parts:
Because
ratio/weighted_avg components reference other metric names, each component keeps its own guardrails and provenance. A numerator’s guardrails fire automatically wherever it’s used. Every kind also accepts an optional population_filter, applied before aggregation on every leaf, for metrics that are only defined over a restricted population (e.g. excluding test accounts from active_customers). See the compiler for how each strategy actually compiles to SQL.
Guardrails
A guardrail declares a rule the compiler must enforce:severity: error (the default) blocks the query, but severity: warn lets it through with a warnings[] entry instead. mandatory_filter has no “block” outcome to gate this way: its predicate is always injected regardless of severity, and severity: warn there only adds the warnings[] entry on top.
Trust score
Every compiled answer carries a trust tier:caution < provisional < trusted. It is a category with reasons, not a numeric score. It reports confidence in the context behind an answer (provenance, assertion coverage, finality, freshness), never a claim that the number itself is factually correct.
Scoring is worst-signal-dominates. The tier starts at trusted and drops to the lowest tier forced by any active signal, with reasons listing only the signals tied at that worst tier.
A
min_trust guardrail enforces a floor on the served tier for a given context:
canonic audit includes a trust-tier worklist ranking every canonical metric worst-tier-first. See canonic audit.
Finality
Some metrics are served by two physical realizations along a freshness axis, a batch table that’s final, and a real-time table that’s provisional:final or provisional. board_only_final pairs with a restrict_source guardrail so a board_reporting context sees only the final source.
Assertions
An assertion (contracts/assertions/<id>.yaml) is a trusted query → expected-result check:
canonic assert runs every assertion through the compiler and gates on the result: the CI integration that turns “>90% accuracy” from aspirational into measured. canonic query --harness runs matching assertions inline against a single query.