Support
Log In

Migration Overview

Bring your existing semantic layer — Looker, Tableau, Power BI, and more — into Credible as governed Malloy models

You've probably already built a semantic layer — whether or not you call it one. And you may well have more than one: a Looker instance from one team, a Tableau data source from another, DAX measures in Power BI, a Snowflake semantic view — the sprawl that comes with acquisitions, multiple business units, or just different teams reaching for different tools. Each holds years of business logic your team trusts.

Credible captures that meaning — from one tool or many — and consolidates it into governed data models in Malloy: readable, versioned in Git, and delivered as trusted context to every surface.

Your source model is prior art, not a spec to transpile line-for-line: the agent reads it for intent, keeps the logic worth keeping, drops what's tool-specific, and rebuilds the analytical domain as governed Malloy — running on the same open-source agent skills that power the rest of Credible, extended to read your source tool.

Migrate the Domain, Not the Dashboard

In practice there isn't one dashboard — there are dozens or hundreds, uneven in quality and usage, a handful carrying most of the traffic. Migration shouldn't recreate them tile for tile. Our migration approach anchors on the ones that matter and captures the analytical domain beneath them — the fields, metrics, and relationships actually in use, plus what they depend on — modeled by question rather than by tile, so the result rebuilds what those dashboards show and answers the follow-ups they imply. How sharply it can tell used from merely defined depends on the context: with query logs or system activity (as Looker has), the trim is precise; otherwise the agent works from the data models and the SQL behind your key dashboards.

How It Works

Migration is the Context step at full stretch. The meaning already exists — in your model code (LookML, TMDL, a YAML model, a semantic-view definition), in the dashboards and query logs built on it, and in the docs and decks written around it — and the agent connects to wherever it lives and brings it in. Where the source exposes APIs or MCP tools (MCP is the open protocol that connects agents to tools), it connects over them to read the live model and validate against it. Collecting context finds what's written down; it can't find judgment. Your team supplies that in the Model step, and the result hands off to the same Deliver path every model uses. Then it runs four steps:

Read

Inventory the source model — tables, dimensions, measures, joins, and the logic buried in calculated fields and filters.

Translate

Map each concept to its Malloy equivalent — sources, joins, dimensions, measures, views — keeping the logic and dropping tool-specific presentation and performance constructs.

Annotate

Add #(doc) and #(index) metadata tags — documenting what each field means and how to use it (units, rules, caveats) and indexing its values — so an agent finds the right field and uses it correctly.

Validate

Where a connection is available, run the model against live data and compare it row-by-row to the source's own engine — confirming a match before delivery.

The agent runs in the Credible App or in your IDE via local development — the same skills either way. A live connection isn't required to produce the model: without one you still get the full translation, ready to validate once a connection — the source engine or the warehouse behind it — is in place.

What the Agent Keeps, Skips, and Flags

Not every line in a source model belongs in the data model:

What it coversExamples
KeepBusiness logic and structureDimension and measure names, aggregation formulas, primary keys, joins, CASE logic, filtered aggregates, currency/percent formats
SkipDead weight & tool plumbingStale, redundant, or unused fields and reports; drill paths, action links, raw HTML and cosmetic styling
FlagJudgment calls for a humanLogic that may belong upstream (warehouse or dbt), synthetic primary keys, duplicate or conflicting field definitions

Presentation isn't ignored where it carries meaning: number and currency formats become render tags, a conditional-format rule ("flag when churn tops 10%") becomes model logic, and whole dashboards are rebuilt — often improved — as data apps. What's genuinely dropped is what's dead — stale, redundant, or unused — or pure tool plumbing with no meaning. Where Malloy expresses something differently — DAX filter context, table calculations, metric_time — it's re-worked explicitly, never dropped silently; each source guide spells out how.

Proving Parity

When there's query access, the agent validates row-by-row — running each original metric through the source's engine (or equivalent SQL against the same warehouse) and diffing it against the migrated Malloy. Matching numbers confirm the translation; but a source of truth can carry its own errors, ambiguities, and inconsistencies, so any delta is confirmed and flagged for deeper investigation, not silently reconciled. It produces a coverage report — modeled, renamed, deferred, or skipped, each with a reason — plus any discrepancies it surfaced.

More Than a Reformat

A before/after looks like a translation — same metrics, cleaner syntax. That's the fidelity check; the reasons to migrate are what the new model can do that the old one couldn't:

  • It answers the next question. Malloy is composable — views nest, chain, and reuse as sources — so the model handles follow-ups the original dashboard never exposed.
  • AI-usable meaning. #(doc) and #(index) tags compressed into the engine's concept index tell an agent what a field means, how to use it, and what values it holds — so it finds the right field and queries it correctly, not just by matching a name.
  • Correct by construction. Malloy's symmetric aggregates stop measures double-counting across one-to-many joins — the silent bug in hand-written SQL and BI extracts.
  • It's real code, and it compiles. A typed language catches bad references and type mismatches at build time, not as wrong numbers in a dashboard — and it's concise, turning sprawling DAX or LookML into a few readable lines.
  • One model, every surface. One governed model serves agents over MCP, dashboards, data apps, and the REST APIs, with access control enforced at the gateway on every query — open, in Git, no lock-in.

A Worked Example

The payoff is a question the old dashboard couldn't answer — say, how revenue is pacing against target. With the sales domain modeled and a targets source joined in, that's one query:

// #(doc) Monthly revenue vs. target, with attainment
query: revenue_vs_target is sales -> {
  group_by: order_month is order_date.month
  aggregate:
    actual is total_revenue
    target is targets.monthly_target
    # percent
    attainment is actual / target
}

Supported Sources

Each has a dedicated guide with a concept-to-Malloy mapping and a before/after: Looker, Sigma, Omni, Cube, Power BI, Tableau, Snowflake, dbt, and Databricks.

Don't see your tool? The same method applies to any semantic layer that exposes its definitions. Contact us and we'll walk through it.

Next Steps

On this page