diff --git a/docs/concepts/connectors.mdx b/docs/concepts/connectors.mdx index ea81a0f..c2a5f7b 100644 --- a/docs/concepts/connectors.mdx +++ b/docs/concepts/connectors.mdx @@ -82,6 +82,8 @@ When live introspection is unavailable or partial, canonic descends a priority o 5. **Sample-based inference** *(not yet implemented)*. 6. **Hand-authored `semantics/*.yaml`**: validated against the live source before being trusted (below). +Acquisition tier and provenance are independent axes. A tier-2 `dbt` import still enters [reconciliation](/concepts/ingestion-and-reconciliation#reconciliation) at provenance `inferred`, exactly like raw introspection, so it never displaces a `human_curated` or `board_approved` fact. Its acquisition tier only breaks ties **within** the `inferred` band: when a modeling-code definition and a raw-introspection fact describe the same relation without disagreeing on type, the modeling-code evidence is preferred. Structural fields (`grain`, `joins`, `measures`) still always require review regardless of confidence. See a [worked example](/concepts/ingestion-and-reconciliation#example-adding-a-definition-connector-after-an-initial-apply). + Partial capability is never silent: if only some relations are introspectable, the gap is reported rather than omitted. ## Schema validation probe diff --git a/docs/concepts/ingestion-and-reconciliation.mdx b/docs/concepts/ingestion-and-reconciliation.mdx index 86794ce..4b27ca2 100644 --- a/docs/concepts/ingestion-and-reconciliation.mdx +++ b/docs/concepts/ingestion-and-reconciliation.mdx @@ -55,6 +55,14 @@ The `answer_outcome` row is a deliberate exception to that tier logic: it always A conflict is never resolved by silent overwrite. The worst case is a flagged contradiction a human resolves: contradictions ride into the review surface (a PR comment in headless mode) and don't fail a run by default. +### Example: adding a definition connector after an initial apply + +Say a connection starts out queryable-only. `canonic ingest` runs [live introspection](/concepts/connectors#schema-acquisition-ladder) and proposes semantic sources at provenance `inferred`, the tier every new proposal starts at. `canonic apply` accepts them into `semantics/*.yaml`. Accepting a file this way commits it, but doesn't curate it: it's still `inferred`. + +Now a `dbt` connector is added to the same connection and `canonic ingest` runs again. `extract_definitions` produces definition evidence from the compiled manifest, an acquisition tier above raw introspection, but it still enters reconciliation at provenance `inferred`, same as the existing fact. Provenance and acquisition tier are independent: the two proposals disagreeing on the same relation is not a "existing tier higher" case and not a silent win either way. Instead, the modeling-code evidence is preferred as the tie-break within the `inferred` band, so the run resolves to the "conflicts, tier ≤ proposal" row above: propose an **edit**. That diff lands under `.canonic/pending-diffs//` and goes through [`canonic review`](/cli-reference/review-apply) / [`canonic apply`](/cli-reference/review-apply) exactly like the first round. If the edit touches `grain`, `joins`, or `measures`, it's ineligible for auto-apply no matter how confident the proposal is, per the `never` list under [Propose-only by default](#propose-only-by-default) below. + +Had the file instead been `freeze`d during the first review, the dbt proposal would only flag a contradiction: the existing fact is left untouched regardless of its acquisition tier or confidence, per the "existing frozen" row above. + ## Feedback loop (E11) [`canonic outcome mark`](/cli-reference/status-report#canonic-outcome-mark) records a correct/incorrect ground-truth verdict against a served answer, with an attribution reason-code (`wrong_definition`, `wrong_data`, `wrong_interpretation`, or `unspecified`) when incorrect. Only `wrong_definition` ever implicates the canonical binding that served the answer; the other reason codes are recorded but never feed back into reconciliation or trust. diff --git a/docs/introduction.mdx b/docs/introduction.mdx index 57c61cb..c042930 100644 --- a/docs/introduction.mdx +++ b/docs/introduction.mdx @@ -61,7 +61,7 @@ Every output in these docs is real, captured from a live run, not hand-written; | --- | --- | --- | | Giving the agent raw schema/SQL access | Fluency without correctness; it guesses definitions and picks wrong tables | Resolved canonical definitions, enforced guardrails, never a silent wrong number | | Hand-building a semantic layer from scratch | Months of modeling before any value | Context auto-drafted from your live schema on day one; you review, not author from zero | -| Migrating onto a new metrics platform | Lock-in and a rebuild | canonic **ingests** your dbt / BI tools / docs; it feeds your existing stack, it doesn't replace it | +| Migrating onto a new metrics platform | Lock-in and a rebuild | canonic **ingests** your dbt (definitions), BI tools (usage evidence), and docs (evidence). It feeds your existing stack, it doesn't replace it | | A hosted "AI analytics" SaaS | Your data and definitions leaving your environment | Local-first, fully **air-gapped-capable**: nothing has to leave your machine | What makes it different in one line: **canonic builds the context for you, keeps it honest, and refuses to lie when it isn't sure.**