FactCraft

Semantic models · Power BI · AI

AI, built on facts.

Your agents and Copilot are only as right as the numbers you feed them. FactCraft audits your Power BI models, has your key measures validated by the business, and tells you the moment a validated calculation changes. Metadata only, never your data.

Or audit your model now, free and in your browser: nothing leaves your machine.

Before

Audit

After

  1. Net Sales
  2. Gross Margin
  3. Margin %
  4. Turnover
  5. Revenue
  6. KPI_Basket_02
  7. Order Count
  1. Net Sales

    Validated

  2. Gross Margin

    Validated

  3. Margin %

    Validated

  4. Revenue

    Validated

  5. Order Count

    Validated

  6. Average Basket (was KPI_Basket_02)

    Renamed, described

  7. Turnover

    Removed

The seven measures of a fictional sales model, before and after the audit. Point at a measure to trace it.Filled square: validated. Outlined: renamed or described. Struck through: removed.

The problem

The bottleneck isn't the AI model. It's how reliable the facts you give it are.

  • 3 versions

    One number, a different answer per department

    Finance, sales and controlling each have their own revenue. The agent picks one, and nobody knows which.

  • CD_STAT_X

    Names only the author understands

    Cryptic columns, measures with no description, technical columns left visible. A human guesses. An AI makes things up.

  • Column or measure?

    Logic in the wrong place

    A calculated column where a measure belonged, a fact table at the wrong grain: inflated totals, and not a single error message.

Before and after

Same model, same question. Now flip FactCraft on.

Three questions an agent gets every day, asked of a fictional sales model.
  1. Off

    The agent reads the names and descriptions of the measures, picks one or writes its own calculation, and answers with confidence.

  2. On

    The audit pins its findings on the measures that misled it: a description that says nothing, a copy, a stale validation.

  3. Fixed

    The business validates the fixes. The agent reads the model again, and the number changes.

Same question, before and after FactCraft · fictional example

Question to the agent

What was our revenue this year?

What the agent reads in the model

  • [Revenue]“Quantity × list price, before discounts.” validated by the Finance department
    • FC-LIS-02Description that says nothing(fixed)
  • [Net Sales]validated by the Finance department

    Picked

After FactCraft

€4.87M off by 13%

€4.31M

[Revenue] now says what it is, the copy of [Net Sales] is gone: the agent picks [Net Sales], validated by the Finance department.

Example amounts, fictional. After FactCraft, the agent answers €4.31M, instead of €4.87M.

How it works

One model, four moments.

A fictional sales model, read from its TMDL files by the FactCraft engine and audited by it. Scroll: the business validates, a calculation changes, the audit flags it.
  1. 01 · The model

    Your model, as an AI reads it.

    4 tables, 7 measures, 3 relationships. Copilot and agents choose the measure that answers a question from these declarations: names, descriptions, DAX, relationships.

  2. 02 · Validated

    The business validates its key measures.

    On 5 Oct 2026, the Finance department rereads Net Sales, Gross Margin and Margin %. Each validation is written into the model, with a fingerprint of the calculation.

  3. 03 · A change

    A calculation changes. Its validation falls.

    Someone adds shipping costs to Gross Margin. Its fingerprint no longer matches, and Margin %, which calls it, falls with it. Net Sales still holds.

  4. 04 · The audit

    Today's audit pins every finding on its object.

    15 findings, a score of 77 out of 100. Not ready for AI. Hover or select a flagged object to read what is wrong and the proposed fix.

Swipe the diagram sideways to see the whole model.

Sales.SemanticModelNot ready for AI77 / 100*1*1*1SalesNet SalesValidatedGross MarginStaleMargin %StaleTurnoverRevenueKPI_Basket_02Order CountOrder NumberProduct IDCustomer IDDateQuantityNet AmountPurchase CostShipping CostProductProduct IDProduct NameCategoryList PriceCalendarDateYearMonthMonth NumberCustomerCustomer IDCustomer NameRegion

[Turnover] in Sales

  • blockingFC-LIS-01Visible measure without a description

    Proposed fix, to validate with the business: Add a /// description above the measure: what it computes, in which unit, under which rule.

  • importantFC-COH-01Two measures with the same DAX

    Proposed fix, to validate with the business: First check with the business that the two names mean the same figure. If they do, keep a single calculation: replace the DAX of “Turnover” with [Net Sales], or delete “Turnover” if nothing uses it; hiding it is not enough, the measures that reference it still read it. If they do not, one of the two calculations is wrong: correct it.

