Markdown Editor

Semantic Model Specification Template (Metrics Layer)

Datasets and entities, relationships and join keys, dimensions and time grains, measures, metric types, filters, access rules, certification, tests, interchange

データエンジニアリング・ガバナンスフルdbt MetricFlow v0.213.0 concepts; Apache Ossie draft (emerging)semanticmodelspecification

使い方: Use it when you define a governed semantic model or metrics layer that BI tools, notebooks and AI assistants must query. Fill the datasets, entities and relationships first, then the metrics with links to their Metric Definitions. The main pitfall is a many-to-many join that silently double counts revenue.

プレビュー

Semantic Model Specification: [Model name]

Specification of one governed semantic model (metrics layer): the datasets and entities it covers, relationships and join keys, dimensions and time grains, measures and aggregations, metrics by type, default filters, access rules, owners, certification, tests, change control and export to an open interchange format. Concepts are aligned with dbt MetricFlow (Apache License 2.0, release v0.213.0 of 2026-09-10) and kept tool-neutral; Apache Ossie (incubating), formerly Open Semantic Interchange, is named as an emerging draft interchange format. Replace every [bracketed] value and every row marked Example.

Document control

FieldValue
Document ID[SEM-ORD-001] (Example)
Semantic model name[orders]
Subject area[Orders and revenue]
Semantic engine and version[MetricFlow vX.Y / BI tool semantic layer / other]
Source project[corvid_analytics, marts/orders] (Example)
Version[1.0]
Status[Draft / In review / Certified / Deprecated]
Business owner[@head-of-commerce-analytics]
Technical owner[@analytics-engineer]
Owner[@business-owner]
Approvers/reviewers[@data-governance-lead], [@finance-controller], [@security-reviewer]
Classification[Internal / Confidential]
Contains personal data[Yes, pseudonymous customer key / No]
Last updatedYYYY-MM-DD
Next certification reviewYYYY-MM-DD

Approvals

RoleNameDecisionDate
Business owner[@name][Certified / Changes requested]YYYY-MM-DD
Data governance lead[@name][Approved / Changes requested]YYYY-MM-DD
Finance controller (revenue metrics)[@name][Approved / Changes requested]YYYY-MM-DD

Revision history

VersionDateAuthorChange
0.1YYYY-MM-DD[@author]First draft
1.0YYYY-MM-DD[@author]Certified for production use

Contents

1. Purpose and scope

The [Orders] semantic model gives every consumer one governed way to ask questions about orders, revenue, customers and products at Corvid Commerce (Example). Once certified, dashboards and notebooks must query revenue and order metrics through this model rather than writing their own SQL against the marts.

In scope (Example)Out of scope (Example)
Orders, order lines, refunds, gross and net revenueCheckout funnel events (Checkout model, SEM-CHK-001)
Customers (pseudonymous key, segment, region)Marketing attribution and spend
Products and categoriesInventory and supply
Daily, weekly, monthly and fiscal timeIntraday operational monitoring

Questions the model must answer (Example):

  1. What were net revenue and order count by region and channel last fiscal month, compared with the same month last year?
  2. What is average order value by customer segment over a rolling 90 days?
  3. What share of orders were refunded within 30 days of purchase?

2. Model overview

ElementCount (Example)
Datasets6 (section 3)
Entities6 (order, order_line, customer, product, refund, date_day)
Dimensions7 (section 5)
Measures or simple aggregations6 (section 6)
Metrics (all types)10 (section 7)
Certified metrics7

3. Datasets and entities

Every dataset must be a public mart with an enforced contract (see rule DBT-051 in dbt Project Standard, data/dbt-project-standard), or a table covered by a Data Contract (data/data-contract).

