What's New in FLUID 0.7.2 — Semantic Truth Engine
FLUID 0.7.2 is the Semantic Truth Engine release. It adds to 0.7.1 with one narrowing change — notification became a closed object, so a 0.7.1 contract with an extra member on a notifications[] entry is rejected by 0.7.2 (details below). It completes the agentic contract: agentPolicy decides whether an AI agent may act on a data product, and semantics tells it how to act correctly.
🧠 Semantic Model (NEW)
Each exposes[] entry now accepts an optional semantics block that maps physical columns to business concepts — entities, measures, dimensions, and metrics — in a form agents and BI tools can reason about without re-deriving KPIs.
# NEW in v0.7.2: machine-readable business logic on an exposed table
exposes:
- exposeId: customer_profiles
kind: table
# ...binding, contract, etc...
semantics:
entities:
- name: customer
type: primary # primary | foreign | unique | natural
expr: customer_id
measures:
- name: revenue
agg: sum
expr: order_total
- name: active_customers
agg: count_distinct
expr: customer_id
dimensions:
- name: signup_month
type: time # categorical | time
expr: "DATE_TRUNC('month', created_at)"
metrics:
- name: monthly_active_customers
type: simple # simple | derived | ratio
measure: active_customers
filter: "last_active_at >= CURRENT_DATE - INTERVAL 30 DAY"
Why this matters: eliminates the semantic hallucination failure mode where an LLM asked "what's our MRR?" invents an SQL expression because the contract never told it how MRR is defined. The shape is aligned with dbt MetricFlow, Snowflake Semantic Views, and OSI-format metric definitions — portable across engines.
🧊 Apache Iceberg Binding Config (NEW)
binding.icebergConfig lets contracts declare Iceberg table format specifics — write version, file format, partition spec, sort order — directly in the FLUID contract, so provisioners don't need an out-of-band config file.
binding:
platform: aws
format: iceberg
location: { bucket: warehouse, path: "gold/customer_profiles" }
icebergConfig:
writeVersion: 2
fileFormat: parquet
partitionSpec:
- { sourceColumn: created_at, transform: month }
Backward compatibility with 0.7.1: one narrowing change
- ✅
semanticsandicebergConfigare both opt-in - ✅ All 0.7.1 features (agentPolicy, sovereignty, provider-first orchestration, root accessPolicy) fully preserved
- ⚠️ One breaking change, corrected here after the fact:
notificationbecame a closed object.
This page previously claimed "100% backward compatible" and "no breaking changes". That was not true, and the conformance gate added in #44 proved it. $defs/notification gained "additionalProperties": false in 0.7.2, so a contract carrying any extra member on a build.execution.notifications[] entry validated under 0.7.1 and is rejected by 0.7.2:
build:
execution:
notifications:
- type: slack
target: "#data-alerts"
condition: failure
retryOnFailure: true # accepted by 0.7.1, REJECTED by 0.7.2
Verified with that document plus a negative control — the same contract without retryOnFailure validates under both — so the rejection is attributable to this change and nothing else. The finding is recorded in scripts/compat-waivers.txt, and scripts/check-compat.py now runs on every pull request so a narrowing change cannot ship unannounced again.
If you hit this, drop the unrecognised member from your notifications entries; every field the schema does declare is unchanged.
Migration:
fluidVersion: "0.7.2" # was "0.7.1"; the 0.7.2 schema accepts only "0.7.2"
Change the version, and drop any member the 0.7.2 notification object does not declare. Then add a semantics block on any expose if you want one.
See the Schema Changelog for the full version history, or the 0.7.1 → 0.7.2 diff for the auto-generated change list.
