From 7f5e863229118ba4e6e834a495d231bb3fdbf89b Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 15 Jul 2026 11:09:48 -0300 Subject: [PATCH 1/9] feat(capability-matrix): add CORE_LANGUAGES and coverageScope to ParityReport - Add CORE_LANGUAGES constant and CoreLanguage type for the subset of language SDKs used in parity computation - Replace perFeature field in ParityReport with coverageScope: number - Expected: report.ts and generate-site.ts will fail typecheck until fixed in tasks 2 and 3 --- scripts/capability-matrix/src/types.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/scripts/capability-matrix/src/types.ts b/scripts/capability-matrix/src/types.ts index 2dbfa6b..6d59947 100644 --- a/scripts/capability-matrix/src/types.ts +++ b/scripts/capability-matrix/src/types.ts @@ -9,6 +9,14 @@ export const LANGUAGES = [ ] as const; export type Language = (typeof LANGUAGES)[number]; +export const CORE_LANGUAGES = [ + "javascript", + "flutter", + "python", + "swift", +] as const satisfies readonly Language[]; +export type CoreLanguage = (typeof CORE_LANGUAGES)[number]; + export const STATUSES = [ "implemented", "partially_implemented", @@ -61,8 +69,7 @@ export interface ParityReport { overall: number; perArea: Record; perLanguage: Record; - /** Cross-language parity score per feature ID (0–1). */ - perFeature: Record; + coverageScope: number; } /** Shape of site/compliance.json — raw compliance data plus precomputed parity. */ From c5fd4c446c62b9e65a952e2a3285774fddec4ebd Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 15 Jul 2026 11:14:23 -0300 Subject: [PATCH 2/9] feat(capability-matrix): strict cross-SDK parity score + coverage scope --- scripts/capability-matrix/src/report.ts | 57 ++++--- scripts/capability-matrix/src/types.ts | 1 + scripts/capability-matrix/test/report.test.ts | 143 +++++++++++++++--- 3 files changed, 162 insertions(+), 39 deletions(-) diff --git a/scripts/capability-matrix/src/report.ts b/scripts/capability-matrix/src/report.ts index 93d9757..7560c64 100644 --- a/scripts/capability-matrix/src/report.ts +++ b/scripts/capability-matrix/src/report.ts @@ -1,4 +1,4 @@ -import { LANGUAGES } from "./types.js"; +import { CORE_LANGUAGES, LANGUAGES } from "./types.js"; import type { ComplianceMap, Language, LoadedArea, ParityReport } from "./types.js"; export type { ParityReport }; @@ -6,44 +6,67 @@ export type { ParityReport }; const mean = (xs: number[]): number => xs.length === 0 ? 0 : xs.reduce((a, b) => a + b, 0) / xs.length; +const isDone = (status: string): boolean => + status === "implemented" || status === "partially_implemented"; + export function computeParity( loaded: LoadedArea[], compliance: Partial> ): ParityReport { - const featureParities: number[] = []; - const perAreaParities: Record = {}; + const featurePasses: number[] = []; + const perAreaPasses: Record = {}; const perFeature: Record = {}; const langImplemented = Object.fromEntries(LANGUAGES.map((l) => [l, 0])) as Record; const langApplicable = Object.fromEntries(LANGUAGES.map((l) => [l, 0])) as Record; + let doneCells = 0; + let doneCellsWithSymbols = 0; for (const { area } of loaded) { - perAreaParities[area.area] ??= []; + perAreaPasses[area.area] ??= []; for (const feature of area.features ?? []) { - let implemented = 0; - let applicable = 0; + // Strict cross-SDK pass check (core languages only) + const applicableCore = CORE_LANGUAGES.filter( + (lang) => (compliance[lang]?.[feature.id]?.status ?? "not_implemented") !== "not_applicable" + ); + const passes = + applicableCore.length > 0 && + applicableCore.every((lang) => compliance[lang]?.[feature.id]?.status === "implemented"); + const passValue = passes ? 1 : 0; + featurePasses.push(passValue); + perAreaPasses[area.area].push(passValue); + perFeature[feature.id] = passValue; + + // Per-language completion score (all 7 langs, unchanged semantics) for (const lang of LANGUAGES) { const status = compliance[lang]?.[feature.id]?.status ?? "not_implemented"; if (status === "not_applicable") continue; - applicable++; langApplicable[lang]++; - if (status === "implemented" || status === "partially_implemented") { - implemented++; - langImplemented[lang]++; - } + if (isDone(status)) langImplemented[lang]++; + } + + // Coverage scope (core languages only) + for (const lang of CORE_LANGUAGES) { + const entry = compliance[lang]?.[feature.id]; + const status = entry?.status ?? "not_implemented"; + if (!isDone(status)) continue; + doneCells++; + if (entry?.symbols && entry.symbols.length > 0) doneCellsWithSymbols++; } - const parity = applicable === 0 ? 1 : implemented / applicable; - featureParities.push(parity); - perAreaParities[area.area].push(parity); - perFeature[feature.id] = parity; } } const perArea: Record = {}; - for (const [name, xs] of Object.entries(perAreaParities)) perArea[name] = mean(xs); + for (const [name, xs] of Object.entries(perAreaPasses)) perArea[name] = mean(xs); const perLanguage = Object.fromEntries( LANGUAGES.map((l) => [l, langApplicable[l] === 0 ? 0 : langImplemented[l] / langApplicable[l]]) ) as Record; - return { overall: mean(featureParities), perArea, perLanguage, perFeature }; + return { + overall: mean(featurePasses), + perArea, + perLanguage, + coverageScope: doneCells === 0 ? 0 : doneCellsWithSymbols / doneCells, + perFeature, + }; } diff --git a/scripts/capability-matrix/src/types.ts b/scripts/capability-matrix/src/types.ts index 6d59947..12e87b4 100644 --- a/scripts/capability-matrix/src/types.ts +++ b/scripts/capability-matrix/src/types.ts @@ -70,6 +70,7 @@ export interface ParityReport { perArea: Record; perLanguage: Record; coverageScope: number; + perFeature: Record; } /** Shape of site/compliance.json — raw compliance data plus precomputed parity. */ diff --git a/scripts/capability-matrix/test/report.test.ts b/scripts/capability-matrix/test/report.test.ts index dcc3a86..46bb06a 100644 --- a/scripts/capability-matrix/test/report.test.ts +++ b/scripts/capability-matrix/test/report.test.ts @@ -10,49 +10,148 @@ function area(id: string, features: ReturnType[]): LoadedArea { return { file: "auth.yaml", area: { area: id, title: "T", description: "d", features } }; } -function compliance(lang: Language, statuses: Record): Partial> { - const map: ComplianceMap = {}; - for (const [id, status] of Object.entries(statuses)) { - map[id] = { status: status as never }; - } - return { [lang]: map }; +function entry(status: string, symbols?: string[]) { + return symbols ? { status: status as never, symbols } : { status: status as never }; } -describe("computeParity", () => { - it("returns 0 when all features have no compliance data", () => { +describe("computeParity — strict overall/perArea (core langs only)", () => { + it("returns 0 overall when all features have no compliance data", () => { const a = area("auth", [feature("auth.a"), feature("auth.b")]); const report = computeParity([a], {}); expect(report.overall).toBe(0); expect(report.perLanguage.javascript).toBe(0); }); - it("treats not_applicable as excluded from the denominator", () => { + it("passes a feature only when every core lang is exactly implemented", () => { const a = area("auth", [feature("auth.a")]); - // js: implemented, others: not_implemented (from empty map) -> 1/7 - const c = compliance("javascript", { "auth.a": "implemented" }); + const c: Partial> = { + javascript: { "auth.a": entry("implemented") }, + flutter: { "auth.a": entry("implemented") }, + python: { "auth.a": entry("implemented") }, + swift: { "auth.a": entry("implemented") }, + }; + const report = computeParity([a], c); + expect(report.overall).toBe(1); + expect(report.perArea.auth).toBe(1); + }); + + it("ignores csharp/go/kotlin status entirely for the strict pass check", () => { + const a = area("auth", [feature("auth.a")]); + const c: Partial> = { + javascript: { "auth.a": entry("implemented") }, + flutter: { "auth.a": entry("implemented") }, + python: { "auth.a": entry("implemented") }, + swift: { "auth.a": entry("implemented") }, + csharp: { "auth.a": entry("not_implemented") }, + go: { "auth.a": entry("not_implemented") }, + kotlin: { "auth.a": entry("not_implemented") }, + }; + const report = computeParity([a], c); + expect(report.overall).toBe(1); + // but csharp/go/kotlin still get their own (low) completion score + expect(report.perLanguage.csharp).toBe(0); + }); + + it("fails a feature when a core lang is only partially_implemented", () => { + const a = area("auth", [feature("auth.a")]); + const c: Partial> = { + javascript: { "auth.a": entry("implemented") }, + flutter: { "auth.a": entry("implemented") }, + python: { "auth.a": entry("implemented") }, + swift: { "auth.a": entry("partially_implemented") }, + }; + const report = computeParity([a], c); + expect(report.overall).toBe(0); + }); + + it("excludes a core lang marked not_applicable from the pass check", () => { + const a = area("auth", [feature("auth.a")]); + const c: Partial> = { + javascript: { "auth.a": entry("implemented") }, + flutter: { "auth.a": entry("implemented") }, + python: { "auth.a": entry("implemented") }, + swift: { "auth.a": entry("not_applicable") }, + }; + const report = computeParity([a], c); + expect(report.overall).toBe(1); + }); + + it("fails a feature that is not_applicable in every core lang", () => { + const a = area("auth", [feature("auth.a")]); + const c: Partial> = { + javascript: { "auth.a": entry("not_applicable") }, + flutter: { "auth.a": entry("not_applicable") }, + python: { "auth.a": entry("not_applicable") }, + swift: { "auth.a": entry("not_applicable") }, + }; + const report = computeParity([a], c); + expect(report.overall).toBe(0); + }); + + it("computes overall as passing features / total features across a mixed fixture", () => { + const a = area("auth", [feature("auth.a"), feature("auth.b")]); + const c: Partial> = { + javascript: { "auth.a": entry("implemented"), "auth.b": entry("implemented") }, + flutter: { "auth.a": entry("implemented"), "auth.b": entry("not_implemented") }, + python: { "auth.a": entry("implemented"), "auth.b": entry("implemented") }, + swift: { "auth.a": entry("implemented"), "auth.b": entry("implemented") }, + }; + // auth.a passes (all core implemented), auth.b fails (flutter not_implemented) -> 1/2 + const report = computeParity([a], c); + expect(report.overall).toBe(0.5); + expect(report.perArea.auth).toBe(0.5); + }); +}); + +describe("computeParity — perLanguage (unchanged, all 7 langs)", () => { + it("treats not_applicable as excluded from that language's own denominator", () => { + const a = area("auth", [feature("auth.a")]); + const c: Partial> = { + javascript: { "auth.a": entry("implemented") }, + }; const report = computeParity([a], c); - expect(report.overall).toBeCloseTo(1 / 7, 6); expect(report.perLanguage.javascript).toBeCloseTo(1, 6); expect(report.perLanguage.swift).toBeCloseTo(0, 6); }); - it("excludes not_applicable from feature parity", () => { + it("counts partially_implemented as implemented for a language's own score", () => { + const a = area("auth", [feature("auth.a")]); + const c: Partial> = { + javascript: { "auth.a": entry("partially_implemented") }, + }; + const report = computeParity([a], c); + expect(report.perLanguage.javascript).toBeCloseTo(1, 6); + }); +}); + +describe("computeParity — coverageScope", () => { + it("is 0 when there are no done cells at all", () => { + const a = area("auth", [feature("auth.a")]); + const report = computeParity([a], {}); + expect(report.coverageScope).toBe(0); + }); + + it("is the fraction of done core-lang cells that have symbols listed", () => { const a = area("auth", [feature("auth.a")]); const c: Partial> = { - javascript: { "auth.a": { status: "implemented" } }, - flutter: { "auth.a": { status: "implemented" } }, - go: { "auth.a": { status: "not_applicable" } }, + javascript: { "auth.a": entry("implemented", ["Foo.bar"]) }, + flutter: { "auth.a": entry("implemented") }, // done, no symbols + python: { "auth.a": entry("not_implemented") }, // not done, doesn't count + swift: { "auth.a": entry("partially_implemented", ["Bar.baz"]) }, }; - // applicable: 6 (go excluded), implemented: 2 -> 2/6 + // done cells: javascript, flutter, swift (3); with symbols: javascript, swift (2) -> 2/3 const report = computeParity([a], c); - expect(report.overall).toBeCloseTo(2 / 6, 6); - expect(report.perArea.auth).toBeCloseTo(2 / 6, 6); + expect(report.coverageScope).toBeCloseTo(2 / 3, 6); }); - it("counts partially_implemented as implemented for parity", () => { + it("ignores csharp/go/kotlin cells even if they have symbols", () => { const a = area("auth", [feature("auth.a")]); - const c = compliance("javascript", { "auth.a": "partially_implemented" }); + const c: Partial> = { + javascript: { "auth.a": entry("implemented") }, // done, no symbols + csharp: { "auth.a": entry("implemented", ["Csharp.Foo"]) }, + }; + // only javascript counts as a core done cell -> 0/1 const report = computeParity([a], c); - expect(report.perLanguage.javascript).toBeCloseTo(1, 6); + expect(report.coverageScope).toBe(0); }); }); From 1acade1cd9836e61768046a2c48d96a806fa93a5 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 15 Jul 2026 11:16:56 -0300 Subject: [PATCH 3/9] fix(capability-matrix): drop perFeature reintroduced during Task 2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task 1 removed perFeature from ParityReport per plan; Task 2's implementer re-added it (in both types.ts and report.ts) to make the whole-project typecheck pass early, which was never a Task 2 requirement — generate-site.ts still references parity.perFeature until Task 3 removes that column. Revert to the plan's exact shape; the remaining generate-site.ts typecheck failure is expected until Task 3. --- scripts/capability-matrix/src/report.ts | 3 --- scripts/capability-matrix/src/types.ts | 1 - 2 files changed, 4 deletions(-) diff --git a/scripts/capability-matrix/src/report.ts b/scripts/capability-matrix/src/report.ts index 7560c64..e1387af 100644 --- a/scripts/capability-matrix/src/report.ts +++ b/scripts/capability-matrix/src/report.ts @@ -15,7 +15,6 @@ export function computeParity( ): ParityReport { const featurePasses: number[] = []; const perAreaPasses: Record = {}; - const perFeature: Record = {}; const langImplemented = Object.fromEntries(LANGUAGES.map((l) => [l, 0])) as Record; const langApplicable = Object.fromEntries(LANGUAGES.map((l) => [l, 0])) as Record; let doneCells = 0; @@ -34,7 +33,6 @@ export function computeParity( const passValue = passes ? 1 : 0; featurePasses.push(passValue); perAreaPasses[area.area].push(passValue); - perFeature[feature.id] = passValue; // Per-language completion score (all 7 langs, unchanged semantics) for (const lang of LANGUAGES) { @@ -67,6 +65,5 @@ export function computeParity( perArea, perLanguage, coverageScope: doneCells === 0 ? 0 : doneCellsWithSymbols / doneCells, - perFeature, }; } diff --git a/scripts/capability-matrix/src/types.ts b/scripts/capability-matrix/src/types.ts index 12e87b4..6d59947 100644 --- a/scripts/capability-matrix/src/types.ts +++ b/scripts/capability-matrix/src/types.ts @@ -70,7 +70,6 @@ export interface ParityReport { perArea: Record; perLanguage: Record; coverageScope: number; - perFeature: Record; } /** Shape of site/compliance.json — raw compliance data plus precomputed parity. */ From a382f4a32431f827cfd69992617968f7aeab1ca2 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 15 Jul 2026 11:20:31 -0300 Subject: [PATCH 4/9] feat(capability-matrix): drop per-feature parity column, add coverage scope badge - Remove perFeature parity column from feature table - Add Coverage scope badge to header - Remove dead .th-parity and .parity-cell CSS rules - Reduce table colspan from LANGUAGES.length + 2 to LANGUAGES.length + 1 --- scripts/capability-matrix/src/generate-site.ts | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/scripts/capability-matrix/src/generate-site.ts b/scripts/capability-matrix/src/generate-site.ts index d08f687..68c23a7 100644 --- a/scripts/capability-matrix/src/generate-site.ts +++ b/scripts/capability-matrix/src/generate-site.ts @@ -90,9 +90,8 @@ function renderArea(loaded: LoadedArea, compliance: Partial${esc(group)}\n`; + rows += `${esc(group)}\n`; for (const f of features) { - const fp = parity.perFeature[f.id] ?? 0; const nameHtml = specs.has(f.id) ? `${esc(f.name)}` : esc(f.name); @@ -102,7 +101,6 @@ function renderArea(loaded: LoadedArea, compliance: Partial${esc(f.description)} ${LANGUAGES.map((l) => statusCell(f, l, compliance)).join("")} - ${pct(fp)} \n`; } } @@ -119,7 +117,6 @@ function renderArea(loaded: LoadedArea, compliance: Partial Feature ${LANGUAGES.map((l) => `${esc(LANG_LABELS[l])}`).join("")} - Parity @@ -352,7 +349,6 @@ export function renderHtml( } .th-feature { min-width: 200px; } .th-sdk { width: 80px; text-align: center; } - .th-parity { width: 60px; text-align: center; } tbody tr:hover { background: #f8fafc; } @@ -416,13 +412,6 @@ export function renderHtml( white-space: nowrap; } - /* ── Parity cell ───────────────────────────────────────── */ - .parity-cell { - text-align: center; - font-weight: 600; - font-size: 0.75rem; - font-variant-numeric: tabular-nums; - } .parity-high { color: #16a34a; } .parity-mid { color: #d97706; } .parity-low { color: #dc2626; } @@ -461,6 +450,10 @@ export function renderHtml( Overall parity ${pct(clamp01(parity.overall))} +
+ Coverage scope + ${pct(clamp01(parity.coverageScope))} +
${sdkCards} From 263af5aabc99dedeb7c25f3a3e9cc53a0f828ab9 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 15 Jul 2026 11:28:48 -0300 Subject: [PATCH 5/9] chore(capability-matrix): drop dead parity-color CSS and unused CoreLanguage type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bare .parity-high/mid/low rules were unreachable after the per-feature column was removed — only the higher-specificity .sdk-score.* and .area-card-score.* combinators are ever matched. CoreLanguage was exported but never consumed anywhere. --- scripts/capability-matrix/src/generate-site.ts | 4 ---- scripts/capability-matrix/src/types.ts | 1 - 2 files changed, 5 deletions(-) diff --git a/scripts/capability-matrix/src/generate-site.ts b/scripts/capability-matrix/src/generate-site.ts index 68c23a7..8598e32 100644 --- a/scripts/capability-matrix/src/generate-site.ts +++ b/scripts/capability-matrix/src/generate-site.ts @@ -412,10 +412,6 @@ export function renderHtml( white-space: nowrap; } - .parity-high { color: #16a34a; } - .parity-mid { color: #d97706; } - .parity-low { color: #dc2626; } - /* ── SDK score parity colours ──────────────────────────── */ .sdk-score.parity-high { color: #3ECF8E; } .sdk-score.parity-mid { color: #f59e0b; } diff --git a/scripts/capability-matrix/src/types.ts b/scripts/capability-matrix/src/types.ts index 6d59947..864e98f 100644 --- a/scripts/capability-matrix/src/types.ts +++ b/scripts/capability-matrix/src/types.ts @@ -15,7 +15,6 @@ export const CORE_LANGUAGES = [ "python", "swift", ] as const satisfies readonly Language[]; -export type CoreLanguage = (typeof CORE_LANGUAGES)[number]; export const STATUSES = [ "implemented", From 95cf4daea6f46c8f09131b0326a9437d41a5e31b Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 15 Jul 2026 13:25:59 -0300 Subject: [PATCH 6/9] feat(capability-matrix): explain overall parity and coverage scope on site MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a hover tooltip on each badge plus a short note under them, so "58%"/"32%" don't read as mysterious numbers — states plainly that both are computed only across the 4 core SDKs and what counts as a pass. --- scripts/capability-matrix/src/generate-site.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/scripts/capability-matrix/src/generate-site.ts b/scripts/capability-matrix/src/generate-site.ts index 8598e32..6ab53d5 100644 --- a/scripts/capability-matrix/src/generate-site.ts +++ b/scripts/capability-matrix/src/generate-site.ts @@ -225,9 +225,11 @@ export function renderHtml( padding: 0.5rem 1rem; border-radius: 8px; font-size: 0.85rem; + cursor: help; } .overall-badge .label { color: #888; } .overall-badge .value { font-weight: 700; color: #3ECF8E; font-size: 1.1rem; } + .badge-note { font-size: 0.72rem; color: #888; margin-top: 0.6rem; } /* ── SDK score cards ───────────────────────────────────── */ .sdk-grid { @@ -442,15 +444,16 @@ export function renderHtml(

Supabase SDK Capability Matrix

Updated ${esc(buildDate)} · compliance.json

-
+
Overall parity ${pct(clamp01(parity.overall))}
-
+
Coverage scope ${pct(clamp01(parity.coverageScope))}
+

Overall parity and coverage scope are computed only across core SDKs (JavaScript, Flutter, Python, Swift) — hover a badge for details.

${sdkCards}
From f3b56ce9b15534de4ce5f716e138c8e27af28c1e Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 15 Jul 2026 13:32:13 -0300 Subject: [PATCH 7/9] refactor(capability-matrix): make parity/coverage explanations always-visible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the hover-only badge tooltips with metric cards that show the description text directly under each value — no longer hidden behind a hover. Header restructured: title row on top, metrics row below it, then the SDK score cards. --- .../capability-matrix/src/generate-site.ts | 43 ++++++++++++------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/scripts/capability-matrix/src/generate-site.ts b/scripts/capability-matrix/src/generate-site.ts index 6ab53d5..1a6860c 100644 --- a/scripts/capability-matrix/src/generate-site.ts +++ b/scripts/capability-matrix/src/generate-site.ts @@ -217,19 +217,23 @@ export function renderHtml( } .build-info a { color: #3ECF8E; text-decoration: none; } .build-info a:hover { text-decoration: underline; } - .overall-badge { + .metrics-row { display: flex; - align-items: center; - gap: 0.5rem; + flex-wrap: wrap; + gap: 0.75rem; + margin-bottom: 1.5rem; + } + .metric-card { background: #2d2d2d; - padding: 0.5rem 1rem; + padding: 0.65rem 1rem; border-radius: 8px; - font-size: 0.85rem; - cursor: help; + min-width: 220px; + max-width: 320px; } - .overall-badge .label { color: #888; } - .overall-badge .value { font-weight: 700; color: #3ECF8E; font-size: 1.1rem; } - .badge-note { font-size: 0.72rem; color: #888; margin-top: 0.6rem; } + .metric-card .metric-top { display: flex; align-items: baseline; gap: 0.5rem; } + .metric-card .label { color: #888; font-size: 0.85rem; } + .metric-card .value { font-weight: 700; color: #3ECF8E; font-size: 1.1rem; } + .metric-card .metric-desc { font-size: 0.72rem; color: #999; margin-top: 0.25rem; line-height: 1.4; } /* ── SDK score cards ───────────────────────────────────── */ .sdk-grid { @@ -444,16 +448,23 @@ export function renderHtml(

Supabase SDK Capability Matrix

Updated ${esc(buildDate)} · compliance.json

-
- Overall parity - ${pct(clamp01(parity.overall))} +
+
+
+
+ Overall parity + ${pct(clamp01(parity.overall))} +
+

% of tracked features fully implemented in every core SDK (JavaScript, Flutter, Python, Swift) — a feature only counts if none of them are missing or partial.

-
- Coverage scope - ${pct(clamp01(parity.coverageScope))} +
+
+ Coverage scope + ${pct(clamp01(parity.coverageScope))} +
+

Of the features marked implemented/partial in a core SDK, % that have a registered symbols list — real code evidence behind the "done" claim.

-

Overall parity and coverage scope are computed only across core SDKs (JavaScript, Flutter, Python, Swift) — hover a badge for details.

${sdkCards}
From 6e45061497c1550719d971f1b0bddc9f489dba6b Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 15 Jul 2026 13:37:07 -0300 Subject: [PATCH 8/9] fix(capability-matrix): coverageScope only counts exactly implemented MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit partially_implemented was being treated as "done" for coverage scope via the shared isDone() helper (same as perLanguage's legacy semantics), but a partial implementation isn't really done — per review feedback on #63, a symbol-linked partial claim shouldn't score the same as a symbol-linked full one. perLanguage keeps its existing isDone-based behavior unchanged; only coverageScope now requires status === "implemented". --- scripts/capability-matrix/src/report.ts | 6 ++++-- scripts/capability-matrix/test/report.test.ts | 15 ++++++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/scripts/capability-matrix/src/report.ts b/scripts/capability-matrix/src/report.ts index e1387af..b983f3c 100644 --- a/scripts/capability-matrix/src/report.ts +++ b/scripts/capability-matrix/src/report.ts @@ -42,11 +42,13 @@ export function computeParity( if (isDone(status)) langImplemented[lang]++; } - // Coverage scope (core languages only) + // Coverage scope (core languages only). Only exactly `implemented` counts + // as done here — unlike perLanguage's isDone, partial claims don't get + // credit for "coverage" since they're not actually complete. for (const lang of CORE_LANGUAGES) { const entry = compliance[lang]?.[feature.id]; const status = entry?.status ?? "not_implemented"; - if (!isDone(status)) continue; + if (status !== "implemented") continue; doneCells++; if (entry?.symbols && entry.symbols.length > 0) doneCellsWithSymbols++; } diff --git a/scripts/capability-matrix/test/report.test.ts b/scripts/capability-matrix/test/report.test.ts index 46bb06a..140ee8c 100644 --- a/scripts/capability-matrix/test/report.test.ts +++ b/scripts/capability-matrix/test/report.test.ts @@ -137,11 +137,20 @@ describe("computeParity — coverageScope", () => { javascript: { "auth.a": entry("implemented", ["Foo.bar"]) }, flutter: { "auth.a": entry("implemented") }, // done, no symbols python: { "auth.a": entry("not_implemented") }, // not done, doesn't count - swift: { "auth.a": entry("partially_implemented", ["Bar.baz"]) }, + swift: { "auth.a": entry("partially_implemented", ["Bar.baz"]) }, // partial doesn't count as done }; - // done cells: javascript, flutter, swift (3); with symbols: javascript, swift (2) -> 2/3 + // done cells: javascript, flutter (2); with symbols: javascript (1) -> 1/2 const report = computeParity([a], c); - expect(report.coverageScope).toBeCloseTo(2 / 3, 6); + expect(report.coverageScope).toBeCloseTo(1 / 2, 6); + }); + + it("excludes partially_implemented entirely from coverage scope, even with symbols", () => { + const a = area("auth", [feature("auth.a")]); + const c: Partial> = { + javascript: { "auth.a": entry("partially_implemented", ["Foo.bar"]) }, + }; + const report = computeParity([a], c); + expect(report.coverageScope).toBe(0); }); it("ignores csharp/go/kotlin cells even if they have symbols", () => { From 5f0bbe7ab675a558c4b38642533dea7cbd339a9c Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 15 Jul 2026 13:44:04 -0300 Subject: [PATCH 9/9] fix(capability-matrix): perLanguage no longer credits partially_implemented MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drops isDone() entirely — every metric (overall, perLanguage, coverageScope) now requires the exact "implemented" status. Per discussion on #63, partial credit conflated "claims something is done" with "actually done", which no longer applies anywhere in this pipeline. --- scripts/capability-matrix/src/report.ts | 13 +++++-------- scripts/capability-matrix/test/report.test.ts | 6 +++--- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/scripts/capability-matrix/src/report.ts b/scripts/capability-matrix/src/report.ts index b983f3c..d0d28ac 100644 --- a/scripts/capability-matrix/src/report.ts +++ b/scripts/capability-matrix/src/report.ts @@ -6,9 +6,6 @@ export type { ParityReport }; const mean = (xs: number[]): number => xs.length === 0 ? 0 : xs.reduce((a, b) => a + b, 0) / xs.length; -const isDone = (status: string): boolean => - status === "implemented" || status === "partially_implemented"; - export function computeParity( loaded: LoadedArea[], compliance: Partial> @@ -34,17 +31,17 @@ export function computeParity( featurePasses.push(passValue); perAreaPasses[area.area].push(passValue); - // Per-language completion score (all 7 langs, unchanged semantics) + // Per-language completion score (all 7 langs). Only exactly `implemented` + // counts — partial claims aren't credited as done. for (const lang of LANGUAGES) { const status = compliance[lang]?.[feature.id]?.status ?? "not_implemented"; if (status === "not_applicable") continue; langApplicable[lang]++; - if (isDone(status)) langImplemented[lang]++; + if (status === "implemented") langImplemented[lang]++; } - // Coverage scope (core languages only). Only exactly `implemented` counts - // as done here — unlike perLanguage's isDone, partial claims don't get - // credit for "coverage" since they're not actually complete. + // Coverage scope (core languages only). Same rule — only exactly + // `implemented` counts as done. for (const lang of CORE_LANGUAGES) { const entry = compliance[lang]?.[feature.id]; const status = entry?.status ?? "not_implemented"; diff --git a/scripts/capability-matrix/test/report.test.ts b/scripts/capability-matrix/test/report.test.ts index 140ee8c..e82aee8 100644 --- a/scripts/capability-matrix/test/report.test.ts +++ b/scripts/capability-matrix/test/report.test.ts @@ -103,7 +103,7 @@ describe("computeParity — strict overall/perArea (core langs only)", () => { }); }); -describe("computeParity — perLanguage (unchanged, all 7 langs)", () => { +describe("computeParity — perLanguage (all 7 langs, exact implemented only)", () => { it("treats not_applicable as excluded from that language's own denominator", () => { const a = area("auth", [feature("auth.a")]); const c: Partial> = { @@ -114,13 +114,13 @@ describe("computeParity — perLanguage (unchanged, all 7 langs)", () => { expect(report.perLanguage.swift).toBeCloseTo(0, 6); }); - it("counts partially_implemented as implemented for a language's own score", () => { + it("does not credit partially_implemented for a language's own score", () => { const a = area("auth", [feature("auth.a")]); const c: Partial> = { javascript: { "auth.a": entry("partially_implemented") }, }; const report = computeParity([a], c); - expect(report.perLanguage.javascript).toBeCloseTo(1, 6); + expect(report.perLanguage.javascript).toBe(0); }); });