Dataset IDPhysical relationGrainContractDefault time dimension
DS-01 (Example)marts.orders.fct_orders (v2)One row per confirmed orderEnforced dbt model contract; built from lakehouse.sales.orders, which is covered by Data Contract DC-ORD-001ordered_at
DS-02 (Example)marts.orders.fct_order_linesOne row per order lineEnforced dbt model contractordered_at
DS-03 (Example)marts.orders.fct_refundsOne row per refundEnforced dbt model contractrefunded_at
DS-04 (Example)marts.orders.dim_customersOne row per customer (current state)Enforced dbt model contractNone
DS-05 (Example)marts.orders.dim_productsOne row per product (current state)Enforced dbt model contractNone
DS-06 (Example)marts.core.dim_calendarOne row per day, with fiscal periodsEnforced dbt model contractdate_day

Column lineage to the Orders data contract (Example): fct_orders keeps order_id, customer_id, channel, net_amount, currency and ship_country with the contract names. The contract's order_ts is renamed ordered_at in staging under rule DBT-013 of dbt Project Standard; the meaning (time the order was confirmed, UTC) is unchanged. The deprecated region_code is not used; the region is derived from ship_country (DIM-04).

Entities are the keys that identify business objects and allow joins. Use the four entity roles below; most semantic engines distinguish them in the same way.

RoleMeaningJoin behaviour
PrimaryExactly one row per value, and every value of the entity is presentSafe target of a many-to-one join
UniqueAt most one row per value, but the dataset may hold a subsetSafe target, but some keys may not match
ForeignZero, one or many rows per valueSource side of a join; never a target
NaturalA business key, or combination, that identifies a real-world record and may change over timeUsed for slowly changing dimensions with validity periods
Entity IDEntityDatasetColumn or expressionRole
ENT-01 (Example)orderDS-01order_idPrimary
ENT-02 (Example)customerDS-01customer_idForeign
ENT-03 (Example)customerDS-04customer_idPrimary
ENT-04 (Example)orderDS-02order_idForeign
ENT-05 (Example)productDS-02product_idForeign
ENT-06 (Example)productDS-05product_idPrimary
ENT-07 (Example)order_lineDS-02order_line_idPrimary
ENT-08 (Example)refundDS-03refund_idPrimary
ENT-09 (Example)orderDS-03order_idForeign
ENT-10 (Example)date_dayDS-06date_dayPrimary
[ENT-NN][entity][DS-NN][column][Role]

customer_id is a pseudonymous key (classified Confidential with the PD and PSEUDO flags in the Orders data contract); the semantic model never exposes names, e-mail addresses or other direct identifiers, and does not offer customer_id as a dimension.

4. Relationships and join keys

Rel IDFrom (dataset.entity)To (dataset.entity)CardinalityJoin typeUnmatched rows (Example)
REL-01 (Example)DS-01.customerDS-04.customerMany to oneLeftShown as "Unknown customer"; test alerts above 0.5 percent
REL-02 (Example)DS-02.orderDS-01.orderMany to oneLeftMust be zero; test fails on any orphan line
REL-03 (Example)DS-02.productDS-05.productMany to oneLeftShown as "Unknown product"
REL-04 (Example)DS-03.orderDS-01.orderMany to oneLeftMust be zero
[REL-NN][from][to][Cardinality][Join type][Handling]

Rules:

  • SEM-001 Allow only many-to-one and one-to-one joins toward a primary or unique entity. A many-to-many path must be resolved by a bridge dataset with its own grain, documented here.
  • SEM-002 Limit join depth to [2] hops (Example); beyond that, build a mart.
  • SEM-003 State the join type explicitly; never rely on an engine default.
  • SEM-004 For dimensions that keep history, state whether metrics use the value at event time or the current value. Default (Example): the value at event time for region, the current value for customer segment.

5. Dimensions and time grains

Dimensions are either categorical (labels to group and filter by) or time (dates and timestamps that roll up to coarser grains).

