import { readdir, readFile } from 'node:fs/promises' import { resolve } from 'node:path' const root = resolve(new URL('..', import.meta.url).pathname) const load = async (file) => JSON.parse(await readFile(resolve(root, file), 'utf8')) const fail = (message) => { throw new Error(`FreeCAD golden coverage: ${message}`) } const lockedCommit = '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' const plan = await load('config/freecad-golden-coverage-plan.json') if (plan.schemaVersion !== 1 || plan.baselineId !== 'freecad-1.1.1' || plan.sourceCommit !== lockedCommit) fail('coverage plan is not locked to FreeCAD 1.1.1.') if (plan.parameterMutationPlan !== 'config/freecad-parameter-mutation-plan.json') fail('coverage plan must reference the fail-closed parameter mutation matrix.') const parameterMutationPlan = await load(plan.parameterMutationPlan) if (parameterMutationPlan.schemaVersion !== 1 || parameterMutationPlan.baselineId !== plan.baselineId || parameterMutationPlan.sourceCommit !== lockedCommit || parameterMutationPlan.failClosed !== true || !Array.isArray(parameterMutationPlan.dimensions) || parameterMutationPlan.dimensions.length !== 5) fail('parameter mutation plan is not locked to the same baseline or five-dimensional fail-closed contract.') if (!Array.isArray(plan.dimensions) || new Set(plan.dimensions).size !== plan.dimensions.length) fail('dimensions must be a unique array.') if (!Array.isArray(plan.families) || plan.families.length < 30) fail('coverage plan must enumerate every supported Part/PartDesign family.') const familyIds = new Set() for (const family of plan.families) { if (!family || typeof family.id !== 'string' || familyIds.has(family.id)) fail(`invalid or duplicate family ${family?.id || ''}.`) if (!Array.isArray(family.operationTypes) || family.operationTypes.length === 0) fail(`${family.id} has no operation type mapping.`) for (const field of ['stageTypeIds', 'roundtripIds', 'browserOperations']) if (!Array.isArray(family[field])) fail(`${family.id}.${field} must be an array.`) if (family.oracleSuccessSources !== undefined && !Array.isArray(family.oracleSuccessSources)) fail(`${family.id}.oracleSuccessSources must be an array.`) for (const source of family.oracleSuccessSources || []) if (typeof source?.file !== 'string' || !Array.isArray(source.ids) || source.ids.length === 0 || source.ids.some((id) => typeof id !== 'string')) fail(`${family.id} has an invalid oracle success source.`) familyIds.add(family.id) } const oracleFiles = [...new Set(plan.families.flatMap((family) => (family.oracleSuccessSources || []).map((source) => source.file)))] const oracleReports = new Map(await Promise.all(oracleFiles.map(async (file) => [file, await load(file)]))) const oracleSuccessCounts = new Map() for (const family of plan.families) for (const source of family.oracleSuccessSources || []) { const report = oracleReports.get(source.file) if (report?.schemaVersion !== 1 || report.status !== 'pass' || report.freecadVersion !== '1.1.1' || report.gitCommit !== lockedCommit || !Array.isArray(report.cases)) fail(`${source.file} is not a locked FreeCAD oracle report.`) for (const id of source.ids) { const fixture = report.cases.find((candidate) => candidate.id === id) if (!fixture || fixture.passed !== true || fixture.status !== 'Valid' || (fixture.typeId && fixture.typeId !== family.id)) fail(`${source.file}/${id} is not valid success evidence for ${family.id}.`) oracleSuccessCounts.set(family.id, (oracleSuccessCounts.get(family.id) || 0) + 1) } } const successManifest = await load(plan.successManifest) const failureManifest = await load(plan.failureManifest) const supplementalSuccessManifest = await load(plan.supplementalSuccessManifest) const supplementalFailureManifest = await load(plan.supplementalFailureManifest) const goldenVerification = await load('config/freecad-golden-verification.json') const partdesignFailureOracle = await load(plan.partdesignFailureOracle) const partdesignRevolutionGrooveOracle = await load(plan.partdesignRevolutionGrooveOracle) const partdesignTransformOracle = await load(plan.partdesignTransformOracle) const partBuildersOracle = await load(plan.partBuildersOracle) if (successManifest.schemaVersion !== 1 || successManifest.baselineId !== plan.baselineId || !Array.isArray(successManifest.scenarios)) fail('success manifest baseline or shape is invalid.') if (failureManifest.schemaVersion !== 1 || failureManifest.baselineId !== plan.baselineId || !Array.isArray(failureManifest.failures)) fail('failure manifest baseline or shape is invalid.') if (supplementalSuccessManifest.schemaVersion !== 1 || supplementalSuccessManifest.baselineId !== plan.baselineId || !Array.isArray(supplementalSuccessManifest.scenarios)) fail('supplemental success manifest baseline or shape is invalid.') if (supplementalFailureManifest.schemaVersion !== 1 || supplementalFailureManifest.baselineId !== plan.baselineId || !Array.isArray(supplementalFailureManifest.failures)) fail('supplemental failure manifest baseline or shape is invalid.') if (goldenVerification.schemaVersion !== 1 || goldenVerification.baselineId !== plan.baselineId || goldenVerification.sourceCommit !== lockedCommit) fail('golden verification config is not locked to the same baseline.') if (partdesignFailureOracle.schemaVersion !== 1 || partdesignFailureOracle.baselineId !== 'freecad-1.1.1-partdesign-failure-oracle' || partdesignFailureOracle.freecadVersion !== '1.1.1' || partdesignFailureOracle.gitCommit !== lockedCommit || partdesignFailureOracle.status !== 'pass' || !Array.isArray(partdesignFailureOracle.cases) || partdesignFailureOracle.summary?.rejected !== 13 || partdesignFailureOracle.summary?.acceptedEmpty !== 4) fail('PartDesign failure oracle baseline or tri-state summary is invalid.') const partdesignFailureCounts = new Map(partdesignFailureOracle.cases.filter((fixture) => fixture.observed === 'rejected' && fixture.passed === true).map((fixture) => [fixture.typeId, 1])) if (partdesignRevolutionGrooveOracle.schemaVersion !== 1 || partdesignRevolutionGrooveOracle.baselineId !== 'freecad-1.1.1-partdesign-revolution-groove-oracle' || partdesignRevolutionGrooveOracle.freecadVersion !== '1.1.1' || partdesignRevolutionGrooveOracle.gitCommit !== lockedCommit || partdesignRevolutionGrooveOracle.status !== 'pass' || partdesignRevolutionGrooveOracle.summary?.passed !== 2 || !Array.isArray(partdesignRevolutionGrooveOracle.cases)) fail('PartDesign Revolution/Groove oracle baseline or summary is invalid.') const partdesignFeatureSuccessCounts = new Map(partdesignRevolutionGrooveOracle.cases.filter((fixture) => fixture.passed === true && fixture.shapeValid === true && fixture.solids === 1 && fixture.volume > 0).map((fixture) => [fixture.typeId, 1])) if (partdesignTransformOracle.schemaVersion !== 1 || partdesignTransformOracle.baselineId !== 'freecad-1.1.1-partdesign-transform-oracle' || partdesignTransformOracle.freecadVersion !== '1.1.1' || partdesignTransformOracle.gitCommit !== lockedCommit || partdesignTransformOracle.status !== 'pass' || partdesignTransformOracle.summary?.successPassed !== 6 || partdesignTransformOracle.summary?.failurePassed !== 4 || partdesignTransformOracle.summary?.rejected !== 4 || partdesignTransformOracle.summary?.acceptedEmpty !== 0 || !Array.isArray(partdesignTransformOracle.cases)) fail('PartDesign transform oracle baseline or failure summary is invalid.') const partdesignTransformFailureCounts = new Map(partdesignTransformOracle.cases.filter((fixture) => fixture.passed === true && fixture.observed === 'rejected' && fixture.state?.includes('Invalid')).map((fixture) => [fixture.typeId, 1])) if (partBuildersOracle.schemaVersion !== 1 || partBuildersOracle.baselineId !== 'freecad-1.1.1-part-builders-oracle' || partBuildersOracle.freecadVersion !== '1.1.1' || partBuildersOracle.gitCommit !== lockedCommit || partBuildersOracle.status !== 'pass' || partBuildersOracle.summary?.successPassed !== 6 || partBuildersOracle.summary?.failurePassed !== 6 || partBuildersOracle.summary?.rejected !== 6 || partBuildersOracle.summary?.acceptedEmpty !== 0 || !Array.isArray(partBuildersOracle.successCases) || !Array.isArray(partBuildersOracle.failureCases)) fail('Part builders oracle baseline or summary is invalid.') const partBuilderSuccessCounts = new Map(partBuildersOracle.successCases.filter((fixture) => fixture.passed === true && fixture.observed === 'success' && fixture.shapeValid === true && fixture.solids === 1).map((fixture) => [fixture.typeId, 1])) const partBuilderFailureCounts = new Map(partBuildersOracle.failureCases.filter((fixture) => fixture.passed === true && fixture.observed === 'rejected' && fixture.shapeNull === true).map((fixture) => [fixture.typeId, 1])) const countTopLevelOperations = (manifest, directory, entriesKey) => { const counts = new Map() return Promise.all(manifest[entriesKey].map(async (entry) => { if (!entry || typeof entry.id !== 'string' || typeof entry.file !== 'string') fail(`invalid ${entriesKey} manifest entry.`) const fixture = await load(`${directory}/${entry.file}`) if (fixture.id !== entry.id || !fixture.operation || typeof fixture.operation.type !== 'string') fail(`${entry.id} has no operation payload.`) const type = fixture.operation.type counts.set(type, (counts.get(type) || 0) + 1) return fixture })).then((fixtures) => ({ fixtures, counts })) } const [{ fixtures: mainSuccessFixtures, counts: mainSuccessCounts }, { fixtures: mainFailureFixtures, counts: mainFailureCounts }, { fixtures: supplementalSuccessFixtures, counts: supplementalSuccessCounts }, { fixtures: supplementalFailureFixtures, counts: supplementalFailureCounts }] = await Promise.all([ countTopLevelOperations(successManifest, 'fixtures/freecad-golden', 'scenarios'), countTopLevelOperations(failureManifest, 'fixtures/freecad-golden/failures', 'failures'), countTopLevelOperations(supplementalSuccessManifest, 'fixtures/freecad-golden/feature-families', 'scenarios'), countTopLevelOperations(supplementalFailureManifest, 'fixtures/freecad-golden/feature-families/failures', 'failures'), ]) const mergeCounts = (first, second) => { const merged = new Map(first) for (const [type, count] of second) merged.set(type, (merged.get(type) || 0) + count) return merged } const successFixtures = [...mainSuccessFixtures, ...supplementalSuccessFixtures] const failureFixtures = [...mainFailureFixtures, ...supplementalFailureFixtures] const successCounts = mergeCounts(mainSuccessCounts, supplementalSuccessCounts) const failureCounts = mergeCounts(mainFailureCounts, supplementalFailureCounts) if (goldenVerification.successFixtures?.count !== mainSuccessFixtures.length || goldenVerification.failureFixtures?.count !== mainFailureFixtures.length || goldenVerification.supplementalFixtures?.successCount !== supplementalSuccessFixtures.length || goldenVerification.supplementalFixtures?.failureCount !== supplementalFailureFixtures.length) fail('golden verification fixture counts are stale.') const composite = await load(plan.compositeOracle) if (composite.schemaVersion !== 1 || composite.baselineId !== 'freecad-1.1.1-composite-history-elementmap2' || composite.freecadVersion !== '1.1.1' || composite.gitCommit !== lockedCommit || composite.status !== 'pass' || !Array.isArray(composite.cases)) fail('composite history oracle baseline is invalid.') const stageCounts = new Map() const elementMapCaseCounts = new Map() let compositeStages = 0 let nativeEvidenceStages = 0 let finalShapeOnlyStages = 0 let opaquePreservedStages = 0 let ambiguousStages = 0 let missingEvidenceStages = 0 let nativeEvidenceValidatedStages = 0 let nativeMappedNameStages = 0 let nativeIndexedNameStages = 0 let indexedNameOnlyStages = 0 let privateTokenEvidenceRequiredStages = 0 let privateTokenEvidenceCompleteStages = 0 let internalBuilderEvidenceStages = 0 let internalBuilderEvidenceMissingStages = 0 const builderStageType = /^(Part::(Fuse|Cut|Common|Extrusion|Revolution|Loft|Sweep|Fillet|Chamfer)|PartDesign::(Pad|Pocket|Revolution|Groove|AdditiveLoft|SubtractiveLoft|AdditivePipe|SubtractivePipe|Fillet|Chamfer|Draft|Thickness|Mirrored|MultiTransform|LinearPattern|PolarPattern|Hole))$/ for (const fixture of composite.cases) { if (fixture.status !== 'pass' || !Array.isArray(fixture.stages) || fixture.stages.length === 0) fail(`composite fixture ${fixture.id || ''} is incomplete.`) const hasElementMap = Object.keys(fixture.elementMapResources || {}).length > 0 for (const stage of fixture.stages) { if (typeof stage.typeId !== 'string' || !stage.typeId) continue compositeStages += 1 stageCounts.set(stage.typeId, (stageCounts.get(stage.typeId) || 0) + 1) if (hasElementMap) elementMapCaseCounts.set(stage.typeId, (elementMapCaseCounts.get(stage.typeId) || 0) + 1) if (stage.namingEvidenceStatus === 'native-evidence') nativeEvidenceStages += 1 else if (stage.namingEvidenceStatus === 'final-shape-only') finalShapeOnlyStages += 1 else if (stage.namingEvidenceStatus === 'opaque-preserved') opaquePreservedStages += 1 else if (stage.namingEvidenceStatus === 'ambiguous') ambiguousStages += 1 else missingEvidenceStages += 1 if (stage.nativeEvidence?.stageId === stage.name && stage.nativeEvidence?.resultObjectId === stage.name && stage.nativeEvidence?.status === stage.namingEvidenceStatus) nativeEvidenceValidatedStages += 1 if (stage.nativeEvidence?.mappedNameApiEntries > 0) nativeMappedNameStages += 1 if (stage.nativeEvidence?.indexedNameApiEntries > 0) nativeIndexedNameStages += 1 if (stage.nativeEvidence?.indexedNameOnly === true) indexedNameOnlyStages += 1 if (stage.nativeEvidence?.privateTokenEvidenceRequired === true) privateTokenEvidenceRequiredStages += 1 if (stage.nativeEvidence?.privateTokenEvidenceComplete === true) privateTokenEvidenceCompleteStages += 1 if (builderStageType.test(stage.typeId || '')) { if (stage.nativeEvidence?.internalBuilderEvidence === true) internalBuilderEvidenceStages += 1 else if (stage.namingEvidenceStatus === 'native-evidence') internalBuilderEvidenceMissingStages += 1 } } } let elementMapResources = 0 let stringHasherResources = 0 for (const fixture of composite.cases) { elementMapResources += Object.keys(fixture.elementMapResources || {}).length if (fixture.stringHasherResource?.text) stringHasherResources += 1 } const roundtrip = await load(plan.fcstdRoundtrip) if (roundtrip.schemaVersion !== 1 || roundtrip.baselineId !== plan.baselineId || roundtrip.freecadCommit !== lockedCommit || roundtrip.status !== 'verified' || !Array.isArray(roundtrip.scenarios)) fail('FCStd round-trip report baseline or shape is invalid.') const roundtripPassIds = new Set(roundtrip.scenarios.filter((scenario) => scenario.status === 'pass' && (!scenario.differences || scenario.differences.length === 0)).map((scenario) => scenario.id)) const browserGolden = await load(plan.browserGolden) const browserPrimitiveEvidence = await load(plan.browserPrimitiveEvidence) if (browserGolden.schemaVersion !== 1 || browserGolden.baselineId !== plan.baselineId || browserGolden.freecadCommit !== lockedCommit || browserGolden.status !== 'pass' || !Array.isArray(browserGolden.reports)) fail('browser golden report baseline or shape is invalid.') if (browserPrimitiveEvidence.schemaVersion !== 1 || browserPrimitiveEvidence.status !== 'pass' || browserPrimitiveEvidence.browserId !== 'chrome' || !Array.isArray(browserPrimitiveEvidence.operations) || browserPrimitiveEvidence.afterRelease?.shapeCount !== 0 || browserPrimitiveEvidence.afterRelease?.kernelReferenceCount !== 0) fail('browser primitive evidence is invalid or leaked resources.') const browserOperationCounts = new Map() for (const report of browserGolden.reports) { if (report.status !== 'pass' || (report.differences || []).length !== 0 || typeof report.operation !== 'string') continue browserOperationCounts.set(report.operation, (browserOperationCounts.get(report.operation) || 0) + 1) } for (const operation of ['ellipsoid', 'torus', 'prism', 'wedge']) { const probe = browserGolden.productRecompute?.[operation] if (probe?.quality?.structuralValid === true && probe.quality.isNull === false && probe.quality.structuralErrors === 0 && probe.quality.solids === 1 && probe.comparison?.status === 'pass' && (probe.comparison.differences || []).length === 0) { browserOperationCounts.set(operation, (browserOperationCounts.get(operation) || 0) + 1) } } for (const operation of browserPrimitiveEvidence.operations) { if (typeof operation.name !== 'string' || (!(operation.volume > 0) && !(operation.length > 0))) continue browserOperationCounts.set(operation.name, (browserOperationCounts.get(operation.name) || 0) + 1) } const historyFiles = (await readdir(resolve(root, 'config'))).filter((file) => file.startsWith('chrome-native-') && file.endsWith('-history-verification.json')) const nativeOperationByFile = { 'chrome-native-history-verification.json': ['fuse', 'cut', 'common'], 'chrome-native-pad-history-verification.json': ['pad'], 'chrome-native-pocket-history-verification.json': ['pocket'], 'chrome-native-revolution-history-verification.json': ['revolution'], 'chrome-native-groove-history-verification.json': ['groove'], 'chrome-native-loft-history-verification.json': ['loft'], 'chrome-native-pipe-history-verification.json': ['pipe'], 'chrome-native-fillet-history-verification.json': ['fillet'], 'chrome-native-chamfer-history-verification.json': ['chamfer'], 'chrome-native-hole-history-verification.json': ['hole'], 'chrome-native-draft-history-verification.json': ['draft'], 'chrome-native-thickness-history-verification.json': ['thickness'], 'chrome-native-linear-pattern-history-verification.json': ['linear-pattern'], 'chrome-native-polar-pattern-history-verification.json': ['polar-pattern'], 'chrome-native-mirrored-history-verification.json': ['mirrored'], 'chrome-native-multi-transform-history-verification.json': ['multi-transform'], } const nativeOperations = new Map() for (const file of historyFiles) { const report = await load(`config/${file}`) if (report.status !== 'pass' || report.nativeCapabilities?.availability !== 'available') continue const history = report.history || {} const recordCount = Number.isInteger(history.recordCount) ? history.recordCount : report.execution?.recordCount if (!Number.isInteger(recordCount) || recordCount <= 0) continue for (const operation of nativeOperationByFile[file] || []) nativeOperations.set(operation, (nativeOperations.get(operation) || 0) + 1) } const nativeAliases = new Map([ ['partdesign-revolution', 'revolution'], ['partdesign-fillet', 'fillet'], ['partdesign-chamfer', 'chamfer'], ['additive-loft', 'loft'], ['subtractive-loft', 'loft'], ['additive-pipe', 'pipe'], ['subtractive-pipe', 'pipe'], ]) const nativeDimensionOperations = new Set(['fuse', 'cut', 'common', 'pad', 'pocket', 'revolution', 'groove', 'loft', 'pipe', 'fillet', 'chamfer', 'hole', 'draft', 'thickness', 'linear-pattern', 'polar-pattern', 'mirrored', 'multi-transform']) const countFor = (family) => { const operationTypes = new Set(family.operationTypes) const nativeTypes = new Set([...operationTypes].map((type) => nativeAliases.get(type) || type)) const success = [...operationTypes].reduce((sum, type) => sum + (successCounts.get(type) || 0), 0) + (oracleSuccessCounts.get(family.id) || 0) + (partdesignFeatureSuccessCounts.get(family.id) || 0) + (partBuilderSuccessCounts.get(family.id) || 0) const failure = [...operationTypes].reduce((sum, type) => sum + (failureCounts.get(type) || 0), 0) + (partdesignFailureCounts.get(family.id) || 0) + (partdesignTransformFailureCounts.get(family.id) || 0) + (partBuilderFailureCounts.get(family.id) || 0) const native = [...nativeTypes].reduce((sum, type) => sum + (nativeOperations.get(type) || 0), 0) const stage = family.stageTypeIds.reduce((sum, type) => sum + (stageCounts.get(type) || 0), 0) const elementMap = family.stageTypeIds.reduce((sum, type) => sum + (elementMapCaseCounts.get(type) || 0), 0) const roundtripCount = family.roundtripIds.filter((id) => roundtripPassIds.has(id)).length const browser = family.browserOperations.reduce((sum, type) => sum + (browserOperationCounts.get(type) || 0), 0) const required = ['success-fixture', 'failure-fixture'] if (family.roundtripIds.length > 0) required.push('fcstd-roundtrip') if (family.stageTypeIds.length > 0) required.push('composite-stage', 'elementmap2-resource') if ([...nativeTypes].some((type) => nativeDimensionOperations.has(type))) required.push('native-history') if (family.browserOperations.length > 0) required.push('browser-replay') const counts = { 'success-fixture': success, 'failure-fixture': failure, 'native-history': native, 'composite-stage': stage, 'elementmap2-resource': elementMap, 'fcstd-roundtrip': roundtripCount, 'browser-replay': browser, } const missing = required.filter((dimension) => counts[dimension] < 1) return { id: family.id, required, counts, complete: missing.length === 0, missing } } const families = plan.families.map(countFor) const completeFamilies = families.filter((family) => family.complete).length const blockers = families.filter((family) => !family.complete).map((family) => ({ family: family.id, missing: family.missing })) const globalBlockers = [] if (nativeEvidenceStages === 0) globalBlockers.push('composite oracle has no native-evidence stage; native topology identity remains unavailable') if (nativeEvidenceValidatedStages !== nativeEvidenceStages) globalBlockers.push(`${nativeEvidenceStages - nativeEvidenceValidatedStages} native-evidence stages failed runtime evidence identity validation`) if (nativeIndexedNameStages !== nativeEvidenceStages) globalBlockers.push(`${nativeEvidenceStages - nativeIndexedNameStages} native-evidence stages have no direct FreeCAD indexed-name identity`) if (privateTokenEvidenceCompleteStages < privateTokenEvidenceRequiredStages) globalBlockers.push(`${privateTokenEvidenceRequiredStages - privateTokenEvidenceCompleteStages} native builder stages do not have complete private MappedName token evidence`) if (internalBuilderEvidenceMissingStages > 0) globalBlockers.push(`${internalBuilderEvidenceMissingStages} composite builder stages have no native intermediate builder evidence; final geometry cannot reconstruct private intermediate history`) globalBlockers.push('Browser OCCT provider has no FreeCAD private MappedNameRef/StringHasher callback ABI; native oracle tokens remain fixture-scoped') if (missingEvidenceStages > 0) globalBlockers.push(`${missingEvidenceStages} composite stages have missing naming evidence status`) if (elementMapResources === 0) globalBlockers.push('composite oracle has no ElementMap2 resources') if (stringHasherResources === 0) globalBlockers.push('composite oracle has no StringHasher resources') const sortedObject = (map) => Object.fromEntries([...map.entries()].sort(([left], [right]) => left.localeCompare(right))) const detailed = process.argv.includes('--details') const result = { status: 'freecad-golden-coverage-pass', baseline: { id: plan.baselineId, commit: plan.sourceCommit }, exactPromotionReady: false, totals: { successFixtures: successFixtures.length, failureFixtures: failureFixtures.length, primarySuccessFixtures: mainSuccessFixtures.length, primaryFailureFixtures: mainFailureFixtures.length, supplementalSuccessFixtures: supplementalSuccessFixtures.length, supplementalFailureFixtures: supplementalFailureFixtures.length, compositeCases: composite.cases.length, compositeStages, nativeEvidenceStages, nativeEvidenceValidatedStages, nativeIndexedNameStages, nativeMappedNameStages, indexedOnlyStages: indexedNameOnlyStages, privateTokenEvidenceRequiredStages, privateTokenEvidenceCompleteStages, internalBuilderEvidenceStages, internalBuilderEvidenceMissingStages, finalShapeOnlyStages, opaquePreservedStages, ambiguousStages, missingEvidenceStages, elementMapResources, stringHasherResources, roundtripScenarios: roundtrip.scenarios.length, roundtripPassScenarios: roundtripPassIds.size, browserGoldenReports: browserGolden.reports.length, browserPrimitiveOperations: browserPrimitiveEvidence.operations.length, nativeOracleSuccessCases: [...oracleSuccessCounts.values(), ...partdesignFeatureSuccessCounts.values(), ...partBuilderSuccessCounts.values()].reduce((sum, count) => sum + count, 0), nativeOracleFailureCases: [...partdesignFailureCounts.values(), ...partdesignTransformFailureCounts.values(), ...partBuilderFailureCounts.values()].reduce((sum, count) => sum + count, 0), }, operationCounts: { success: sortedObject(successCounts), failure: sortedObject(failureCounts), oracleSuccess: sortedObject(new Map([...oracleSuccessCounts, ...partdesignFeatureSuccessCounts, ...partBuilderSuccessCounts])), oracleFailure: sortedObject(new Map([...partdesignFailureCounts, ...partdesignTransformFailureCounts, ...partBuilderFailureCounts])), nativeHistory: sortedObject(nativeOperations), browserReplay: sortedObject(browserOperationCounts) }, families: { total: families.length, complete: completeFamilies, incomplete: families.length - completeFamilies, blockerCount: blockers.length }, missingDimensions: Object.fromEntries([...new Set(blockers.flatMap(({ missing }) => missing))].sort().map((dimension) => [dimension, blockers.filter((family) => family.missing.includes(dimension)).length])), blockers: globalBlockers, } if (detailed) result.familyBlockers = blockers console.log(JSON.stringify(result, null, 2))