All 15 findings
  • FC-LIS-01 · Visible measure without a description · [Turnover] in Sales
  • FC-LIS-01 · Visible measure without a description · [KPI_Basket_02] in Sales
  • FC-LIS-01 · Visible measure without a description · [Order Count] in Sales
  • FC-LIS-02 · Description that says nothing · [Revenue] in Sales
  • FC-LIS-03 · Cryptic name on a visible object · [KPI_Basket_02] in Sales
  • FC-LIS-05 · Visible technical column · Sales[Product ID]
  • FC-LIS-05 · Visible technical column · Sales[Customer ID]
  • FC-COH-01 · Two measures with the same DAX · [Turnover] in Sales
  • FC-STR-01 · Bidirectional relationship · Sales[Customer ID] → Customer[Customer ID]
  • FC-STR-02 · Missing or automatic date table · the model
  • FC-IA-01 · Implicit measures allowed · Product[List Price]
  • FC-IA-01 · Implicit measures allowed · Sales[Product ID]
  • FC-IA-03 · Stale validation · [Gross Margin] in Sales
  • FC-IA-03 · Stale validation · [Margin %] in Sales
  • FC-IA-04 · AI instructions missing · the model
Sales.SemanticModel: table Sales, [Net Sales] in Sales (validation holds), [Gross Margin] in Sales (stale validation), [Margin %] in Sales (stale validation), [Turnover] in Sales, [Revenue] in Sales, [KPI_Basket_02] in Sales, [Order Count] in Sales, Sales[Order Number], Sales[Product ID], Sales[Customer ID], Sales[Date], Sales[Quantity], Sales[Net Amount], Sales[Purchase Cost], Sales[Shipping Cost]; table Product, Product[Product ID], Product[Product Name], Product[Category], Product[List Price]; table Calendar, Calendar[Date], Calendar[Year], Calendar[Month], Calendar[Month Number]; table Customer, Customer[Customer ID], Customer[Customer Name], Customer[Region]; relationships Sales[Product ID] → Product[Product ID], Sales[Customer ID] → Customer[Customer ID] (both directions), Sales[Date] → Calendar[Date].

Validated facts

Validated by the business. Flagged the moment it changes.

Power BI certifies whole models. FactCraft validates a measure, and knows when that validation no longer holds. Coming with the validated facts subscription.
  • Validated by the business

    The owner reads the definition: what the measure computes, in which unit, under which rule. The validation is written into the model itself: who, when, and a fingerprint of the calculation.

  • A fingerprint of the calculation

    It covers the measure's name, description, format and DAX, and the calculation of every measure it calls. Reformatting the DAX leaves it intact; changing the calculation does not.

  • Flagged the moment it changes

    The audit reports the stale validation, and a check in your CI pipeline stops before an AI quotes a number nobody has reread.

In the model, not beside it

annotation FactCraft_Validation = {"by":"Finance department","on":"2026-10-05","fingerprint":"sha256:…"}

A TMDL annotation on the measure: it travels with your .pbip project, reads in a git diff, and Power BI keeps it without interpreting it.

TMDLSales.SemanticModel / tables / Sales.tmdl
/// Gross margin in euros: net sales minus the purchase cost of the products sold.measure 'Gross Margin' =    [Net Sales] - SUM ( Sales[Purchase Cost] )  formatString: #,0 €  annotation FactCraft_Validation = {"by":"Finance department","on":"2026-10-05",…}

Validated fact

by the Finance department, 5 Oct 2026 · fingerprint sha256:da9b…3c53

The Gross Margin measure carries the validation of the Finance department. When its calculation changes, the validation falls and FactCraft says so.

The session

One measure at a time, in the words of the business.

The data team prepares the key figures to validate; the business goes through them in a session, without DAX. Below, the validation screen on the example model, with the Finance department, on 31 Oct 2026. Coming with the validated facts subscription.
Validation screen · SessionSales.SemanticModel · Finance department

Measure 1 of 6

Is this what your team means by “Gross Margin”?

“Gross margin in euros: net sales minus the purchase cost of the products sold.”

Its definition or its calculation changed after Finance department validated it on 5 October 2026: reread it before renewing.

It uses

Net Salesvalidated

The measure

Gross Marginchanged since validated

Yes, that’s itNot quite (the answer given)

Skip for now

How it is calculated
[Net Sales] - SUM(Sales[Purchase Cost]) - SUM(Sales[Shipping Cost])
The validation screen in session with the Finance department, on the example model: one measure at a time, the answer given, then the lines written into the model files.

What we do