Dim IDDimensionDatasetTypeAllowed values or grainDescription (Example)
DIM-01 (Example)order__ordered_atDS-01TimeDay, week, month, quarter, yearTime the order was confirmed, UTC (contract order_ts)
DIM-02 (Example)order__channelDS-01Categoricalweb, app, marketplace (contract enumeration); null before 2022 shown as "Unknown"Channel that captured the order
DIM-03 (Example)order__ship_countryDS-01CategoricalISO 3166-1 alpha-2 codesCountry of delivery at order time
DIM-04 (Example)order__ship_regionDS-01CategoricalEMEA, AMER, APACDerived from ship_country through the seed seed_country_region; replaces the deprecated region_code
DIM-05 (Example)customer__segmentDS-04Categoricalnew, returning, vipCurrent segment, recalculated daily
DIM-06 (Example)product__categoryDS-05CategoricalCategory tree level 1Current category
DIM-07 (Example)refund__refunded_atDS-03TimeDay and coarserTime the refund was issued, UTC
[DIM-NN][name][DS-NN][Type][Values][Description]

Time rules:

  • SEM-010 Define one metric time per measure (the aggregation time dimension). Consumers asking for "revenue by month" get months of that time dimension unless they choose another.
  • SEM-011 Store timestamps in UTC; derive local or fiscal periods through a calendar dataset, not through per-query conversions.
  • SEM-012 Declare the smallest grain each time dimension supports. Consumers may roll up to coarser grains only.
  • SEM-013 Define the fiscal calendar once (Example: fiscal year starts 1 February, weeks start Monday, ISO week numbering) and expose fiscal grains as separate dimensions.

6. Measures and aggregations

Measures are the base aggregations of a column or expression. Some engines declare them separately; from dbt v1.12 the dbt semantic layer expresses them as simple metrics (type: simple with agg and expr) instead of a separate measures list. Either way, list them here, because every other metric type is built from them. On an engine without separate measures, each row below becomes a simple metric, usually hidden from consumers when it is only an input.

Measure IDNameDatasetExpressionAggregationAdditivityAgg time dimension
MEA-01 (Example)order_countDS-01order_idCount distinctAdditive, because each order has one order date and one value per dimensionordered_at
MEA-02 (Example)gross_revenue_eurDS-02quantity * unit_price_eurSumFully additiveordered_at
MEA-03 (Example)discount_eurDS-02discount_eurSumFully additiveordered_at
MEA-04 (Example)refund_amount_eurDS-03refund_amount_eurSumFully additiverefunded_at
MEA-05 (Example)customer_countDS-01customer_idCount distinctNon-additiveordered_at
MEA-06 (Example)net_amount_eurDS-01net_amount converted to EURSumFully additiveordered_at
[MEA-NN][name][DS-NN][expression][Sum / Count / Count distinct / Min / Max / Average / Median / Percentile][Additivity][time dimension]
  • SEM-020 Every monetary measure states its currency in the name and the conversion rule in the description (Example: converted to EUR at the daily reference rate of the order date).
  • SEM-021 Mark non-additive and semi-additive measures; dashboards must not total them across the non-additive dimension.
  • SEM-022 Percentile and median measures state whether they are exact or approximate on the engine in use.

7. Metrics

Metric types follow the five types used by MetricFlow; most semantic layers support equivalents.

