FLUIDFLUID
  • Introduction
  • Quickstart
  • Why FLUID
  • FAQ
  • What FLUID Is
  • Core Principles
  • Agentic-Native Layer
  • FLUID vs ODCS / ODPS
  • Reference Implementation
  • Anatomy
  • Cheatsheet
  • Minimal Contract
  • Specification
  • Versions
  • Changelog
  • JSON Schema 0.7.5 (stable) ↗
  • Reference 0.7.5 (HTML) ↗
  • Preview: 0.7.6
Examples
How-to
What's New
Deck
  • Contributing
  • Governance ↗
  • Conformance Corpus ↗
  • Vision
GitHub
GitHub
  • Introduction
  • Quickstart
  • Why FLUID
  • FAQ
  • What FLUID Is
  • Core Principles
  • Agentic-Native Layer
  • FLUID vs ODCS / ODPS
  • Reference Implementation
  • Anatomy
  • Cheatsheet
  • Minimal Contract
  • Specification
  • Versions
  • Changelog
  • JSON Schema 0.7.5 (stable) ↗
  • Reference 0.7.5 (HTML) ↗
  • Preview: 0.7.6
Examples
How-to
What's New
Deck
  • Contributing
  • Governance ↗
  • Conformance Corpus ↗
  • Vision
GitHub
GitHub
  • What's New

    • What's New
    • FLUID 0.7.6 (preview) — Declarative Packaging Modes
    • What's New in FLUID 0.7.5 — Streaming Kafka → Iceberg Sink & Confluent Tableflow
    • What's New in FLUID 0.7.4 — Runtime agentPolicy Enforcement at the MCP Gateway
    • What's New in FLUID 0.7.3 — Source-Aligned Acquisition
    • What's New in FLUID 0.7.2 — Semantic Truth Engine
    • What's New in FLUID 0.7.1 — Agentic Governance + Provider-First Orchestration

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

  • ✅ semantics and icebergConfig are 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: notification became 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.

Edit this page on GitHub
Last Updated: 10/5/26, 9:55 AM
Contributors: fas89, Claude Opus 4.8, Claude Opus 5
Prev
What's New in FLUID 0.7.3 — Source-Aligned Acquisition
Next
What's New in FLUID 0.7.1 — Agentic Governance + Provider-First Orchestration