From raw model to validated answers.

  1. 01

    AI-ready audit

    Free, in your browser

    FactCraft reads your semantic model (.pbip, TMDL) and scores it out of a hundred: readability, consistency, structure, AI readiness. Every finding comes with a proposed fix.

  2. 02

    Validated facts

    Subscription · coming soon

    Your key measures, validated by the business and fingerprinted in the model. The moment a validated calculation changes, the audit and your CI pipeline flag it.

    Join the waitlist
  3. 03

    Agents wired to your measures

    Next

    An MCP server on top of the semantic model: the agent answers through your validated measures, never by inventing its own calculation.

  4. 04

    Data and AI engagements

    Engagement

    Guided modeling, validation workshops with the business, and the whole chain made usable by AI, from Databricks to the semantic model, inside your environment.

Where it sits

In your pipeline, before an AI reads the model.

With the validated facts subscription, FactCraft checks your model's files in git on every change, and your pipeline can stop before a model whose validations no longer hold is published. It checks the model, not the answers: your data does not go through it.
  1. Model authors

    Power BI Desktop, Tabular Editor

    The business

    Validates the key measures

  2. Your semantic model

    TMDL files, in git

  3. FactCraft check

    Audit and validated facts, in your CI

    Coming soon

  4. Published model

    Power BI service, Fabric

  5. Copilot

    In Power BI

    Data agents

    In Fabric

    Your agents

    Querying the model

The audit

A score, the rules, the fixes.

The report fits on one page: where your model stands, what blocks Copilot and agents, and what to fix first. What is measured is written in numbers, not adjectives.

The audit runs in your browser: your model never leaves your machine. Sample report on a fictional model, also in JSON. The audit also runs in French.

Sales.SemanticModel

4 tables · 7 measures · 3 relationships

77 / 100

Not ready for AI

  • Readability81

    Fail · Visible measure without a description, 3 of 7

  • Consistency95

    Fail · Two measures with the same DAX, 1 of 7

  • Structure86

    Fail · Bidirectional relationship, 1 of 3

  • AI readiness56

    Fail · Implicit measures allowed, 2 of 8

Validated facts

Validated facts: 1 of 7 visible measures

First fix · FC-LIS-01 · to validate

[Turnover] in Sales: Add a /// description above the measure: what it computes, in which unit, under which rule.

Where to calculate?

At the source, in Power Query, as a column or as a measure.

The question behind every calculation. Here is how we answer it.
Business needWhereWhy
Margin per customer, filterableMeasureIt has to respond to the report's filters.
Age band for segmentationPower QueryA fixed value per row, compressed better than a DAX column.
Conversion at the daily exchange rateSourceA rule shared by every tool, not just Power BI.
Customer status shown in a slicerColumnRare: only when it depends on another table in the model.

Security

We read your metadata. Not your rows.

  • Schemas and definitions only

    Table, column and measure names, descriptions, DAX and relationships. Never a single row of data.

  • Runs in your browser

    The free audit is computed in the page, which sends nothing. Load it, cut your network: it still works.

  • Inside your tenant

    On engagements, we work with your access, in your Fabric or Databricks, or on a copy of the model under NDA, deleted afterwards.

What the audit opens

Its TMDL files and, if the project has them, its AI instructions for Copilot: nothing else. The data cache that Power BI Desktop keeps beside them is never opened by the audit, in your browser or on the command line.

  • Sales.SemanticModel/
  • .pbi/
  • cache.abfData cache, never opened
  • editorSettings.jsonNot read
  • definition/
  • tables/
  • Calendar.tmdlRead
  • Customer.tmdlRead
  • Product.tmdlRead
  • Sales.tmdlRead
  • database.tmdlRead
  • model.tmdlRead
  • relationships.tmdlRead
  • definition.pbismNot read
  • diagramLayout.jsonNot read

Who's behind FactCraft

Built by a semantic model practitioner.

Omar Arrim, data and Power BI consultant. FactCraft turns what his engagements taught him into rules anyone can run.
  • 6 years

    of engagements at a large European energy group, across several departments.

  • ~50M rows

    in SSAS Tabular semantic models, with advanced DAX.

  • .pbip

    Creator of ChartCraft, which generates Power BI projects.

Source: the founder's own engagements.

From facts to decisions

FactCraft makes the facts reliable. ChartCraft makes them readable.

FactCraft

AI, built on facts.

Upstream: data, semantic models, validated measures, agents.

ChartCraft

Decisions, by design.

Downstream: Power BI reports designed around decisions, delivered as .pbip.

Discover ChartCraft

Know what Copilot will quote, before it does.

Run the free audit in your browser, then send us its JSON report: object names, never your data. We review it for free and come back with the priority fixes and a plan to validate your key measures.

A full audit, run on your model's definition shared under NDA, hands back an audit dossier like this sample, built on a fictional model.

contact@factcraft.io