TypeBuilt fromTypical use
SimpleOne measure, optionally filteredCounts and sums
RatioA numerator metric divided by a denominator metricRates and averages that must be computed after aggregation
CumulativeOne measure over a running or trailing window, or grain to dateRolling 90-day customers, month to date revenue
DerivedAn expression over other metrics, optionally with time offsetsGrowth versus last year, revenue after refunds
ConversionEntities that perform a base event and then a conversion event within a windowRefund within 30 days, repeat purchase
Metric IDName and labelTypeInputsMetric definitionCertifiedOwner (Example)
MET-ORD-001 (Example)orders, "Orders"SimpleMEA-01MET-ORD-001 docYes[@commerce-analytics]
MET-REV-001 (Example)net_revenue, "Net revenue"SimpleMEA-06 (contract measure total_net_amount)MET-REV-001 docYes[@finance-analytics]
MET-REV-002 (Example)gross_revenue, "Gross revenue"SimpleMEA-02MET-REV-002 docYes[@finance-analytics]
MET-REV-003 (Example)average_order_value, "Average order value"Rationet_revenue / ordersMET-REV-003 docYes[@commerce-analytics]
MET-REV-004 (Example)net_revenue_yoy_growth, "Net revenue growth vs last year"Derivednet_revenue and net_revenue offset by 1 yearMET-REV-004 docYes[@finance-analytics]
MET-REV-005 (Example)discounts, "Discounts"SimpleMEA-03Used by TST-07No (input only, hidden)[@finance-analytics]
MET-REV-006 (Example)refunds, "Refunds"SimpleMEA-04MET-REV-006 docYes[@finance-analytics]
MET-CUS-002 (Example)customers, "Customers"SimpleMEA-05Input to MET-CUS-001No (input only, hidden)[@crm-analytics]
MET-CUS-001 (Example)active_customers_90d, "Active customers (90 days)"CumulativeSimple metric MET-CUS-002 (customers, over MEA-05), trailing 90 daysMET-CUS-001 docYes[@crm-analytics]
MET-ORD-002 (Example)refund_rate_30d, "Refund within 30 days"ConversionBase: order; conversion: refund; window 30 days; entity: orderMET-ORD-002 docNo (in review)[@commerce-analytics]
[MET-XXX-NNN][name, label][Type][Inputs][Link][Yes / No][@owner]

Net revenue (MET-REV-001) is the governed metric that the Orders data contract names for its measure total_net_amount: the sum of net_amount (order value after discounts, before tax and shipping) for confirmed orders that are not cancelled. This model implements it as a simple metric over MEA-06, converted to EUR with the SEM-020 rule, so a question about "net revenue" gets the same answer from the contract's verified statement, from SQL on the mart and from the semantic layer. Refunds are reported separately (MET-REV-006) and are not deducted from net revenue. Gross revenue less discounts at line grain must equal net revenue at order grain (TST-07). Derived and ratio metrics take metrics as inputs, never measures; that is why discounts and customers appear as hidden simple metrics.

Rules:

  • SEM-030 Every certified metric has exactly one Metric Definition (data/metric-definition) with the same ID. The definition owns the business meaning; this specification owns the implementation.
  • SEM-031 Compute ratios from aggregated numerator and denominator, never by averaging row-level ratios.
  • SEM-032 Labels are unique across all certified models.
  • SEM-033 Derived metrics with time offsets state how missing prior periods are shown (Example: null, never zero).

Engine-neutral sketch of one ratio metric (Example):

metric:
  id: MET-REV-003
  name: average_order_value
  label: Average order value
  type: ratio
  numerator: net_revenue
  denominator: orders
  unit: EUR
  certified: true
  owner: "@commerce-analytics"
  definition: data/metric-definition MET-REV-003

Translate the sketch into the syntax of your engine; property names differ between engines and releases.

8. Filters and default constraints

Filter IDApplies toCondition (plain words)Reason (Example)
FLT-01 (Example)All order metricsExclude test orders created by internal accountsTest traffic in production
FLT-02 (Example)All order metricsExclude orders with status cancelled (cancelled before shipment)Not a sale; same rule as the Orders data contract
FLT-03 (Example)MET-REV-001, MET-REV-002, MET-REV-005Include only confirmed orders (the grain of the Orders data contract)Revenue counted at order confirmation, as in the contract's verified statement
FLT-04 (Example)MET-CUS-001Exclude customers who requested erasurePrivacy rights; aggregate history stays, the key is removed
[FLT-NN][metrics][condition][reason]
  • SEM-040 Model-wide filters are applied in the marts, not in the semantic layer, so that SQL users get the same rows. Metric-specific filters live on the metric.
  • SEM-041 Every filter appears in the Metric Definition of each affected metric (section "Filters and exclusions" of that template).

9. Access rules

