import { readFile } from 'node:fs/promises' import { resolve } from 'node:path' import { createElementMap2MultiStageNameMapping, parseElementMap2MultiStageNameMapping, writeElementMap2MultiStageNameMapping } from '../src/facade/elementMap2.ts' import { createNativeStageNamingEvidence, validateNativeNamingEvidence } from '../src/facade/nativeNamingEvidence.ts' const root = resolve(new URL('..', import.meta.url).pathname) const load = async (path) => JSON.parse(await readFile(resolve(root, path), 'utf8')) const matrix = await load('config/compatibility-matrix.json') const oracle = await load('config/freecad-composite-history-elementmap-oracle.json') const fail = (message) => { throw new Error(`FreeCAD native naming evidence gate: ${message}`) } const blockers = matrix.nativeOcctHistory?.historyProtocol?.namingEvidence?.exactBlockers if (!Array.isArray(blockers) || blockers.length !== 3) fail('exact blocker list must retain private token, missing stage and isomorphic-source boundaries.') const featureLevels = matrix.facadeCapabilities?.geometry?.featureLevels for (const feature of ['pad', 'pocket', 'revolution', 'groove', 'boolean']) { if (!featureLevels?.[feature] || featureLevels[feature].level !== 'compatible' || !Array.isArray(featureLevels[feature].exactBlockedBy) || featureLevels[feature].exactBlockedBy.length === 0) fail(`${feature} must have a non-exact capability level with explicit blockers.`) } let oracleStages = 0 let nativeEvidenceStages = 0 let nativeMappedNameStages = 0 let nativeIndexedNameStages = 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 oracle.cases) for (const stage of fixture.stages ?? []) { oracleStages += 1 if (!['final-shape-only', 'opaque-preserved', 'native-evidence', 'ambiguous', 'missing'].includes(stage.namingEvidenceStatus)) fail(`${fixture.id}/${stage.name} has no explicit naming evidence status.`) if (!stage.nativeEvidence || stage.nativeEvidence.stageId !== stage.name || stage.nativeEvidence.resultObjectId !== stage.name || stage.nativeEvidence.status !== stage.namingEvidenceStatus) fail(`${fixture.id}/${stage.name} has no stage-bound runtime naming evidence.`) const validation = validateNativeNamingEvidence(stage.nativeEvidence) if (!validation.valid) fail(`${fixture.id}/${stage.name} has invalid runtime naming evidence: ${validation.issues[0].path}: ${validation.issues[0].message}`) if (stage.namingEvidenceStatus === 'native-evidence') nativeEvidenceStages += 1 if (stage.nativeEvidence.mappedNameApiEntries > 0) nativeMappedNameStages += 1 if (stage.nativeEvidence.indexedNameApiEntries > 0) nativeIndexedNameStages += 1 if (stage.nativeEvidence.privateTokenEvidenceComplete === true) privateTokenEvidenceCompleteStages += 1 if (builderStageType.test(stage.typeId || '')) { if (stage.nativeEvidence.internalBuilderEvidence === true) internalBuilderEvidenceStages += 1 else internalBuilderEvidenceMissingStages += 1 } } if (oracleStages !== 219 || nativeEvidenceStages !== 219 || nativeIndexedNameStages !== 219) fail(`locked composite oracle must contain 219/219 stage-bound native indexed-name records, found native=${nativeEvidenceStages}, indexed=${nativeIndexedNameStages}, stages=${oracleStages}.`) const exactFeatures = Object.values(featureLevels).filter((feature) => feature.level === 'exact').length if (matrix.systemExactEvaluation?.exact !== false || matrix.systemExactEvaluation?.featureExactCount !== exactFeatures || JSON.stringify(matrix.systemExactEvaluation?.blockers) !== JSON.stringify(blockers)) fail('system exact evaluation must remain false and list the active native naming blockers.') const table = { schemaVersion: 2, nativeVersion: 1, entries: [{ id: 1, flags: 0, relatedIds: [], data: 'native', postfix: '' }] } const stage0 = createNativeStageNamingEvidence({ stageId: 'gate:0', resultObjectId: 'shape:0', status: 'native-evidence', stringHasher: table, mappedNames: [{ kind: 'face', resultIndex: 0, resultPersistentId: 'face:0', relation: 'generated', reference: { name: 'Face1', stringIds: [1] } }] }) const stage1 = createNativeStageNamingEvidence({ stageId: 'gate:1', resultObjectId: 'shape:1', status: 'ambiguous', stringHasher: table, mappedNames: [{ kind: 'face', resultIndex: 0, resultPersistentId: 'face:1', relation: 'ambiguous', reference: { name: 'Face1', stringIds: [1] }, sourceRefs: [{ objectId: 'shape:0', persistentId: 'face:0', stageId: 'gate:0' }], candidates: [{ objectId: 'a', persistentId: 'face:a' }, { objectId: 'b', persistentId: 'face:b' }] }] }) if (!validateNativeNamingEvidence(stage0).valid || !validateNativeNamingEvidence(stage1).valid) fail('runtime evidence validator rejected its golden native and ambiguous fixtures.') const mapping = createElementMap2MultiStageNameMapping([stage0, stage1], []) if (parseElementMap2MultiStageNameMapping(writeElementMap2MultiStageNameMapping(mapping)).stages[1].entries[0].status !== 'ambiguous') fail('multi-stage ElementMap2 mapping did not persist ambiguity.') console.log(JSON.stringify({ status: 'freecad-native-naming-evidence-pass', cases: oracle.cases.length, oracleStages, nativeEvidenceStages, nativeIndexedNameStages, nativeMappedNameStages, indexedOnlyStages: nativeIndexedNameStages - nativeMappedNameStages, privateTokenEvidenceCompleteStages, internalBuilderEvidenceStages, internalBuilderEvidenceMissingStages, featureLevels: Object.fromEntries(Object.entries(featureLevels).map(([key, value]) => [key, value.level])), exactBlockers: blockers.length, ambiguousPersisted: true, systemFreecadExact: false, exactFeatures }, null, 2))