Blog · AI and self-service analytics
Why self-service analytics fails without one governed definition of each metric, how to run a versioned registry where net revenue v4 supersedes v3 on a date, how scope is applied in the data layer rather than a prompt, and what an audit trail per answer has to record.
Self-service analytics has a predictable failure. Three teams ask the same question, get three numbers, and the meeting is about which number is right rather than what to do. The cause is never the tool. It is that revenue meant three different things. This guide sets out the governance that fixes it: one definition per metric, versioned, applied in code, with scope in the data layer and an audit trail on every answer.
A metric definition is a formula over the underlying columns, with filters, grain and owner:
| Metric | Definition | Grain | Owner | Version | Effective |
|---|---|---|---|---|---|
| Net revenue | bookings − credits − churn | monthly | Finance | v4 | 2026-07-01 |
| Coverage | accounts touched ÷ accounts assigned | 90-day window | RevOps | v2 | 2026-03-01 |
| Share of wallet | our revenue ÷ estimated account spend | quarterly | Sales Ops | v3 | 2026-01-01 |
| Active account | ≥ 1 order in trailing 90 days | daily | RevOps | v1 | 2025-09-01 |
The definition is applied by a function, and every screen and every assistant answer calls that function. Nobody recomputes revenue in a spreadsheet, because there is nowhere for a second definition to live.
When finance changes net revenue to exclude a new category of credit, v5 takes effect on a date. From that date, every answer uses v5 and says so. Answers given before it used v4 and say so. The question "why is last quarter's number different in this deck" has an answer: the definition changed, here is what changed, here is the number under each.
The registry keeps every version. Nothing is overwritten.
A rep asks "what is my coverage". The system resolves "my" to the rep's account identifiers before any row is read, in the data layer, from the directory. The coverage function receives only those rows. The model that phrased the answer never saw the other reps' accounts and cannot leak them, because there is nothing to leak.
The alternative, telling a model "only answer about this rep's accounts" while giving it all the rows, is a permission the model can misread. The difference matters to compliance and it matters in a bank.
Every answer records:
That trail is exportable, and it is what turns "the assistant said" into "the coverage function, v2, on these 214 rows, said". Finance can check it; a regulator can read it.
Two answers to "what was net revenue in Q2", one asked in June, one in August.
| Asked | Version in force | Answer | Trail |
|---|---|---|---|
| 18 June | v4 | $4.62m | revenue_calculator(period=Q2, def=net_revenue.v4) |
| 22 August | v5 | $4.51m | revenue_calculator(period=Q2, def=net_revenue.v5) |
The two numbers differ by the credits v5 excludes. Both are right under their definition. The registry says which is which, and the August answer can note that the June figure was computed under v4.
Definitions in a wiki. A definition that is documented but not executed is a suggestion. The function is the definition.
Versions without effective dates. A change with no date cannot be applied to history. Every version has one.
Scope in the prompt. See above. It is the difference between a guarantee and a hope.
Trail without rows. An audit trail that records the question and the answer but not the rows cannot be rerun. Record the rows, or a stable reference to them.
Once the registry exists and scope is in the data layer, self-service can be opened to every team, because every answer agrees with finance and every answer can be traced. Covirage runs on this model. The metrics governance page describes it.
The name, the formula in terms of the underlying columns, the filters, the grain, the owner, the version number and the date it took effect. Net revenue v4: bookings minus credits minus churn, monthly, owner finance, effective 1 July 2026.
Because answers given under the old definition still exist in slide decks and emails. When someone asks why last quarter's number differs from this quarter's, the answer is often that the definition changed, and only a version history can say so.
In the data layer. A rep's scope resolves to their account identifiers before any query runs, so the assistant cannot leak what it never saw. Scope in a prompt is a suggestion; scope in the data layer is a guarantee.