Rule IDSubject (role or group)ScopeRuleEnforced in (Example)
ACC-01 (Example)All employeesMetrics MET-ORD-001, MET-REV-003Read, all regionsSemantic layer role
ACC-02 (Example)Regional managersAll metricsRows limited to their own order__ship_regionRow access policy on marts
ACC-03 (Example)Finance and the executive teamMET-REV-001 to MET-REV-006Read, all regions, all grainsSemantic layer role
ACC-04 (Example)External partnersNoneNo access to this modelNot granted
ACC-05 (Example)AI assistants and service accountsCertified metrics onlyRead with the calling user's identity, never a shared superuserSemantic layer API token per user
[ACC-NN][role][scope][rule][layer]
  • SEM-050 Enforce row-level rules in the data platform (row access policies) or in a semantic layer that every consumer must use; record where in this table.
  • SEM-051 Apply a minimum group size of [10] customers (Example) to any metric broken down by customer attributes, to limit re-identification from small cells.
  • SEM-052 Identity and role mapping follow IAM Solution Design (security/iam-solution-design).

10. Ownership and certification

RoleResponsibilityPerson
Business ownerApproves meaning and certifies metrics[@business-owner]
Technical ownerImplements, tests and deploys the model[@analytics-engineer]
Metric ownersOwn individual Metric DefinitionsSee section 7
Data stewardMaintains descriptions, glossary links and classification[@data-steward]

Certification criteria (all required):

  1. The metric has an approved Metric Definition with the same ID.
  2. Every input dataset is a contracted public mart.
  3. Tests in section 11 pass for [14] consecutive days (Example).
  4. The value reconciles with the agreed reference (section 11, TST-04).
  5. Access rules in section 9 are implemented and tested.
  6. Owners are named and reachable.

Certification lasts [12 months] (Example) or until the logic changes, whichever comes first. Decertify a metric when its owner leaves without a successor or when reconciliation fails twice in a row.

11. Tests and validation

Test IDWhat it checksMethodFrequencyFailure action (Example)
TST-01 (Example)Model definitions parse and validate against the warehouseSemantic engine validation in CIEvery pull requestBlock merge
TST-02 (Example)Entity keys are unique where declared primaryData tests on martsEvery buildBlock deploy
TST-03 (Example)No orphan rows on REL-02 and REL-04Relationship testsEvery buildBlock deploy
TST-04 (Example)Net revenue by month equals finance ledger total within 0.5 percentReconciliation queryDailyAlert finance analytics; decertify after two failures
TST-05 (Example)Saved queries for top 10 dashboard questions return expected values on a fixed fixtureRegression snapshotEvery pull requestBlock merge
TST-06 (Example)Row access policy returns only own region for a test regional managerAccess test with test identityWeekly and on changeBlock deploy
TST-07 (Example)gross_revenue - discounts per day equals net_revenue (the contract measure total_net_amount, converted to EUR with the SEM-020 rule) within 0.1 percent (same tolerance as DQ-ORD-004)Reconciliation queryDailyAlert finance analytics; block certification
[TST-NN][check][method][frequency][action]

Monitor data quality thresholds from Data Quality Standard (data/data-quality-standard); this section adds the tests that are specific to the semantic layer.

12. Change control and versioning

Change classExamplesApprovalNotice to consumers (Example)
AdditiveNew dimension, new uncertified metricTechnical ownerRelease note
CorrectiveBug fix that changes a certified numberBusiness owner and metric ownerAnnouncement before deploy, with old and new values
BreakingRename or remove a metric or dimension, change a grain or a joinBusiness owner and data governance lead[30 days] with a deprecation period
Definition changeNew meaning of a certified metricMetric owner, business owner, finance for revenueNew Metric Definition version, [30 days] notice
  • SEM-060 Keep a deprecated metric available, labelled as deprecated, for the notice period, and point it to its replacement.
  • SEM-061 Version this document with every certified change and list affected metrics in the revision history.
  • SEM-062 Record lineage from metrics to marts to sources in the data catalogue so impact analysis is possible before a change.

13. Consumers and interchange

