feat: close builder mutation and roundtrip evidence gaps

This commit is contained in:
2026-08-10 21:27:42 -04:00
parent 3907f50ff1
commit 26ea9b57d7
49 changed files with 5797 additions and 687 deletions

View File

@@ -49,6 +49,14 @@ const addVariant = (familyId, snapshot, source) => {
bucket.parameterVariants.set(stable(snapshot), { snapshot, source })
bucket.sources.add(source)
}
const addMutation = (mutation, source) => {
if (!mutation || typeof mutation !== 'object') return
const familyId = familyByType.get(mutation.familyId)
if (!familyId || mutation.status !== 'pass' || mutation.parameterChanged !== true || mutation.shapeChanged !== true || mutation.restoredExactly !== true) return
addRecord(familyId, 'editRecovery', { transaction: `native-parameter:${mutation.featureName}:${mutation.propertyPath}`, ...mutation }, source)
addVariant(familyId, mutation.before.parameterSnapshot, `${source}#before`)
addVariant(familyId, mutation.edited.parameterSnapshot, `${source}#edited`)
}
const manifestCases = async (manifestPath, entryKey, directory) => {
const manifest = await load(manifestPath)
const base = resolve(root, directory)
@@ -81,11 +89,16 @@ const addOracleCases = async (file, successKey, failureKey) => {
for (const key of [successKey, failureKey]) for (const fixture of report[key] || []) {
const familyId = familyByType.get(fixture.typeId)
if (!familyId) continue
if (key === successKey) addRecord(familyId, 'nominal', { id: fixture.id, typeId: fixture.typeId }, source)
if (key === successKey) {
addRecord(familyId, 'nominal', { id: fixture.id, typeId: fixture.typeId }, source)
addMutation(fixture.mutation, source)
}
else addRecord(familyId, 'invalid', { id: fixture.id, typeId: fixture.typeId }, source)
}
}
await addOracleCases('config/freecad-part-builders-oracle.json', 'successCases', 'failureCases')
const coreMutationOracle = await load('config/freecad-core-parameter-mutation-oracle.json')
for (const mutation of coreMutationOracle.cases || []) addMutation(mutation, 'config/freecad-core-parameter-mutation-oracle.json')
for (const file of ['config/freecad-partdesign-failure-oracle.json', 'config/freecad-partdesign-revolution-groove-oracle.json', 'config/freecad-partdesign-transform-oracle.json']) {
const report = await load(file)
for (const fixture of report.cases || []) {
@@ -93,18 +106,21 @@ for (const file of ['config/freecad-partdesign-failure-oracle.json', 'config/fre
if (!familyId) continue
if (fixture.passed === true && fixture.status === 'Valid' && fixture.shapeValid !== false && fixture.solids > 0) addRecord(familyId, 'nominal', { id: fixture.id, typeId: fixture.typeId }, file)
if (fixture.passed === true && (fixture.observed === 'rejected' || fixture.state?.includes('Invalid'))) addRecord(familyId, 'invalid', { id: fixture.id, typeId: fixture.typeId }, file)
addMutation(fixture.mutation, file)
}
}
const baseOracle = await load('config/freecad-partdesign-base-oracle.json')
for (const fixture of baseOracle.cases || []) {
const familyId = fixture.id.startsWith('pad-') ? 'PartDesign::Pad' : fixture.id.startsWith('pocket-') ? 'PartDesign::Pocket' : undefined
if (familyId && fixture.passed === true && fixture.status === 'Valid' && fixture.solids > 0) addRecord(familyId, 'nominal', { id: fixture.id, typeId: familyId, outcome: { volume: fixture.volume, faces: fixture.faces } }, 'config/freecad-partdesign-base-oracle.json')
if (familyId) addMutation(fixture.mutation, 'config/freecad-partdesign-base-oracle.json')
}
for (const file of ['config/freecad-partdesign-loft-oracle.json', 'config/freecad-partdesign-dressup-oracle.json']) {
const report = await load(file)
for (const fixture of report.cases || []) {
const familyId = familyByType.get(fixture.typeId)
if (familyId && fixture.passed === true && fixture.status === 'Valid' && fixture.solids > 0) addRecord(familyId, 'nominal', { id: fixture.id, typeId: fixture.typeId, outcome: { volume: fixture.volume, faces: fixture.faces } }, file)
addMutation(fixture.mutation, file)
}
}