diff --git a/src/analytics/metrics/semantic-provider.ts b/src/analytics/metrics/semantic-provider.ts index 435f1d0..1961e67 100644 --- a/src/analytics/metrics/semantic-provider.ts +++ b/src/analytics/metrics/semantic-provider.ts @@ -40,12 +40,33 @@ import type { SemanticModelVersion } from './semantic-registry'; /** * The version this provider is written against. * - * UNVERIFIED: no supply-chain or licence review has been run for it in this - * repo, and it has not been executed. It is a declared intent, not a - * certification, and `providerReadiness()` reports it as such so nothing - * downstream can mistake the constant for a green light. + * LICENCE BOUNDARY — the reason this is 0.209.0 and not 0.208.1. + * + * MetricFlow was relicensed by dbt Labs at 0.209.0. Verified against the + * LICENSE file at each git tag, 2026-09-07, not inferred from PyPI metadata + * (PyPI reports no licence field for either version, so a metadata check + * would have found nothing): + * + * v0.208.1 Business Source License 1.1 — source-available, NOT open source + * v0.209.0 Apache License 2.0 + * + * The previous pin sat exactly one patch below that boundary. For a + * self-hosted platform whose premise is no proprietary runtime dependency, + * a BUSL component in the semantic layer is a licence defect, not a + * preference — BUSL restricts production use until its change date. + * + * STILL UNVERIFIED, and deliberately still reported as such: no supply-chain + * review has been run and MetricFlow has never been executed here (no Python + * runtime is provisioned). `providerReadiness()` continues to return + * `verified: false`. Fixing the licence does not make the provider proven. */ -export const METRICFLOW_PINNED_VERSION = '0.208.1'; +export const METRICFLOW_PINNED_VERSION = '0.209.0'; + +/** + * The first MetricFlow release under Apache-2.0. Anything below this is BUSL + * and must not be pinned here; the test asserts the pin stays at or above it. + */ +export const METRICFLOW_FIRST_OPEN_SOURCE_VERSION = '0.209.0'; /** The provider-neutral port. BI-P029's `SiaxSemanticProvider`. */ export interface SiaxSemanticProvider { diff --git a/tests/unit/metricflow-licence.test.ts b/tests/unit/metricflow-licence.test.ts new file mode 100644 index 0000000..bf1dfb4 --- /dev/null +++ b/tests/unit/metricflow-licence.test.ts @@ -0,0 +1,37 @@ +import { describe, expect, it } from 'vitest'; +import { + METRICFLOW_FIRST_OPEN_SOURCE_VERSION, + METRICFLOW_PINNED_VERSION, +} from '../../src/analytics/metrics/semantic-provider'; + +/** + * BI-P147. MetricFlow below 0.209.0 is Business Source License 1.1 — + * source-available, NOT open source, and restricted for production use until + * its change date. dbt Labs relicensed to Apache-2.0 at 0.209.0, verified + * against the LICENSE file at each git tag on 2026-09-07 (PyPI reports no + * licence field for either version, so a metadata check finds nothing). + * + * This guards a boundary an ordinary "pin the version we tested" change would + * cross without noticing: the previous pin, 0.208.1, was one patch below it. + */ +const cmp = (a: string, b: string): number => { + const pa = a.split('.').map(Number); + const pb = b.split('.').map(Number); + for (let i = 0; i < Math.max(pa.length, pb.length); i += 1) { + const d = (pa[i] ?? 0) - (pb[i] ?? 0); + if (d !== 0) return d; + } + return 0; +}; + +describe('BI-P147 MetricFlow licence boundary', () => { + it('pins a version at or above the Apache-2.0 boundary', () => { + expect(cmp(METRICFLOW_PINNED_VERSION, METRICFLOW_FIRST_OPEN_SOURCE_VERSION)).toBeGreaterThanOrEqual(0); + }); + + it('rejects every known BUSL version — the comparison genuinely discriminates', () => { + for (const busl of ['0.207.3', '0.208.0', '0.208.1']) { + expect(cmp(busl, METRICFLOW_FIRST_OPEN_SOURCE_VERSION)).toBeLessThan(0); + } + }); +});