Consumer IDConsumerAccess pathNotes (Example)
CON-01 (Example)Executive Sales Dashboard (DSH-001)BI tool connector to the semantic layerSpecified in Dashboard Specification (data/dashboard-specification)
CON-02 (Example)Finance notebooksSemantic layer API or SQL interfaceCertified metrics only
CON-03 (Example)Internal AI analytics assistantSemantic layer API with user identityACC-05 applies; answers cite metric IDs
CON-04 (Example)Data product "Orders"Exports of saved queries to tablesDescribed in Data Product Specification (data/data-product-specification)
[CON-NN][consumer][path][notes]

Interchange:

  • Keep the model as code in version control, in the native format of the semantic engine, as the source of truth.
  • Where consumers use another tool, export rather than retype. Apache Ossie (incubating), formerly Open Semantic Interchange, is an emerging vendor-neutral specification for exchanging semantic models (datasets, relationships, fields and metrics) between analytics, BI and AI tools. As of October 2026 its core specification is a draft (0.2.0.dev0) with no formal release, and dbt can already read Ossie documents as an alternative to its native semantic model YAML. Check its maturity at https://github.com/apache/ossie before relying on it.
  • Record the export format, version and the tools tested:
FormatVersionExported byTested withStatus (Example)
Native engine definitions[engine version]CISemantic engineSource of truth
[Open interchange format][version][export job][tools]Pilot

14. Traceability matrix

QuestionMetricMetric definitionDatasetsTestsConsumers (Example)
Q1 Net revenue by region vs last yearMET-REV-001, MET-REV-004MET-REV-001, MET-REV-004DS-01, DS-02, DS-06TST-02, TST-04, TST-05, TST-07CON-01, CON-02
Q2 Average order value by segment, rolling 90 daysMET-REV-003MET-REV-003DS-01, DS-04TST-02, TST-05CON-01
Q3 Share of orders refunded within 30 daysMET-ORD-002MET-ORD-002DS-01, DS-03TST-03CON-01 (after certification)
[Question][MET-ID][Link][DS-NN][TST-NN][CON-NN]

15. Glossary and references

TermMeaning
Semantic modelA governed definition of datasets, entities, dimensions and metrics that tools query instead of raw tables
EntityA key that identifies a business object and defines how datasets join
DimensionAn attribute to group or filter by; categorical or time
MeasureA base aggregation of a column or expression
MetricA named, owned calculation built from measures or other metrics
Metric timeThe time dimension used to place a metric value on the calendar
Fan-outRow multiplication caused by joining to a dataset at a finer grain
CertificationA dated statement by the business owner that a metric is correct and supported

References:

  • dbt MetricFlow, v0.213.0 (2026-09-10), Apache License 2.0 from v0.209.0: https://github.com/dbt-labs/metricflow
  • dbt documentation on semantic models and metrics (entity roles, dimension types, metric types; the spec that replaces measures with simple metrics applies to dbt v1.12 and later): https://docs.getdbt.com
  • Apache Ossie (incubating), core metadata specification 0.2.0.dev0, draft: https://github.com/apache/ossie
  • Related templates: Metric Definition (data/metric-definition), Analytics and BI Solution Design (architecture/analytics-bi-solution-design), Dashboard Specification (data/dashboard-specification), Data Dictionary (architecture/data-dictionary), Data Platform Architecture (architecture/data-platform-architecture), dbt Project Standard (data/dbt-project-standard), Data Contract (data/data-contract).

Standard and licence note

Structure aligned with the semantic modelling concepts of dbt MetricFlow (Apache License 2.0, https://github.com/dbt-labs/metricflow) and with the concept names of the Apache Ossie (incubating) draft core specification (Apache License 2.0, https://github.com/apache/ossie). Only concept and type names are used; no specification text, schema or documentation prose is reproduced, and the Corvid Commerce example is fictional. Ossie is a draft and may change. dbt and MetricFlow are trademarks of dbt Labs, Inc., and Apache and Apache Ossie are trademarks of The Apache Software Foundation; this template is not affiliated with or endorsed by them. This template is original text written for this collection. Check the current official versions before use. Template licence: MIT.

関連テンプレート