feat: advance FreeCAD exact parity evidence
This commit is contained in:
@@ -2,16 +2,22 @@ import { readFile } from 'node:fs/promises'
|
||||
import { resolve } from 'node:path'
|
||||
import { createElementMap2NameToken, elementMap2NameTokenToReference, elementMap2SemanticDigest, parseElementMap2, validateElementMap2, writeElementMap2 } from '../src/facade/elementMap2.ts'
|
||||
import { migrateStringHasherSchema, parseStringHasherTable, validateElementMap2StringHasherEvidence, validateStringHasherTable, writeStringHasherTable } from '../src/facade/stringHasher.ts'
|
||||
import { validateCompositeMutationEvidence } from './freecad-composite-mutation-evidence.mjs'
|
||||
|
||||
const root = resolve(new URL('..', import.meta.url).pathname)
|
||||
const load = async (path) => JSON.parse(await readFile(resolve(root, path), 'utf8'))
|
||||
const gate = await load('config/freecad-exact-history-elementmap-gate.json')
|
||||
const oracle = await load('config/freecad-composite-history-elementmap-oracle.json')
|
||||
const roundtrip = await load('config/freecad-fcstd-roundtrip-verification.json')
|
||||
const resave = await load('config/freecad-composite-history-resave-verification.json')
|
||||
const stageCorrelation = await load('config/freecad-tsn-stage-correlation-oracle.json')
|
||||
if (oracle.baselineId !== gate.baselineId || oracle.freecadVersion !== gate.requiredFreecadVersion || oracle.gitCommit !== gate.requiredFreecadCommit || oracle.status !== 'pass' || oracle.summary?.cases !== gate.requiredCases || oracle.summary?.passed !== gate.requiredCases) throw new Error('Exact history/ElementMap2 gate baseline is not the locked FreeCAD 1.1.1 30-case report.')
|
||||
const mutationEvidence = validateCompositeMutationEvidence(oracle)
|
||||
if (mutationEvidence.mutationCases !== gate.requirements.mutationCases || mutationEvidence.mutationPassed !== gate.requirements.mutationCases - gate.requirements.mutationFailures || mutationEvidence.mutationStageRecords !== gate.requirements.mutationStageRecords || mutationEvidence.mutationStageRestoreFailures !== gate.requirements.mutationStageRestoreFailures || mutationEvidence.mutationFinalPropagationFailures !== gate.requirements.mutationFinalPropagationFailures || mutationEvidence.mutationNamingRestoreDriftCases !== gate.requirements.mutationNamingRestoreDriftCases || mutationEvidence.mutationNamingRestoreDriftStages !== gate.requirements.mutationNamingRestoreDriftStages) throw new Error('Exact history/ElementMap2 mutation requirements do not match per-case evidence.')
|
||||
let wrongBindings = 0
|
||||
let unexplainedRelations = 0
|
||||
let roundtripNameDrift = 0
|
||||
let resaveNameDrift = 0
|
||||
let elementMap2ParseFailures = 0
|
||||
let elementMap2SemanticFailures = 0
|
||||
let elementMap2TokenWriterFailures = 0
|
||||
@@ -31,7 +37,22 @@ 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))$/
|
||||
let resources = 0
|
||||
let caseReconciliations = 0
|
||||
const resaveById = new Map((resave.cases || []).map((fixture) => [fixture.id, fixture]))
|
||||
if (resaveById.size !== gate.requiredCases || resave.cases?.length !== gate.requiredCases) throw new Error('Exact gate resave evidence is not joined one-to-one with the locked corpus.')
|
||||
const zeroMetrics = () => ({ wrongBindings, unexplainedRelations, roundtripNameDrift, resaveNameDrift, elementMap2ParseFailures, elementMap2SemanticFailures, elementMap2TokenWriterFailures, stringHasherParseFailures, stringHasherSemanticFailures, stringHasherEvidenceFailures, namingEvidenceMissing, namingEvidenceBoundaryViolations })
|
||||
for (const fixture of oracle.cases) {
|
||||
const metricsBefore = zeroMetrics()
|
||||
const resaveFixture = resaveById.get(fixture.id)
|
||||
if (!resaveFixture || resaveFixture.roundtripNameDrift !== 0 || resaveFixture.resaveNameDrift !== 0 || resaveFixture.nativeDesktopResaveCovered !== true) throw new Error(`Exact gate case ${fixture.id} lacks passing native save/reopen/resave evidence.`)
|
||||
if (!['initial', 'reopened', 'resaved'].every((phase) => Array.isArray(resaveFixture.stageCorrelations?.[phase]) && resaveFixture.stageCorrelations[phase].length === fixture.stages.length)) throw new Error(`Exact gate case ${fixture.id} lacks complete stage correlations.`)
|
||||
for (const [ordinal, stage] of fixture.stages.entries()) {
|
||||
const expectedKey = `${fixture.id}:${String(ordinal).padStart(3, '0')}:${stage.name}`
|
||||
for (const phase of ['initial', 'reopened', 'resaved']) {
|
||||
const record = resaveFixture.stageCorrelations[phase][ordinal]
|
||||
if (record.key !== expectedKey || record.ordinal !== ordinal || record.name !== stage.name || record.typeId !== stage.typeId || record.relationDigest !== stage.relationDigest || record.semanticNameDigest !== stage.semanticNameDigest) throw new Error(`Exact gate case ${expectedKey} changed identity or naming evidence during ${phase}.`)
|
||||
}
|
||||
}
|
||||
if (fixture.roundtripNameDrift !== 0) roundtripNameDrift += 1
|
||||
const knownObjects = new Set(fixture.stages.map((stage) => stage.name))
|
||||
for (const stage of fixture.stages) {
|
||||
@@ -96,10 +117,20 @@ for (const fixture of oracle.cases) {
|
||||
elementMap2ParseFailures += 1
|
||||
}
|
||||
}
|
||||
const metricsAfter = zeroMetrics()
|
||||
const caseFailures = Object.fromEntries(Object.keys(metricsAfter).map((key) => [key, metricsAfter[key] - metricsBefore[key]]).filter(([, value]) => value !== 0))
|
||||
if (Object.keys(caseFailures).length > 0) throw new Error(`Exact gate case ${fixture.id} failed closed: ${JSON.stringify(caseFailures)}.`)
|
||||
caseReconciliations += 1
|
||||
}
|
||||
for (const scenario of roundtrip.scenarios || []) {
|
||||
if (scenario.status !== 'pass' || (scenario.differences || []).length !== 0) roundtripNameDrift += 1
|
||||
}
|
||||
if (resave.status !== 'pass' || resave.summary?.nativeDesktopResaveCases !== gate.requiredCases || resave.summary?.roundtripNameDrift !== 0 || resave.summary?.resaveNameDrift !== 0 || caseReconciliations !== gate.requiredCases) resaveNameDrift += 1
|
||||
if (stageCorrelation.status !== 'pass' || stageCorrelation.nativeDesktopResaveCovered !== true || stageCorrelation.summary?.mutationCases !== 5 || stageCorrelation.summary?.mutationPassed !== 5) throw new Error('Five-stage desktop correlation/mutation evidence is incomplete.')
|
||||
wrongBindings += stageCorrelation.summary?.wrongBindings ?? 1
|
||||
unexplainedRelations += stageCorrelation.summary?.unexplainedRelations ?? 1
|
||||
roundtripNameDrift += stageCorrelation.summary?.roundtripNameDrift ?? 1
|
||||
resaveNameDrift += stageCorrelation.summary?.resaveNameDrift ?? 1
|
||||
if (indexedNameOnlyStages + privateTokenEvidenceRequiredStages !== nativeEvidenceStages || privateTokenEvidenceCompleteStages !== privateTokenEvidenceRequiredStages || internalBuilderEvidenceStages !== 42 || internalBuilderEvidenceMissingStages !== 0) throw new Error(`Exact native naming evidence is incomplete: indexedOnly=${indexedNameOnlyStages}, tokenRequired=${privateTokenEvidenceRequiredStages}, tokenComplete=${privateTokenEvidenceCompleteStages}, builder=${internalBuilderEvidenceStages}, builderMissing=${internalBuilderEvidenceMissingStages}.`)
|
||||
if (roundtrip.status !== 'verified' || wrongBindings !== gate.requirements.wrongBindings || unexplainedRelations !== gate.requirements.unexplainedRelations || roundtripNameDrift !== gate.requirements.roundtripNameDrift || elementMap2ParseFailures !== gate.requirements.elementMap2ParseFailures || elementMap2SemanticFailures !== gate.requirements.elementMap2SemanticFailures || elementMap2TokenWriterFailures !== gate.requirements.elementMap2TokenWriterFailures || stringHasherParseFailures !== gate.requirements.stringHasherParseFailures || stringHasherSemanticFailures !== gate.requirements.stringHasherSemanticFailures || stringHasherEvidenceFailures !== gate.requirements.stringHasherEvidenceFailures || namingEvidenceMissing !== gate.requirements.namingEvidenceMissing || namingEvidenceBoundaryViolations !== gate.requirements.namingEvidenceBoundaryViolations) throw new Error(`Exact gate failed: wrongBindings=${wrongBindings}, unexplainedRelations=${unexplainedRelations}, roundtripNameDrift=${roundtripNameDrift}, elementMap2ParseFailures=${elementMap2ParseFailures}, elementMap2SemanticFailures=${elementMap2SemanticFailures}, elementMap2TokenWriterFailures=${elementMap2TokenWriterFailures}, stringHasherParseFailures=${stringHasherParseFailures}, stringHasherSemanticFailures=${stringHasherSemanticFailures}, stringHasherEvidenceFailures=${stringHasherEvidenceFailures}, namingEvidenceMissing=${namingEvidenceMissing}, namingEvidenceBoundaryViolations=${namingEvidenceBoundaryViolations}.`)
|
||||
console.log(JSON.stringify({ status: 'freecad-exact-history-elementmap-gate-pass', exactPromotionReady: false, cases: oracle.summary.cases, resources, stringHasherResources, nativeEvidenceStages, nativeIndexedNameStages, nativeMappedNameStages, indexedOnlyStages: indexedNameOnlyStages, privateTokenEvidenceRequiredStages, privateTokenEvidenceCompleteStages, internalBuilderEvidenceStages, internalBuilderEvidenceMissingStages, wrongBindings, unexplainedRelations, roundtripNameDrift, elementMap2ParseFailures, elementMap2SemanticFailures, elementMap2TokenWriterFailures, stringHasherParseFailures, stringHasherSemanticFailures, stringHasherEvidenceFailures, namingEvidenceMissing, namingEvidenceBoundaryViolations }, null, 2))
|
||||
if (roundtrip.status !== 'verified' || wrongBindings !== gate.requirements.wrongBindings || unexplainedRelations !== gate.requirements.unexplainedRelations || roundtripNameDrift !== gate.requirements.roundtripNameDrift || resaveNameDrift !== gate.requirements.resaveNameDrift || elementMap2ParseFailures !== gate.requirements.elementMap2ParseFailures || elementMap2SemanticFailures !== gate.requirements.elementMap2SemanticFailures || elementMap2TokenWriterFailures !== gate.requirements.elementMap2TokenWriterFailures || stringHasherParseFailures !== gate.requirements.stringHasherParseFailures || stringHasherSemanticFailures !== gate.requirements.stringHasherSemanticFailures || stringHasherEvidenceFailures !== gate.requirements.stringHasherEvidenceFailures || namingEvidenceMissing !== gate.requirements.namingEvidenceMissing || namingEvidenceBoundaryViolations !== gate.requirements.namingEvidenceBoundaryViolations) throw new Error(`Exact gate failed: wrongBindings=${wrongBindings}, unexplainedRelations=${unexplainedRelations}, roundtripNameDrift=${roundtripNameDrift}, resaveNameDrift=${resaveNameDrift}, elementMap2ParseFailures=${elementMap2ParseFailures}, elementMap2SemanticFailures=${elementMap2SemanticFailures}, elementMap2TokenWriterFailures=${elementMap2TokenWriterFailures}, stringHasherParseFailures=${stringHasherParseFailures}, stringHasherSemanticFailures=${stringHasherSemanticFailures}, stringHasherEvidenceFailures=${stringHasherEvidenceFailures}, namingEvidenceMissing=${namingEvidenceMissing}, namingEvidenceBoundaryViolations=${namingEvidenceBoundaryViolations}.`)
|
||||
console.log(JSON.stringify({ status: 'freecad-exact-history-elementmap-gate-pass', exactPromotionReady: false, cases: oracle.summary.cases, caseReconciliations, categoryCases: mutationEvidence.categoryCases, mutationCases: mutationEvidence.mutationCases, mutationPassed: mutationEvidence.mutationPassed, mutationStageRecords: mutationEvidence.mutationStageRecords, mutationPhaseStageRecords: mutationEvidence.mutationPhaseStageRecords, mutationStageRestoreFailures: mutationEvidence.mutationStageRestoreFailures, mutationFinalPropagationFailures: mutationEvidence.mutationFinalPropagationFailures, mutationNamingRestoreDriftCases: mutationEvidence.mutationNamingRestoreDriftCases, mutationNamingRestoreDriftStages: mutationEvidence.mutationNamingRestoreDriftStages, nativeDesktopResaveCases: resave.summary.nativeDesktopResaveCases + 1, crossFeatureMutationCases: stageCorrelation.summary.mutationCases, crossFeatureMutationPassed: stageCorrelation.summary.mutationPassed, resources, stringHasherResources, nativeEvidenceStages, nativeIndexedNameStages, nativeMappedNameStages, indexedOnlyStages: indexedNameOnlyStages, privateTokenEvidenceRequiredStages, privateTokenEvidenceCompleteStages, internalBuilderEvidenceStages, internalBuilderEvidenceMissingStages, wrongBindings, unexplainedRelations, roundtripNameDrift, resaveNameDrift, elementMap2ParseFailures, elementMap2SemanticFailures, elementMap2TokenWriterFailures, stringHasherParseFailures, stringHasherSemanticFailures, stringHasherEvidenceFailures, namingEvidenceMissing, namingEvidenceBoundaryViolations }, null, 2))
|
||||
|
||||
Reference in New Issue
Block a user