feat: close ordered pairs and property codec batches
Some checks are pending
real-verification / chrome (push) Waiting to run
real-verification / freecad-oracle (push) Waiting to run
real-verification / wasm (push) Waiting to run

This commit is contained in:
2026-08-17 04:58:46 -04:00
parent 00ed27b7b8
commit d11566403d
265 changed files with 92107 additions and 809 deletions

View File

@@ -0,0 +1,5 @@
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8" /><title>Chrome PropertyAcceleration harness</title></head>
<body><main id="root">Initializing PropertyAcceleration harness.</main><script type="module" src="/src/chromePropertyAccelerationHarness.tsx"></script></body>
</html>

View File

@@ -0,0 +1,5 @@
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8" /><title>Chrome PropertyArea harness</title></head>
<body><main id="root">Initializing PropertyArea harness.</main><script type="module" src="/src/chromePropertyAreaHarness.tsx"></script></body>
</html>

View File

@@ -0,0 +1,5 @@
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8" /><title>Chrome PropertyBoolList harness</title></head>
<body><main id="root">Initializing PropertyBoolList harness.</main><script type="module" src="/src/chromePropertyBoolListHarness.tsx"></script></body>
</html>

View File

@@ -0,0 +1,5 @@
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8" /><title>Chrome PropertyColor harness</title></head>
<body><main id="root">Initializing PropertyColor harness.</main><script type="module" src="/src/chromePropertyColorHarness.tsx"></script></body>
</html>

View File

@@ -0,0 +1,5 @@
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8" /><title>Chrome PropertyColorList harness</title></head>
<body><main id="root">Initializing PropertyColorList harness.</main><script type="module" src="/src/chromePropertyColorListHarness.tsx"></script></body>
</html>

View File

@@ -0,0 +1,5 @@
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8" /><title>Chrome PropertyDirection harness</title></head>
<body><main id="root">Initializing PropertyDirection harness.</main><script type="module" src="/src/chromePropertyDirectionHarness.tsx"></script></body>
</html>

View File

@@ -0,0 +1,5 @@
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8" /><title>Chrome PropertyFile harness</title></head>
<body><main id="root">Initializing PropertyFile harness.</main><script type="module" src="/src/chromePropertyFileHarness.tsx"></script></body>
</html>

View File

@@ -0,0 +1,5 @@
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8" /><title>Chrome PropertyFileIncluded harness</title></head>
<body><main id="root">Initializing PropertyFileIncluded harness.</main><script type="module" src="/src/chromePropertyFileIncludedHarness.tsx"></script></body>
</html>

View File

@@ -90,7 +90,7 @@
}
],
"area": 30,
"shapeId": "shape-mstl5fuc-1",
"shapeId": "shape-mswzv1xd-1",
"state": [
"Up-to-date"
],
@@ -139,7 +139,7 @@
"binder": {
"support": [],
"area": 30,
"shapeId": "shape-mstl5fuc-1",
"shapeId": "shape-mswzv1xd-1",
"state": [
"Up-to-date"
],
@@ -237,7 +237,7 @@
}
],
"area": 30,
"shapeId": "shape-mstl5fuc-1",
"shapeId": "shape-mswzv1xd-1",
"state": [
"Up-to-date"
],
@@ -286,7 +286,7 @@
"binder": {
"support": [],
"area": 30,
"shapeId": "shape-mstl5fuc-1",
"shapeId": "shape-mswzv1xd-1",
"state": [
"Up-to-date"
],
@@ -335,7 +335,7 @@
"binder": {
"support": [],
"area": 30,
"shapeId": "shape-mstl5fuc-1",
"shapeId": "shape-mswzv1xd-1",
"state": [
"Up-to-date"
],
@@ -433,7 +433,7 @@
}
],
"area": 30,
"shapeId": "shape-mstl5fuc-1",
"shapeId": "shape-mswzv1xd-1",
"state": [
"Up-to-date"
],
@@ -531,7 +531,7 @@
}
],
"area": 54,
"shapeId": "shape-mstl5fv3-3",
"shapeId": "shape-mswzv1y3-3",
"state": [
"Up-to-date"
],
@@ -629,7 +629,7 @@
}
],
"area": 30,
"shapeId": "shape-mstl5fuc-1",
"shapeId": "shape-mswzv1xd-1",
"state": [
"Up-to-date"
],
@@ -727,7 +727,7 @@
}
],
"area": 54,
"shapeId": "shape-mstl5fv3-3",
"shapeId": "shape-mswzv1y3-3",
"state": [
"Up-to-date"
],
@@ -825,7 +825,7 @@
}
],
"area": 54,
"shapeId": "shape-mstl5fv3-3",
"shapeId": "shape-mswzv1y3-3",
"state": [
"Up-to-date"
],
@@ -923,7 +923,7 @@
}
],
"area": 30,
"shapeId": "shape-mstl5fuc-1",
"shapeId": "shape-mswzv1xd-1",
"state": [
"Up-to-date"
],
@@ -1021,7 +1021,7 @@
}
],
"area": 54,
"shapeId": "shape-mstl5fv3-3",
"shapeId": "shape-mswzv1y3-3",
"state": [
"Up-to-date"
],
@@ -1059,8 +1059,8 @@
},
{
"path": "src/facade/mockFacade.ts",
"bytes": 160856,
"sha256": "998605cd6b17b82a2567006e6e34fba89f0a425afd383abad541dae03aebf478"
"bytes": 171839,
"sha256": "5124f81066ec2a292d4c770d9f48b4908e844ac874542f2af34c70c5514514a6"
},
{
"path": "src/facade/geometryRuntime.ts",

View File

@@ -0,0 +1,64 @@
{
"schemaVersion": 1,
"status": "pass",
"browserId": "chrome",
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/150.0.0.0 Safari/537.36",
"crossOriginIsolated": true,
"ui": {
"inputType": "number",
"label": "Acceleration",
"unit": "mm/s^2",
"beforeValue": 1000,
"afterValue": 500,
"documentVersion": 2,
"dirty": true,
"objectState": "touched",
"errors": []
},
"persistence": {
"mode": "sqlite-opfs",
"sqliteWasm": true,
"opfs": true,
"savedMode": "sqlite-opfs",
"loadedValue": 500,
"loadedType": "App::PropertyAcceleration",
"checkpointVersion": 2,
"recoveryIntegrity": "ok",
"fcstdElement": "Float",
"fcstdValue": "500"
},
"resource": {
"byteLength": 36,
"roundTrip": true,
"released": true,
"markerRemoved": true
},
"worker": {
"constructed": [
{
"name": "bitbybit-persistence",
"url": "http://127.0.0.1:43769/src/facade/persistenceWorker.ts?worker_file&type=module"
}
],
"requestTypes": [
"initialize",
"save-document",
"load-document",
"load-checkpoint",
"recovery-report",
"put-resource",
"get-resource",
"release-resource",
"get-resource",
"dispose"
],
"terminated": [
"bitbybit-persistence"
]
},
"release": {
"shapeCount": 0,
"kernelReferenceCount": 0,
"workerTerminated": true
}
}

View File

@@ -0,0 +1,71 @@
{
"schemaVersion": 1,
"status": "pass",
"browserId": "chrome",
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/150.0.0.0 Safari/537.36",
"crossOriginIsolated": true,
"ui": {
"areaReadOnly": true,
"beforeText": "20 mm^2",
"afterText": "0 mm^2",
"beforeArea": 20,
"afterArea": 0,
"beforeElementCount": 2,
"afterElementCount": 0,
"triggerLabel": "Clear subshape links",
"documentVersion": 2,
"dirty": true,
"objectState": "touched",
"errors": []
},
"persistence": {
"mode": "sqlite-opfs",
"sqliteWasm": true,
"opfs": true,
"savedMode": "sqlite-opfs",
"loadedArea": 0,
"loadedAreaType": "App::PropertyArea",
"loadedElementCount": 0,
"loadedElementsType": "App::PropertyLinkSubList",
"checkpointVersion": 2,
"recoveryIntegrity": "ok",
"fcstdAreaElement": "Float",
"fcstdAreaValue": "0",
"fcstdElementsElement": "LinkSubList",
"fcstdElementCount": 0
},
"resource": {
"byteLength": 28,
"roundTrip": true,
"released": true,
"markerRemoved": true
},
"worker": {
"constructed": [
{
"name": "bitbybit-persistence",
"url": "http://127.0.0.1:38423/src/facade/persistenceWorker.ts?worker_file&type=module"
}
],
"requestTypes": [
"initialize",
"save-document",
"load-document",
"load-checkpoint",
"recovery-report",
"put-resource",
"get-resource",
"release-resource",
"get-resource",
"dispose"
],
"terminated": [
"bitbybit-persistence"
]
},
"release": {
"shapeCount": 0,
"kernelReferenceCount": 0,
"workerTerminated": true
}
}

View File

@@ -0,0 +1,77 @@
{
"schemaVersion": 1,
"status": "pass",
"browserId": "chrome",
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/150.0.0.0 Safari/537.36",
"crossOriginIsolated": true,
"ui": {
"inputType": "text",
"label": "Bool list",
"beforeText": "false",
"afterText": "true, false, true, false",
"beforeValue": [
false
],
"afterValue": [
true,
false,
true,
false
],
"documentVersion": 2,
"dirty": true,
"objectState": "touched",
"errors": []
},
"persistence": {
"mode": "sqlite-opfs",
"sqliteWasm": true,
"opfs": true,
"savedMode": "sqlite-opfs",
"loadedValue": [
true,
false,
true,
false
],
"loadedType": "App::PropertyBoolList",
"checkpointVersion": 2,
"recoveryIntegrity": "ok",
"fcstdElement": "BoolList",
"fcstdValue": "[true,false,true,false]"
},
"resource": {
"byteLength": 32,
"roundTrip": true,
"released": true,
"markerRemoved": true
},
"worker": {
"constructed": [
{
"name": "bitbybit-persistence",
"url": "http://127.0.0.1:38629/src/facade/persistenceWorker.ts?worker_file&type=module"
}
],
"requestTypes": [
"initialize",
"save-document",
"load-document",
"load-checkpoint",
"recovery-report",
"put-resource",
"get-resource",
"release-resource",
"get-resource",
"dispose"
],
"terminated": [
"bitbybit-persistence"
]
},
"release": {
"shapeCount": 0,
"kernelReferenceCount": 0,
"workerTerminated": true
}
}

View File

@@ -0,0 +1,84 @@
{
"schemaVersion": 1,
"status": "pass",
"browserId": "chrome",
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/150.0.0.0 Safari/537.36",
"crossOriginIsolated": true,
"ui": {
"rgbInputType": "color",
"alphaInputType": "number",
"rgbLabel": "Colour RGB",
"alphaLabel": "Colour alpha",
"beforeHex": "#000000",
"afterHex": "#336699",
"beforeAlpha": "1",
"afterAlpha": 0.8,
"beforeValue": [
0,
0,
0,
1
],
"afterValue": [
0.2,
0.4,
0.6,
0.8
],
"documentVersion": 3,
"dirty": true,
"objectState": "touched",
"errors": []
},
"persistence": {
"mode": "sqlite-opfs",
"sqliteWasm": true,
"opfs": true,
"savedMode": "sqlite-opfs",
"loadedValue": [
0.2,
0.4,
0.6,
0.8
],
"loadedType": "App::PropertyColor",
"checkpointVersion": 3,
"recoveryIntegrity": "ok",
"fcstdElement": "PropertyColor",
"fcstdValue": "862362060"
},
"resource": {
"byteLength": 29,
"roundTrip": true,
"released": true,
"markerRemoved": true
},
"worker": {
"constructed": [
{
"name": "bitbybit-persistence",
"url": "http://127.0.0.1:36501/src/facade/persistenceWorker.ts?worker_file&type=module"
}
],
"requestTypes": [
"initialize",
"save-document",
"load-document",
"load-checkpoint",
"recovery-report",
"put-resource",
"get-resource",
"release-resource",
"get-resource",
"dispose"
],
"terminated": [
"bitbybit-persistence"
]
},
"release": {
"shapeCount": 0,
"kernelReferenceCount": 0,
"workerTerminated": true
}
}

View File

@@ -0,0 +1,131 @@
{
"schemaVersion": 1,
"status": "pass",
"browserId": "chrome",
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/150.0.0.0 Safari/537.36",
"crossOriginIsolated": true,
"ui": {
"rgbInputTypes": [
"color",
"color"
],
"alphaInputTypes": [
"number",
"number"
],
"rgbLabels": [
"Colour list 1 RGB",
"Colour list 2 RGB"
],
"alphaLabels": [
"Colour list 1 alpha",
"Colour list 2 alpha"
],
"addLabel": "Add Colour list color",
"removeLabel": "Remove Colour list 3",
"beforeHex": [
"#000000"
],
"afterHex": [
"#336699",
"#112233"
],
"beforeAlpha": [
"1"
],
"afterAlpha": [
0.8,
0.4
],
"beforeValue": [
[
0,
0,
0,
1
]
],
"afterValue": [
[
0.2,
0.4,
0.6,
0.8
],
[
0.06666666666666667,
0.13333333333333333,
0.2,
0.4
]
],
"beforeItemCount": 1,
"peakItemCount": 3,
"afterItemCount": 2,
"documentVersion": 8,
"dirty": true,
"objectState": "touched",
"errors": []
},
"persistence": {
"mode": "sqlite-opfs",
"sqliteWasm": true,
"opfs": true,
"savedMode": "sqlite-opfs",
"loadedValue": [
[
0.2,
0.4,
0.6,
0.8
],
[
0.06666666666666667,
0.13333333333333333,
0.2,
0.4
]
],
"loadedType": "App::PropertyColorList",
"checkpointVersion": 8,
"recoveryIntegrity": "ok",
"fcstdElement": "ColorList",
"fcstdValue": "[[0.2,0.4,0.6,0.8],[0.06666666666666667,0.13333333333333333,0.2,0.4]]",
"fcstdResourcePath": "ColourList",
"fcstdResourceBytes": 12
},
"resource": {
"byteLength": 33,
"roundTrip": true,
"released": true,
"markerRemoved": true
},
"worker": {
"constructed": [
{
"name": "bitbybit-persistence",
"url": "http://127.0.0.1:40471/src/facade/persistenceWorker.ts?worker_file&type=module"
}
],
"requestTypes": [
"initialize",
"save-document",
"load-document",
"load-checkpoint",
"recovery-report",
"put-resource",
"get-resource",
"release-resource",
"get-resource",
"dispose"
],
"terminated": [
"bitbybit-persistence"
]
},
"release": {
"shapeCount": 0,
"kernelReferenceCount": 0,
"workerTerminated": true
}
}

View File

@@ -0,0 +1,83 @@
{
"schemaVersion": 1,
"status": "pass",
"browserId": "chrome",
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/150.0.0.0 Safari/537.36",
"crossOriginIsolated": true,
"ui": {
"inputTypes": [
"number",
"number",
"number"
],
"labels": [
"Normal x",
"Normal y",
"Normal z"
],
"beforeValue": {
"x": 0,
"y": 0,
"z": 1
},
"afterValue": {
"x": 0.25,
"y": -0.5,
"z": 1.5
},
"documentVersion": 4,
"dirty": true,
"objectState": "touched",
"errors": []
},
"persistence": {
"mode": "sqlite-opfs",
"sqliteWasm": true,
"opfs": true,
"savedMode": "sqlite-opfs",
"loadedValue": {
"x": 0.25,
"y": -0.5,
"z": 1.5
},
"loadedType": "App::PropertyDirection",
"checkpointVersion": 4,
"recoveryIntegrity": "ok",
"fcstdElement": "PropertyVector",
"fcstdValue": "{\"x\":0.25,\"y\":-0.5,\"z\":1.5}"
},
"resource": {
"byteLength": 33,
"roundTrip": true,
"released": true,
"markerRemoved": true
},
"worker": {
"constructed": [
{
"name": "bitbybit-persistence",
"url": "http://127.0.0.1:43033/src/facade/persistenceWorker.ts?worker_file&type=module"
}
],
"requestTypes": [
"initialize",
"save-document",
"load-document",
"load-checkpoint",
"recovery-report",
"put-resource",
"get-resource",
"release-resource",
"get-resource",
"dispose"
],
"terminated": [
"bitbybit-persistence"
]
},
"release": {
"shapeCount": 0,
"kernelReferenceCount": 0,
"workerTerminated": true
}
}

View File

@@ -0,0 +1,63 @@
{
"schemaVersion": 1,
"status": "pass",
"browserId": "chrome",
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/150.0.0.0 Safari/537.36",
"crossOriginIsolated": true,
"ui": {
"inputType": "text",
"label": "File name",
"beforeValue": "project-files/initial.obj",
"afterValue": "project-files/chrome-updated.obj",
"documentVersion": 2,
"dirty": true,
"objectState": "touched",
"errors": []
},
"persistence": {
"mode": "sqlite-opfs",
"sqliteWasm": true,
"opfs": true,
"savedMode": "sqlite-opfs",
"loadedValue": "project-files/chrome-updated.obj",
"loadedType": "App::PropertyFile",
"checkpointVersion": 2,
"recoveryIntegrity": "ok",
"fcstdElement": "String",
"fcstdValue": "project-files/chrome-updated.obj"
},
"resource": {
"byteLength": 63,
"roundTrip": true,
"released": true,
"markerRemoved": true
},
"worker": {
"constructed": [
{
"name": "bitbybit-persistence",
"url": "http://127.0.0.1:45939/src/facade/persistenceWorker.ts?worker_file&type=module"
}
],
"requestTypes": [
"initialize",
"save-document",
"load-document",
"load-checkpoint",
"recovery-report",
"put-resource",
"get-resource",
"release-resource",
"get-resource",
"dispose"
],
"terminated": [
"bitbybit-persistence"
]
},
"release": {
"shapeCount": 0,
"kernelReferenceCount": 0,
"workerTerminated": true
}
}

View File

@@ -0,0 +1,85 @@
{
"schemaVersion": 1,
"status": "pass",
"browserId": "chrome",
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/150.0.0.0 Safari/537.36",
"crossOriginIsolated": true,
"ui": {
"inputType": "file",
"label": "Embedded file",
"beforeName": "Empty",
"afterName": "chrome-resource.bin",
"afterValue": {
"schemaVersion": 1,
"archiveName": "chrome-resource.bin",
"resourceHash": "934b31426acd0c2b98cddae880e72404534f5656e5e82cf1ab15ad661f8f3b2b",
"byteLength": 16,
"mediaType": "application/octet-stream"
},
"documentVersion": 2,
"dirty": true,
"objectState": "touched",
"notices": [
"chrome-resource.bin embedded"
]
},
"persistence": {
"mode": "sqlite-opfs",
"sqliteWasm": true,
"opfs": true,
"savedMode": "sqlite-opfs",
"loadedValue": {
"schemaVersion": 1,
"archiveName": "chrome-resource.bin",
"resourceHash": "934b31426acd0c2b98cddae880e72404534f5656e5e82cf1ab15ad661f8f3b2b",
"byteLength": 16,
"mediaType": "application/octet-stream"
},
"loadedType": "App::PropertyFileIncluded",
"checkpointVersion": 2,
"recoveryIntegrity": "ok",
"fcstdElement": "FileIncluded",
"fcstdResourcePath": "chrome-resource.bin",
"fcstdResourceBytes": 16,
"fcstdResourceMatches": true
},
"resource": {
"documentByteLength": 16,
"documentRoundTrip": true,
"independentByteLength": 48,
"independentRoundTrip": true,
"independentReleased": true,
"markerRemoved": true
},
"worker": {
"constructed": [
{
"name": "bitbybit-persistence",
"url": "http://127.0.0.1:37353/src/facade/persistenceWorker.ts?worker_file&type=module"
}
],
"requestTypes": [
"initialize",
"put-resource",
"save-document",
"load-document",
"load-checkpoint",
"recovery-report",
"get-resource",
"get-resource",
"put-resource",
"get-resource",
"release-resource",
"get-resource",
"dispose"
],
"terminated": [
"bitbybit-persistence"
]
},
"release": {
"shapeCount": 0,
"kernelReferenceCount": 0,
"workerTerminated": true
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -8,5 +8,540 @@
"ordering": "completed task IDs must form a contiguous prefix of the generated follow-up queue",
"evidence": "every completed task must name at least one machine-checkable artifact or focused check"
},
"completedTasks": []
"completedTasks": [
{
"id": "PROP-app-propertyacceleration-A",
"evidence": [
"config/freecad-property-acceleration-inventory.json",
"check:freecad-property-acceleration-inventory"
]
},
{
"id": "PROP-app-propertyacceleration-B",
"evidence": [
"config/freecad-property-acceleration-success.json",
"check:freecad-property-acceleration-success"
]
},
{
"id": "PROP-app-propertyacceleration-C",
"evidence": [
"config/freecad-property-acceleration-failure.json",
"check:freecad-property-acceleration-failure"
]
},
{
"id": "PROP-app-propertyacceleration-D",
"evidence": [
"config/freecad-property-acceleration-mutation.json",
"check:freecad-property-acceleration-mutation"
]
},
{
"id": "PROP-app-propertyacceleration-E",
"evidence": [
"src/facade/types.ts",
"src/facade/fcstd.ts",
"src/facade/mockFacade.ts",
"test:freecad-property-acceleration-facade"
]
},
{
"id": "PROP-app-propertyacceleration-F",
"evidence": [
"tests/propertyAccelerationTransaction.test.ts",
"test:freecad-property-acceleration-transaction"
]
},
{
"id": "PROP-app-propertyacceleration-G",
"evidence": [
"config/freecad-property-acceleration-roundtrip.json",
"check:freecad-property-acceleration-roundtrip"
]
},
{
"id": "PROP-app-propertyacceleration-H",
"evidence": [
"config/chrome-property-acceleration-verification.json",
"check:chrome-property-acceleration"
]
},
{
"id": "PROP-app-propertyacceleration-I",
"evidence": [
"config/freecad-property-acceleration-promotion.json",
"check:freecad-property-acceleration-promotion"
]
},
{
"id": "PROP-app-propertyarea-A",
"evidence": [
"config/freecad-property-area-inventory.json",
"check:freecad-property-area-inventory"
]
},
{
"id": "PROP-app-propertyarea-B",
"evidence": [
"config/freecad-property-area-success.json",
"check:freecad-property-area-success"
]
},
{
"id": "PROP-app-propertyarea-C",
"evidence": [
"config/freecad-property-area-failure.json",
"check:freecad-property-area-failure"
]
},
{
"id": "PROP-app-propertyarea-D",
"evidence": [
"config/freecad-property-area-mutation.json",
"check:freecad-property-area-mutation"
]
},
{
"id": "PROP-app-propertyarea-E",
"evidence": [
"src/facade/types.ts",
"src/facade/fcstd.ts",
"src/facade/mockFacade.ts",
"tests/propertyAreaFacade.test.ts",
"test:freecad-property-area-facade"
]
},
{
"id": "PROP-app-propertyarea-F",
"evidence": [
"tests/propertyAreaTransaction.test.ts",
"test:freecad-property-area-transaction"
]
},
{
"id": "PROP-app-propertyarea-G",
"evidence": [
"config/freecad-property-area-roundtrip.json",
"check:freecad-property-area-roundtrip"
]
},
{
"id": "PROP-app-propertyarea-H",
"evidence": [
"config/chrome-property-area-verification.json",
"check:chrome-property-area"
]
},
{
"id": "PROP-app-propertyarea-I",
"evidence": [
"config/freecad-property-area-promotion.json",
"check:freecad-property-area-promotion"
]
},
{
"id": "PROP-app-propertyboollist-A",
"evidence": [
"config/freecad-property-boollist-inventory.json",
"check:freecad-property-boollist-inventory"
]
},
{
"id": "PROP-app-propertyboollist-B",
"evidence": [
"config/freecad-property-boollist-success.json",
"check:freecad-property-boollist-success"
]
},
{
"id": "PROP-app-propertyboollist-C",
"evidence": [
"config/freecad-property-boollist-failure.json",
"check:freecad-property-boollist-failure"
]
},
{
"id": "PROP-app-propertyboollist-D",
"evidence": [
"config/freecad-property-boollist-mutation.json",
"check:freecad-property-boollist-mutation"
]
},
{
"id": "PROP-app-propertyboollist-E",
"evidence": [
"src/facade/types.ts",
"src/facade/fcstd.ts",
"src/facade/mockFacade.ts",
"src/App.tsx",
"tests/propertyBoolListFacade.test.ts",
"test:freecad-property-boollist-facade"
]
},
{
"id": "PROP-app-propertyboollist-F",
"evidence": [
"tests/propertyBoolListTransaction.test.ts",
"test:freecad-property-boollist-transaction"
]
},
{
"id": "PROP-app-propertyboollist-G",
"evidence": [
"config/freecad-property-boollist-roundtrip.json",
"check:freecad-property-boollist-roundtrip"
]
},
{
"id": "PROP-app-propertyboollist-H",
"evidence": [
"config/chrome-property-boollist-verification.json",
"check:chrome-property-boollist"
]
},
{
"id": "PROP-app-propertyboollist-I",
"evidence": [
"config/freecad-property-boollist-promotion.json",
"check:freecad-property-boollist-promotion"
]
},
{
"id": "PROP-app-propertycolor-A",
"evidence": [
"config/freecad-property-color-inventory.json",
"check:freecad-property-color-inventory"
]
},
{
"id": "PROP-app-propertycolor-B",
"evidence": [
"config/freecad-property-color-success.json",
"check:freecad-property-color-success"
]
},
{
"id": "PROP-app-propertycolor-C",
"evidence": [
"config/freecad-property-color-failure.json",
"check:freecad-property-color-failure"
]
},
{
"id": "PROP-app-propertycolor-D",
"evidence": [
"config/freecad-property-color-mutation.json",
"check:freecad-property-color-mutation"
]
},
{
"id": "PROP-app-propertycolor-E",
"evidence": [
"src/facade/types.ts",
"src/facade/fcstd.ts",
"src/facade/mockFacade.ts",
"src/App.tsx",
"tests/propertyColorFacade.test.ts",
"test:freecad-property-color-facade"
]
},
{
"id": "PROP-app-propertycolor-F",
"evidence": [
"tests/propertyColorTransaction.test.ts",
"test:freecad-property-color-transaction"
]
},
{
"id": "PROP-app-propertycolor-G",
"evidence": [
"config/freecad-property-color-roundtrip.json",
"check:freecad-property-color-roundtrip"
]
},
{
"id": "PROP-app-propertycolor-H",
"evidence": [
"config/chrome-property-color-verification.json",
"check:chrome-property-color"
]
},
{
"id": "PROP-app-propertycolor-I",
"evidence": [
"config/freecad-property-color-promotion.json",
"check:freecad-property-color-promotion"
]
},
{
"id": "PROP-app-propertycolorlist-A",
"evidence": [
"config/freecad-property-colorlist-inventory.json",
"check:freecad-property-colorlist-inventory"
]
},
{
"id": "PROP-app-propertycolorlist-B",
"evidence": [
"config/freecad-property-colorlist-success.json",
"check:freecad-property-colorlist-success"
]
},
{
"id": "PROP-app-propertycolorlist-C",
"evidence": [
"config/freecad-property-colorlist-failure.json",
"check:freecad-property-colorlist-failure"
]
},
{
"id": "PROP-app-propertycolorlist-D",
"evidence": [
"config/freecad-property-colorlist-mutation.json",
"check:freecad-property-colorlist-mutation"
]
},
{
"id": "PROP-app-propertycolorlist-E",
"evidence": [
"src/facade/types.ts",
"src/facade/fcstd.ts",
"src/facade/mockFacade.ts",
"src/App.tsx",
"tests/propertyColorListFacade.test.ts",
"test:freecad-property-colorlist-facade"
]
},
{
"id": "PROP-app-propertycolorlist-F",
"evidence": [
"tests/propertyColorListTransaction.test.ts",
"test:freecad-property-colorlist-transaction"
]
},
{
"id": "PROP-app-propertycolorlist-G",
"evidence": [
"config/freecad-property-colorlist-roundtrip.json",
"check:freecad-property-colorlist-roundtrip"
]
},
{
"id": "PROP-app-propertycolorlist-H",
"evidence": [
"config/chrome-property-colorlist-verification.json",
"check:chrome-property-colorlist"
]
},
{
"id": "PROP-app-propertycolorlist-I",
"evidence": [
"config/freecad-property-colorlist-promotion.json",
"check:freecad-property-colorlist-promotion"
]
},
{
"id": "PROP-app-propertydirection-A",
"evidence": [
"config/freecad-property-direction-inventory.json",
"check:freecad-property-direction-inventory"
]
},
{
"id": "PROP-app-propertydirection-B",
"evidence": [
"config/freecad-property-direction-success.json",
"check:freecad-property-direction-success"
]
},
{
"id": "PROP-app-propertydirection-C",
"evidence": [
"config/freecad-property-direction-failure.json",
"check:freecad-property-direction-failure"
]
},
{
"id": "PROP-app-propertydirection-D",
"evidence": [
"config/freecad-property-direction-mutation.json",
"check:freecad-property-direction-mutation"
]
},
{
"id": "PROP-app-propertydirection-E",
"evidence": [
"src/facade/types.ts",
"src/facade/fcstd.ts",
"src/facade/mockFacade.ts",
"src/App.tsx",
"tests/propertyDirectionFacade.test.ts",
"test:freecad-property-direction-facade"
]
},
{
"id": "PROP-app-propertydirection-F",
"evidence": [
"tests/propertyDirectionTransaction.test.ts",
"test:freecad-property-direction-transaction"
]
},
{
"id": "PROP-app-propertydirection-G",
"evidence": [
"config/freecad-property-direction-roundtrip.json",
"check:freecad-property-direction-roundtrip"
]
},
{
"id": "PROP-app-propertydirection-H",
"evidence": [
"config/chrome-property-direction-verification.json",
"check:chrome-property-direction"
]
},
{
"id": "PROP-app-propertydirection-I",
"evidence": [
"config/freecad-property-direction-promotion.json",
"check:freecad-property-direction-promotion"
]
},
{
"id": "PROP-app-propertyfile-A",
"evidence": [
"config/freecad-property-file-inventory.json",
"check:freecad-property-file-inventory"
]
},
{
"id": "PROP-app-propertyfile-B",
"evidence": [
"config/freecad-property-file-success.json",
"check:freecad-property-file-success"
]
},
{
"id": "PROP-app-propertyfile-C",
"evidence": [
"config/freecad-property-file-failure.json",
"check:freecad-property-file-failure"
]
},
{
"id": "PROP-app-propertyfile-D",
"evidence": [
"config/freecad-property-file-mutation.json",
"check:freecad-property-file-mutation"
]
},
{
"id": "PROP-app-propertyfile-E",
"evidence": [
"src/facade/types.ts",
"src/facade/fcstd.ts",
"src/facade/mockFacade.ts",
"src/App.tsx",
"tests/propertyFileFacade.test.ts",
"test:freecad-property-file-facade"
]
},
{
"id": "PROP-app-propertyfile-F",
"evidence": [
"tests/propertyFileTransaction.test.ts",
"test:freecad-property-file-transaction"
]
},
{
"id": "PROP-app-propertyfile-G",
"evidence": [
"config/freecad-property-file-roundtrip.json",
"check:freecad-property-file-roundtrip"
]
},
{
"id": "PROP-app-propertyfile-H",
"evidence": [
"config/chrome-property-file-verification.json",
"check:chrome-property-file"
]
},
{
"id": "PROP-app-propertyfile-I",
"evidence": [
"config/freecad-property-file-promotion.json",
"check:freecad-property-file-promotion"
]
},
{
"id": "PROP-app-propertyfileincluded-A",
"evidence": [
"config/freecad-property-fileincluded-inventory.json",
"check:freecad-property-fileincluded-inventory"
]
},
{
"id": "PROP-app-propertyfileincluded-B",
"evidence": [
"config/freecad-property-fileincluded-success.json",
"check:freecad-property-fileincluded-success"
]
},
{
"id": "PROP-app-propertyfileincluded-C",
"evidence": [
"config/freecad-property-fileincluded-failure.json",
"check:freecad-property-fileincluded-failure"
]
},
{
"id": "PROP-app-propertyfileincluded-D",
"evidence": [
"config/freecad-property-fileincluded-mutation.json",
"check:freecad-property-fileincluded-mutation"
]
},
{
"id": "PROP-app-propertyfileincluded-E",
"evidence": [
"src/facade/includedFile.ts",
"src/facade/types.ts",
"src/facade/fcstd.ts",
"src/facade/mockFacade.ts",
"src/App.tsx",
"tests/propertyFileIncludedFacade.test.ts",
"test:freecad-property-fileincluded-facade"
]
},
{
"id": "PROP-app-propertyfileincluded-F",
"evidence": [
"tests/propertyFileIncludedTransaction.test.ts",
"test:freecad-property-fileincluded-transaction"
]
},
{
"id": "PROP-app-propertyfileincluded-G",
"evidence": [
"config/freecad-property-fileincluded-roundtrip.json",
"check:freecad-property-fileincluded-roundtrip"
]
},
{
"id": "PROP-app-propertyfileincluded-H",
"evidence": [
"config/chrome-property-fileincluded-verification.json",
"check:chrome-property-fileincluded"
]
},
{
"id": "PROP-app-propertyfileincluded-I",
"evidence": [
"config/freecad-property-fileincluded-promotion.json",
"check:freecad-property-fileincluded-promotion"
]
}
]
}

View File

@@ -7,8 +7,8 @@
},
"source": {
"path": ".cache/freecad/reference-desktop.json",
"bytes": 4699380,
"sha256": "30ffbbdb4139a682486e6fed482a8d8d8a88c287a38dfec8d814e38f4e70fc80"
"bytes": 2298709,
"sha256": "082400ec7379e8efc2af16709032d45890d7092277967b714acb05761fd1c2a7"
},
"runtime": {
"registeredObjectTypes": 352,
@@ -37,22 +37,22 @@
},
"supportSummary": {
"native-editable-codec": {
"typeCount": 22,
"recordCount": 4304
"typeCount": 30,
"recordCount": 4361
},
"native-specialized-codec": {
"typeCount": 5,
"recordCount": 683
},
"opaque-fcstd-proxy": {
"typeCount": 58,
"recordCount": 523
"typeCount": 50,
"recordCount": 466
}
},
"types": [
{
"typeId": "App::PropertyAcceleration",
"support": "opaque-fcstd-proxy",
"support": "native-editable-codec",
"recordCount": 1,
"objectTypeCount": 1,
"statusNames": []
@@ -71,7 +71,7 @@
},
{
"typeId": "App::PropertyArea",
"support": "opaque-fcstd-proxy",
"support": "native-editable-codec",
"recordCount": 1,
"objectTypeCount": 1,
"statusNames": [
@@ -100,7 +100,7 @@
},
{
"typeId": "App::PropertyBoolList",
"support": "opaque-fcstd-proxy",
"support": "native-editable-codec",
"recordCount": 7,
"objectTypeCount": 7,
"statusNames": [
@@ -111,21 +111,21 @@
},
{
"typeId": "App::PropertyColor",
"support": "opaque-fcstd-proxy",
"support": "native-editable-codec",
"recordCount": 8,
"objectTypeCount": 8,
"statusNames": []
},
{
"typeId": "App::PropertyColorList",
"support": "opaque-fcstd-proxy",
"support": "native-editable-codec",
"recordCount": 2,
"objectTypeCount": 2,
"statusNames": []
},
{
"typeId": "App::PropertyDirection",
"support": "opaque-fcstd-proxy",
"support": "native-editable-codec",
"recordCount": 2,
"objectTypeCount": 2,
"statusNames": []
@@ -165,14 +165,14 @@
},
{
"typeId": "App::PropertyFile",
"support": "opaque-fcstd-proxy",
"support": "native-editable-codec",
"recordCount": 16,
"objectTypeCount": 12,
"statusNames": []
},
{
"typeId": "App::PropertyFileIncluded",
"support": "opaque-fcstd-proxy",
"support": "native-editable-codec",
"recordCount": 20,
"objectTypeCount": 15,
"statusNames": [
@@ -902,10 +902,10 @@
},
"harness": {
"path": "scripts/run-freecad-native-property-semantics.mjs",
"bytes": 6166,
"sha256": "f6fcab14a46c9e7597f10808b31eb10cd5196bd90144c5b6a7a50e6993a1c3f6"
"bytes": 6615,
"sha256": "fad232fd5a013d40639069df2f8752f04fc5d373c6a7a7ece8ed3276612af9f3"
},
"exactPromotionReady": false,
"exactBlocker": "58 runtime property types and 523 records remain opaque-only; complete native document and property semantics",
"generatedAt": "2026-08-14T22:37:52.376Z"
"exactBlocker": "50 runtime property types and 466 records remain opaque-only; complete native document and property semantics",
"generatedAt": "2026-08-17T08:49:24.621Z"
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,193 @@
{
"baselineId": "freecad-1.1.1-property-acceleration-failure",
"cancellationBoundary": {
"classification": "synchronous-property-setter",
"reason": "no-native-cancel-hook",
"replacement": "abort-active-document-transaction",
"supported": false
},
"disabled": {
"after": {
"numeric": 1000,
"raw": "1000.0 mm/s^2",
"unit": "Unit: mm/s^2 (1,0,-2,0,0,0,0,0) [Acceleration]"
},
"afterObjects": [
{
"name": "AccelerationProbe",
"typeId": "Robot::TrajectoryDressUpObject"
}
],
"before": {
"numeric": 1000,
"raw": "1000.0 mm/s^2",
"unit": "Unit: mm/s^2 (1,0,-2,0,0,0,0,0) [Acceleration]"
},
"beforeObjects": [
{
"name": "AccelerationProbe",
"typeId": "Robot::TrajectoryDressUpObject"
}
],
"classification": "editor-read-only-and-python-immutable",
"editorMode": [
"ReadOnly"
],
"exception": {
"message": "Object attribute 'Acceleration' is read-only",
"type": "AttributeError"
},
"objectsPreserved": true,
"requested": "750 mm/s^2",
"restoredEditorMode": [],
"restoredStatus": [],
"status": [
"Immutable",
"ReadOnly"
],
"valuePreserved": true
},
"documentIntegrity": {
"finalObjects": [
{
"name": "AccelerationProbe",
"typeId": "Robot::TrajectoryDressUpObject"
}
],
"initialObjects": [
{
"name": "AccelerationProbe",
"typeId": "Robot::TrajectoryDressUpObject"
}
],
"objectCount": 1,
"objectsPreserved": true
},
"failures": [
{
"after": {
"numeric": 1000,
"raw": "1000.0 mm/s^2",
"unit": "Unit: mm/s^2 (1,0,-2,0,0,0,0,0) [Acceleration]"
},
"afterObjects": [
{
"name": "AccelerationProbe",
"typeId": "Robot::TrajectoryDressUpObject"
}
],
"before": {
"numeric": 1000,
"raw": "1000.0 mm/s^2",
"unit": "Unit: mm/s^2 (1,0,-2,0,0,0,0,0) [Acceleration]"
},
"beforeObjects": [
{
"name": "AccelerationProbe",
"typeId": "Robot::TrajectoryDressUpObject"
}
],
"exception": {
"message": "Not matching Unit!",
"type": "ArithmeticError"
},
"id": "wrong-dimension",
"objectsPreserved": true,
"polluted": false,
"requested": "5 mm",
"valuePreserved": true
},
{
"after": {
"numeric": 1000,
"raw": "1000.0 mm/s^2",
"unit": "Unit: mm/s^2 (1,0,-2,0,0,0,0,0) [Acceleration]"
},
"afterObjects": [
{
"name": "AccelerationProbe",
"typeId": "Robot::TrajectoryDressUpObject"
}
],
"before": {
"numeric": 1000,
"raw": "1000.0 mm/s^2",
"unit": "Unit: mm/s^2 (1,0,-2,0,0,0,0,0) [Acceleration]"
},
"beforeObjects": [
{
"name": "AccelerationProbe",
"typeId": "Robot::TrajectoryDressUpObject"
}
],
"exception": {
"message": "syntax error",
"type": "ParserError"
},
"id": "malformed-text",
"objectsPreserved": true,
"polluted": false,
"requested": "not-a-quantity",
"valuePreserved": true
}
],
"freecadVersion": "1.1.1",
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
"initial": {
"numeric": 1000,
"raw": "1000.0 mm/s^2",
"unit": "Unit: mm/s^2 (1,0,-2,0,0,0,0,0) [Acceleration]"
},
"object": {
"name": "AccelerationProbe",
"typeId": "Robot::TrajectoryDressUpObject"
},
"property": {
"name": "Acceleration",
"typeId": "App::PropertyAcceleration"
},
"schemaVersion": 1,
"status": "pass",
"transaction": {
"activeAfterAbort": {
"id": 0,
"name": ""
},
"activeAfterEdit": {
"id": 1,
"name": "property-acceleration-cancel"
},
"afterAbort": {
"numeric": 1000,
"raw": "1000.0 mm/s^2",
"unit": "Unit: mm/s^2 (1,0,-2,0,0,0,0,0) [Acceleration]"
},
"before": {
"numeric": 1000,
"raw": "1000.0 mm/s^2",
"unit": "Unit: mm/s^2 (1,0,-2,0,0,0,0,0) [Acceleration]"
},
"edited": {
"numeric": 250,
"raw": "250.0 mm/s^2",
"unit": "Unit: mm/s^2 (1,0,-2,0,0,0,0,0) [Acceleration]"
},
"objectsAfter": [
{
"name": "AccelerationProbe",
"typeId": "Robot::TrajectoryDressUpObject"
}
],
"objectsBefore": [
{
"name": "AccelerationProbe",
"typeId": "Robot::TrajectoryDressUpObject"
}
],
"objectsRestored": true,
"pendingAfterAbort": false,
"pendingAfterEdit": true,
"restored": true,
"undoMode": 1
}
}

View File

@@ -0,0 +1,49 @@
{
"schemaVersion": 1,
"status": "pass",
"baseline": {
"freecadVersion": "1.1.1",
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
},
"propertyType": "App::PropertyAcceleration",
"recordCount": 1,
"records": [
{
"objectTypeId": "Robot::TrajectoryDressUpObject",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "Acceleration",
"group": "TrajectoryDressUp",
"status": [],
"defaultRaw": "1000.0 mm/s^2",
"valueModel": {
"kind": "quantity",
"dimension": "length/time^2",
"defaultValue": 1000,
"defaultUnit": "mm/s^2",
"acceptedBoundaryEvidence": "inventory-only; value and boundary acceptance remain pending in phase B/C"
},
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "Robot::TrajectoryDressUpObject",
"source": "Document.supportedTypes runtime inventory"
}
}
],
"source": {
"path": ".cache/freecad/reference-desktop.json",
"bytes": 2298709,
"sha256": "082400ec7379e8efc2af16709032d45890d7092277967b714acb05761fd1c2a7"
},
"classification": "opaque-fcstd-proxy",
"nextPhases": [
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I"
]
}

View File

@@ -0,0 +1,347 @@
{
"baselineId": "freecad-1.1.1-property-acceleration-mutation",
"before": {
"editorMode": [],
"mustExecute": false,
"objectState": [
"Up-to-date"
],
"propertyStatus": [],
"shape": {
"applicable": false
},
"source": {
"name": "SourceTrajectory",
"typeId": "Robot::TrajectoryObject"
},
"statusString": "Valid",
"trajectory": {
"contentSha256": "1a29d89dac9b062e0ea210375b9aeb1f7ada2ed763939e339eb31c05d4ee678f",
"duration": 0.141421356,
"length": 5,
"waypointCount": 2,
"waypoints": [
{
"acceleration": 1000,
"base": 0,
"continuous": false,
"name": "Pt",
"position": [
1,
2,
3
],
"tool": 0,
"type": "LIN",
"velocity": 2000
},
{
"acceleration": 1000,
"base": 0,
"continuous": false,
"name": "Pt1",
"position": [
4,
6,
3
],
"tool": 0,
"type": "LIN",
"velocity": 2000
}
]
},
"useAcceleration": true,
"value": {
"numeric": 1000,
"raw": "1000.0 mm/s^2",
"unit": "Unit: mm/s^2 (1,0,-2,0,0,0,0,0) [Acceleration]"
}
},
"classification": {
"geometry": "not-applicable-no-shape-property",
"propertyChanged": true,
"propertyRestored": true,
"semanticStateRestored": true,
"trajectoryChanged": true,
"trajectoryRestored": true
},
"document": {
"objectsBefore": [
{
"name": "SourceTrajectory",
"typeId": "Robot::TrajectoryObject"
},
{
"name": "AccelerationProbe",
"typeId": "Robot::TrajectoryDressUpObject"
}
],
"objectsPreserved": true,
"objectsRestored": [
{
"name": "SourceTrajectory",
"typeId": "Robot::TrajectoryObject"
},
{
"name": "AccelerationProbe",
"typeId": "Robot::TrajectoryDressUpObject"
}
]
},
"edited": {
"editorMode": [],
"mustExecute": false,
"objectState": [
"Up-to-date"
],
"propertyStatus": [],
"shape": {
"applicable": false
},
"source": {
"name": "SourceTrajectory",
"typeId": "Robot::TrajectoryObject"
},
"statusString": "Valid",
"trajectory": {
"contentSha256": "a7febf338d0c6527d9ad31e709f379092fd6f0144714ee29f973cd77567ecf2c",
"duration": 0.2,
"length": 5,
"waypointCount": 2,
"waypoints": [
{
"acceleration": 500,
"base": 0,
"continuous": false,
"name": "Pt",
"position": [
1,
2,
3
],
"tool": 0,
"type": "LIN",
"velocity": 2000
},
{
"acceleration": 500,
"base": 0,
"continuous": false,
"name": "Pt1",
"position": [
4,
6,
3
],
"tool": 0,
"type": "LIN",
"velocity": 2000
}
]
},
"useAcceleration": true,
"value": {
"numeric": 500,
"raw": "500.0 mm/s^2",
"unit": "Unit: mm/s^2 (1,0,-2,0,0,0,0,0) [Acceleration]"
}
},
"freecadVersion": "1.1.1",
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
"object": {
"name": "AccelerationProbe",
"typeId": "Robot::TrajectoryDressUpObject"
},
"property": {
"name": "Acceleration",
"typeId": "App::PropertyAcceleration"
},
"recompute": {
"edit": 1,
"initial": 2,
"restore": 1
},
"restored": {
"editorMode": [],
"mustExecute": false,
"objectState": [
"Up-to-date"
],
"propertyStatus": [],
"shape": {
"applicable": false
},
"source": {
"name": "SourceTrajectory",
"typeId": "Robot::TrajectoryObject"
},
"statusString": "Valid",
"trajectory": {
"contentSha256": "1a29d89dac9b062e0ea210375b9aeb1f7ada2ed763939e339eb31c05d4ee678f",
"duration": 0.141421356,
"length": 5,
"waypointCount": 2,
"waypoints": [
{
"acceleration": 1000,
"base": 0,
"continuous": false,
"name": "Pt",
"position": [
1,
2,
3
],
"tool": 0,
"type": "LIN",
"velocity": 2000
},
{
"acceleration": 1000,
"base": 0,
"continuous": false,
"name": "Pt1",
"position": [
4,
6,
3
],
"tool": 0,
"type": "LIN",
"velocity": 2000
}
]
},
"useAcceleration": true,
"value": {
"numeric": 1000,
"raw": "1000.0 mm/s^2",
"unit": "Unit: mm/s^2 (1,0,-2,0,0,0,0,0) [Acceleration]"
}
},
"schemaVersion": 1,
"source": {
"before": {
"contentSha256": "cb93c2855ce67ed800416d985edfe22d80035a3313015573d78252bc17619db9",
"duration": 0.447213595,
"length": 5,
"waypointCount": 2,
"waypoints": [
{
"acceleration": 100,
"base": 0,
"continuous": false,
"name": "Pt",
"position": [
1,
2,
3
],
"tool": 0,
"type": "LIN",
"velocity": 2000
},
{
"acceleration": 100,
"base": 0,
"continuous": false,
"name": "Pt1",
"position": [
4,
6,
3
],
"tool": 0,
"type": "LIN",
"velocity": 2000
}
]
},
"edited": {
"contentSha256": "cb93c2855ce67ed800416d985edfe22d80035a3313015573d78252bc17619db9",
"duration": 0.447213595,
"length": 5,
"waypointCount": 2,
"waypoints": [
{
"acceleration": 100,
"base": 0,
"continuous": false,
"name": "Pt",
"position": [
1,
2,
3
],
"tool": 0,
"type": "LIN",
"velocity": 2000
},
{
"acceleration": 100,
"base": 0,
"continuous": false,
"name": "Pt1",
"position": [
4,
6,
3
],
"tool": 0,
"type": "LIN",
"velocity": 2000
}
]
},
"preserved": true,
"restored": {
"contentSha256": "cb93c2855ce67ed800416d985edfe22d80035a3313015573d78252bc17619db9",
"duration": 0.447213595,
"length": 5,
"waypointCount": 2,
"waypoints": [
{
"acceleration": 100,
"base": 0,
"continuous": false,
"name": "Pt",
"position": [
1,
2,
3
],
"tool": 0,
"type": "LIN",
"velocity": 2000
},
{
"acceleration": 100,
"base": 0,
"continuous": false,
"name": "Pt1",
"position": [
4,
6,
3
],
"tool": 0,
"type": "LIN",
"velocity": 2000
}
]
}
},
"status": "pass",
"touchedAfterEdit": {
"mustExecute": false,
"objectState": [
"Touched"
],
"value": {
"numeric": 500,
"raw": "500.0 mm/s^2",
"unit": "Unit: mm/s^2 (1,0,-2,0,0,0,0,0) [Acceleration]"
}
}
}

View File

@@ -0,0 +1,66 @@
{
"schemaVersion": 1,
"status": "pass",
"taskId": "PROP-app-propertyacceleration-I",
"baseline": {
"freecadVersion": "1.1.1",
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
},
"propertyType": "App::PropertyAcceleration",
"recordCount": 1,
"phaseEvidence": {
"A": [
"config/freecad-property-acceleration-inventory.json",
"check:freecad-property-acceleration-inventory"
],
"B": [
"config/freecad-property-acceleration-success.json",
"check:freecad-property-acceleration-success"
],
"C": [
"config/freecad-property-acceleration-failure.json",
"check:freecad-property-acceleration-failure"
],
"D": [
"config/freecad-property-acceleration-mutation.json",
"check:freecad-property-acceleration-mutation"
],
"E": [
"src/facade/types.ts",
"src/facade/fcstd.ts",
"src/facade/mockFacade.ts",
"test:freecad-property-acceleration-facade"
],
"F": [
"tests/propertyAccelerationTransaction.test.ts",
"test:freecad-property-acceleration-transaction"
],
"G": [
"config/freecad-property-acceleration-roundtrip.json",
"check:freecad-property-acceleration-roundtrip"
],
"H": [
"config/chrome-property-acceleration-verification.json",
"check:chrome-property-acceleration"
]
},
"promotion": {
"from": "opaque-fcstd-proxy",
"to": "native-editable-codec",
"facadeValueModel": "finite-number-mm/s^2",
"fcstdElement": "Float",
"nativeRoundTripValue": 500,
"browserRoundTripValue": 500,
"zeroUnknownDrift": true
},
"exactBlockerSync": {
"nativeEditableTypes": 30,
"nativeEditableRecords": 4361,
"opaqueTypes": 50,
"opaqueRecords": 466,
"exactPromotionReady": false,
"exactBlocker": "50 runtime property types and 466 records remain opaque-only; complete native document and property semantics"
},
"systemExact": false,
"generatedAt": "2026-08-17T08:49:33.800Z"
}

View File

@@ -0,0 +1,331 @@
{
"schemaVersion": 1,
"status": "pass",
"baselineId": "freecad-1.1.1-property-acceleration-roundtrip",
"freecadVersion": "1.1.1",
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
"archives": {
"nativeInitial": {
"path": ".cache/freecad/property-acceleration-roundtrip/native-initial.FCStd",
"bytes": 1625,
"sha256": "121b9ef55520cbea76f85d4a462791f22593743680c7c8813c84a06ed092695e"
},
"webEdited": {
"path": ".cache/freecad/property-acceleration-roundtrip/web-edited.FCStd",
"bytes": 1455,
"sha256": "6c9f69279012adfaba3e3093448d343a5829a5c34df7fc3f2f3799a625fb8a70"
},
"nativeResaved": {
"path": ".cache/freecad/property-acceleration-roundtrip/native-resaved.FCStd",
"bytes": 1629,
"sha256": "0a6d34aba0c69b6dd52424f3d1c35bc096b8ca6087e96903b9ada9a1b257cbd9"
}
},
"nativeInitial": {
"object": {
"editorMode": [],
"name": "AccelerationProbe",
"propertyStatus": [],
"propertyTypeId": "App::PropertyAcceleration",
"source": {
"name": "SourceTrajectory",
"typeId": "Robot::TrajectoryObject"
},
"state": [
"Up-to-date"
],
"statusString": "Valid",
"trajectory": {
"contentSha256": "1a29d89dac9b062e0ea210375b9aeb1f7ada2ed763939e339eb31c05d4ee678f",
"duration": 0.141421356,
"length": 5,
"waypointCount": 2,
"waypoints": [
{
"acceleration": 1000,
"name": "Pt",
"position": [
1,
2,
3
],
"type": "LIN",
"velocity": 2000
},
{
"acceleration": 1000,
"name": "Pt1",
"position": [
4,
6,
3
],
"type": "LIN",
"velocity": 2000
}
]
},
"typeId": "Robot::TrajectoryDressUpObject",
"useAcceleration": true,
"value": {
"numeric": 1000,
"raw": "1000.0 mm/s^2",
"unit": "Unit: mm/s^2 (1,0,-2,0,0,0,0,0) [Acceleration]"
}
},
"objectSet": [
{
"name": "SourceTrajectory",
"typeId": "Robot::TrajectoryObject"
},
{
"name": "AccelerationProbe",
"typeId": "Robot::TrajectoryDressUpObject"
}
],
"sourceTrajectory": {
"contentSha256": "cb93c2855ce67ed800416d985edfe22d80035a3313015573d78252bc17619db9",
"duration": 0.447213595,
"length": 5,
"waypointCount": 2,
"waypoints": [
{
"acceleration": 100,
"name": "Pt",
"position": [
1,
2,
3
],
"type": "LIN",
"velocity": 2000
},
{
"acceleration": 100,
"name": "Pt1",
"position": [
4,
6,
3
],
"type": "LIN",
"velocity": 2000
}
]
}
},
"web": {
"before": {
"name": "Acceleration",
"typeId": "App::PropertyAcceleration",
"element": "Float",
"value": "1000.0000000000000000"
},
"after": {
"name": "Acceleration",
"typeId": "App::PropertyAcceleration",
"element": "Float",
"value": "500"
},
"objectSetPreserved": true,
"semanticObjectsPreserved": true,
"opaquePathsPreserved": 0,
"opaqueEntriesPreserved": true
},
"nativeAfter": {
"reopened": {
"object": {
"editorMode": [],
"name": "AccelerationProbe",
"propertyStatus": [],
"propertyTypeId": "App::PropertyAcceleration",
"source": {
"name": "SourceTrajectory",
"typeId": "Robot::TrajectoryObject"
},
"state": [
"Up-to-date"
],
"statusString": "Valid",
"trajectory": {
"contentSha256": "a7febf338d0c6527d9ad31e709f379092fd6f0144714ee29f973cd77567ecf2c",
"duration": 0.2,
"length": 5,
"waypointCount": 2,
"waypoints": [
{
"acceleration": 500,
"name": "Pt",
"position": [
1,
2,
3
],
"type": "LIN",
"velocity": 2000
},
{
"acceleration": 500,
"name": "Pt1",
"position": [
4,
6,
3
],
"type": "LIN",
"velocity": 2000
}
]
},
"typeId": "Robot::TrajectoryDressUpObject",
"useAcceleration": true,
"value": {
"numeric": 500,
"raw": "500.0 mm/s^2",
"unit": "Unit: mm/s^2 (1,0,-2,0,0,0,0,0) [Acceleration]"
}
},
"objectSet": [
{
"name": "SourceTrajectory",
"typeId": "Robot::TrajectoryObject"
},
{
"name": "AccelerationProbe",
"typeId": "Robot::TrajectoryDressUpObject"
}
],
"sourceTrajectory": {
"contentSha256": "cb93c2855ce67ed800416d985edfe22d80035a3313015573d78252bc17619db9",
"duration": 0.447213595,
"length": 5,
"waypointCount": 2,
"waypoints": [
{
"acceleration": 100,
"name": "Pt",
"position": [
1,
2,
3
],
"type": "LIN",
"velocity": 2000
},
{
"acceleration": 100,
"name": "Pt1",
"position": [
4,
6,
3
],
"type": "LIN",
"velocity": 2000
}
]
}
},
"resaved": {
"object": {
"editorMode": [],
"name": "AccelerationProbe",
"propertyStatus": [],
"propertyTypeId": "App::PropertyAcceleration",
"source": {
"name": "SourceTrajectory",
"typeId": "Robot::TrajectoryObject"
},
"state": [
"Up-to-date"
],
"statusString": "Valid",
"trajectory": {
"contentSha256": "a7febf338d0c6527d9ad31e709f379092fd6f0144714ee29f973cd77567ecf2c",
"duration": 0.2,
"length": 5,
"waypointCount": 2,
"waypoints": [
{
"acceleration": 500,
"name": "Pt",
"position": [
1,
2,
3
],
"type": "LIN",
"velocity": 2000
},
{
"acceleration": 500,
"name": "Pt1",
"position": [
4,
6,
3
],
"type": "LIN",
"velocity": 2000
}
]
},
"typeId": "Robot::TrajectoryDressUpObject",
"useAcceleration": true,
"value": {
"numeric": 500,
"raw": "500.0 mm/s^2",
"unit": "Unit: mm/s^2 (1,0,-2,0,0,0,0,0) [Acceleration]"
}
},
"objectSet": [
{
"name": "SourceTrajectory",
"typeId": "Robot::TrajectoryObject"
},
{
"name": "AccelerationProbe",
"typeId": "Robot::TrajectoryDressUpObject"
}
],
"sourceTrajectory": {
"contentSha256": "cb93c2855ce67ed800416d985edfe22d80035a3313015573d78252bc17619db9",
"duration": 0.447213595,
"length": 5,
"waypointCount": 2,
"waypoints": [
{
"acceleration": 100,
"name": "Pt",
"position": [
1,
2,
3
],
"type": "LIN",
"velocity": 2000
},
{
"acceleration": 100,
"name": "Pt1",
"position": [
4,
6,
3
],
"type": "LIN",
"velocity": 2000
}
]
}
}
},
"classification": {
"webValue": "500",
"reopenedValue": 500,
"resavedValue": 500,
"nativeOutputMatches": true,
"unknownSemanticDrift": false,
"zeroUnknownDrift": true
}
}

View File

@@ -0,0 +1,101 @@
{
"baselineId": "freecad-1.1.1-property-acceleration-success",
"cases": [
{
"editorMode": [],
"group": "TrajectoryDressUp",
"id": "default",
"objectState": [
"Up-to-date"
],
"requested": null,
"shape": {
"applicable": false
},
"status": [],
"typeId": "App::PropertyAcceleration",
"value": {
"numeric": 1000,
"raw": "1000.0 mm/s^2",
"unit": "Unit: mm/s^2 (1,0,-2,0,0,0,0,0) [Acceleration]"
}
},
{
"editorMode": [],
"group": "TrajectoryDressUp",
"id": "nominal",
"objectState": [
"Touched",
"Invalid"
],
"requested": "500 mm/s^2",
"shape": {
"applicable": false
},
"status": [],
"typeId": "App::PropertyAcceleration",
"value": {
"numeric": 500,
"raw": "500.0 mm/s^2",
"unit": "Unit: mm/s^2 (1,0,-2,0,0,0,0,0) [Acceleration]"
}
},
{
"editorMode": [],
"group": "TrajectoryDressUp",
"id": "lower-bound",
"objectState": [
"Touched",
"Invalid"
],
"requested": "0 mm/s^2",
"shape": {
"applicable": false
},
"status": [],
"typeId": "App::PropertyAcceleration",
"value": {
"numeric": 0,
"raw": "0.0 mm/s^2",
"unit": "Unit: mm/s^2 (1,0,-2,0,0,0,0,0) [Acceleration]"
}
},
{
"editorMode": [],
"group": "TrajectoryDressUp",
"id": "negative-boundary",
"objectState": [
"Touched",
"Invalid"
],
"requested": "-500 mm/s^2",
"shape": {
"applicable": false
},
"status": [],
"typeId": "App::PropertyAcceleration",
"value": {
"numeric": -500,
"raw": "-500.0 mm/s^2",
"unit": "Unit: mm/s^2 (1,0,-2,0,0,0,0,0) [Acceleration]"
}
}
],
"diagnostics": {
"documentObjectCount": 1,
"exception": null
},
"freecadVersion": "1.1.1",
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
"object": {
"name": "AccelerationProbe",
"typeId": "Robot::TrajectoryDressUpObject"
},
"property": {
"group": "TrajectoryDressUp",
"name": "Acceleration",
"typeId": "App::PropertyAcceleration"
},
"schemaVersion": 1,
"status": "pass"
}

View File

@@ -0,0 +1,544 @@
{
"baselineId": "freecad-1.1.1-property-area-failure",
"cancellationBoundary": {
"classification": "synchronous-measure-recompute",
"reason": "no-native-cancel-hook",
"replacement": "abort-active-document-transaction",
"supported": false
},
"disabled": {
"before": {
"elements": [
{
"object": "AreaBox",
"subElements": [
"Face1"
]
}
],
"numeric": 10,
"raw": "10.0 mm^2",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
},
"classification": "editor-readonly-python-mutable-until-immutable",
"editorMode": [
"ReadOnly"
],
"editorReadOnlyAfter": {
"elements": [
{
"object": "AreaBox",
"subElements": [
"Face1"
]
}
],
"numeric": 20,
"raw": "20.0 mm^2",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
},
"editorReadOnlyException": null,
"editorReadOnlyRequested": "20 mm^2",
"immutableAfter": {
"elements": [
{
"object": "AreaBox",
"subElements": [
"Face1"
]
}
],
"numeric": 20,
"raw": "20.0 mm^2",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
},
"immutableException": {
"message": "Object attribute 'Area' is read-only",
"type": "AttributeError"
},
"immutableRequested": "30 mm^2",
"immutableStatus": [
"Immutable",
"24",
"27"
],
"immutableValuePreserved": true,
"objectsPreserved": true,
"propertyStatus": [
"24",
"27"
],
"pythonBypassesEditorReadOnly": true,
"restored": {
"elements": [
{
"object": "AreaBox",
"subElements": [
"Face1"
]
}
],
"numeric": 10,
"raw": "10.0 mm^2",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
},
"restoredEditorMode": [
"ReadOnly"
],
"restoredStatus": [
"24",
"27"
],
"valueRestored": true
},
"documentIntegrity": {
"finalObjects": [
{
"name": "AreaBox",
"typeId": "Part::Box"
},
{
"name": "AreaCylinder",
"typeId": "Part::Cylinder"
},
{
"name": "AreaPoint",
"typeId": "Part::Feature"
},
{
"name": "AreaLine",
"typeId": "Part::Feature"
},
{
"name": "AreaProbe",
"typeId": "Measure::MeasureArea"
}
],
"initialObjects": [
{
"name": "AreaBox",
"typeId": "Part::Box"
},
{
"name": "AreaCylinder",
"typeId": "Part::Cylinder"
},
{
"name": "AreaPoint",
"typeId": "Part::Feature"
},
{
"name": "AreaLine",
"typeId": "Part::Feature"
},
{
"name": "AreaProbe",
"typeId": "Measure::MeasureArea"
}
],
"objectCount": 5,
"objectsPreserved": true
},
"failures": [
{
"after": {
"elements": [
{
"object": "AreaPoint",
"subElements": [
"Vertex1"
]
}
],
"numeric": 10,
"raw": "10.0 mm^2",
"state": [
"Touched",
"Invalid"
],
"statusString": "Cannot calculate area",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
},
"afterObjects": [
{
"name": "AreaBox",
"typeId": "Part::Box"
},
{
"name": "AreaCylinder",
"typeId": "Part::Cylinder"
},
{
"name": "AreaPoint",
"typeId": "Part::Feature"
},
{
"name": "AreaLine",
"typeId": "Part::Feature"
},
{
"name": "AreaProbe",
"typeId": "Measure::MeasureArea"
}
],
"assignmentException": null,
"before": {
"elements": [
{
"object": "AreaBox",
"subElements": [
"Face1"
]
}
],
"numeric": 10,
"raw": "10.0 mm^2",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
},
"beforeObjects": [
{
"name": "AreaBox",
"typeId": "Part::Box"
},
{
"name": "AreaCylinder",
"typeId": "Part::Cylinder"
},
{
"name": "AreaPoint",
"typeId": "Part::Feature"
},
{
"name": "AreaLine",
"typeId": "Part::Feature"
},
{
"name": "AreaProbe",
"typeId": "Measure::MeasureArea"
}
],
"expectedDiagnostic": "Cannot calculate area",
"id": "unsupported-point",
"objectsPreserved": true,
"recomputeException": null,
"recomputeResult": true,
"recovered": {
"elements": [
{
"object": "AreaBox",
"subElements": [
"Face1"
]
}
],
"numeric": 10,
"raw": "10.0 mm^2",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
},
"recoveredExactly": true,
"source": {
"name": "AreaPoint",
"shapeType": "Vertex",
"subElement": "Vertex1",
"typeId": "Part::Feature"
},
"valuePreserved": true
},
{
"after": {
"elements": [
{
"object": "AreaLine",
"subElements": [
"Edge1"
]
}
],
"numeric": 10,
"raw": "10.0 mm^2",
"state": [
"Touched",
"Invalid"
],
"statusString": "Cannot calculate area",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
},
"afterObjects": [
{
"name": "AreaBox",
"typeId": "Part::Box"
},
{
"name": "AreaCylinder",
"typeId": "Part::Cylinder"
},
{
"name": "AreaPoint",
"typeId": "Part::Feature"
},
{
"name": "AreaLine",
"typeId": "Part::Feature"
},
{
"name": "AreaProbe",
"typeId": "Measure::MeasureArea"
}
],
"assignmentException": null,
"before": {
"elements": [
{
"object": "AreaBox",
"subElements": [
"Face1"
]
}
],
"numeric": 10,
"raw": "10.0 mm^2",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
},
"beforeObjects": [
{
"name": "AreaBox",
"typeId": "Part::Box"
},
{
"name": "AreaCylinder",
"typeId": "Part::Cylinder"
},
{
"name": "AreaPoint",
"typeId": "Part::Feature"
},
{
"name": "AreaLine",
"typeId": "Part::Feature"
},
{
"name": "AreaProbe",
"typeId": "Measure::MeasureArea"
}
],
"expectedDiagnostic": "Cannot calculate area",
"id": "unsupported-line",
"objectsPreserved": true,
"recomputeException": null,
"recomputeResult": true,
"recovered": {
"elements": [
{
"object": "AreaBox",
"subElements": [
"Face1"
]
}
],
"numeric": 10,
"raw": "10.0 mm^2",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
},
"recoveredExactly": true,
"source": {
"name": "AreaLine",
"shapeType": "Edge",
"subElement": "Edge1",
"typeId": "Part::Feature"
},
"valuePreserved": true
}
],
"freecadVersion": "1.1.1",
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
"initial": {
"elements": [
{
"object": "AreaBox",
"subElements": [
"Face1"
]
}
],
"numeric": 10,
"raw": "10.0 mm^2",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
},
"input": {
"name": "Elements",
"typeId": "App::PropertyLinkSubList"
},
"object": {
"name": "AreaProbe",
"typeId": "Measure::MeasureArea"
},
"property": {
"name": "Area",
"typeId": "App::PropertyArea"
},
"schemaVersion": 1,
"status": "pass",
"transaction": {
"activeAfterAbort": {
"id": 0,
"name": ""
},
"activeAfterEdit": {
"id": 1,
"name": "property-area-cancel"
},
"afterAbort": {
"elements": [
{
"object": "AreaBox",
"subElements": [
"Face1"
]
}
],
"numeric": 10,
"raw": "10.0 mm^2",
"state": [
"Touched"
],
"statusString": "Touched",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
},
"afterRecompute": {
"elements": [
{
"object": "AreaBox",
"subElements": [
"Face1"
]
}
],
"numeric": 10,
"raw": "10.0 mm^2",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
},
"before": {
"elements": [
{
"object": "AreaBox",
"subElements": [
"Face1"
]
}
],
"numeric": 10,
"raw": "10.0 mm^2",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
},
"edited": {
"elements": [
{
"object": "AreaCylinder",
"subElements": [
"Face1"
]
}
],
"numeric": 75.398223877,
"raw": "75.39822387695312 mm^2",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
},
"objectsAfter": [
{
"name": "AreaBox",
"typeId": "Part::Box"
},
{
"name": "AreaCylinder",
"typeId": "Part::Cylinder"
},
{
"name": "AreaPoint",
"typeId": "Part::Feature"
},
{
"name": "AreaLine",
"typeId": "Part::Feature"
},
{
"name": "AreaProbe",
"typeId": "Measure::MeasureArea"
}
],
"objectsBefore": [
{
"name": "AreaBox",
"typeId": "Part::Box"
},
{
"name": "AreaCylinder",
"typeId": "Part::Cylinder"
},
{
"name": "AreaPoint",
"typeId": "Part::Feature"
},
{
"name": "AreaLine",
"typeId": "Part::Feature"
},
{
"name": "AreaProbe",
"typeId": "Measure::MeasureArea"
}
],
"objectsRestored": true,
"pendingAfterAbort": false,
"pendingAfterEdit": true,
"restored": true,
"undoMode": 1
}
}

View File

@@ -0,0 +1,108 @@
{
"schemaVersion": 1,
"status": "pass",
"baseline": {
"freecadVersion": "1.1.1",
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
},
"propertyType": "App::PropertyArea",
"recordCount": 1,
"records": [
{
"objectTypeId": "Measure::MeasureArea",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "Area",
"group": "Measurement",
"status": [
24,
27
],
"normalizedStatus": [
"PropReadOnly",
"PropOutput"
],
"defaultRaw": "0.0 mm^2",
"valueModel": {
"kind": "quantity",
"dimension": "length^2",
"defaultValue": 0,
"defaultUnit": "mm^2",
"derived": true,
"writable": false
},
"inputs": [
{
"propertyName": "Elements",
"typeId": "App::PropertyLinkSubList",
"group": "Measurement",
"defaultValue": [],
"scope": "Global",
"allowExternal": true,
"cardinality": "one-or-more"
}
],
"dependencies": [
{
"sourceProperty": "Elements",
"targetProperty": "Area",
"relation": "link-sub-list",
"effect": "immediate-recompute-on-change"
}
],
"applicability": {
"selectionMustBeNonEmpty": true,
"everyElementMustBeValid": true,
"supportedMeasureElementTypes": [
"PLANE",
"CYLINDER",
"SURFACE",
"VOLUME"
],
"unsupportedMeasureElementTypes": [
"INVALID",
"POINT",
"LINE",
"CURVE"
],
"externalDocumentElementsAllowed": true
},
"execution": {
"aggregation": "sum-area",
"resultProperty": "Area",
"invalidGeometryDiagnostic": "Cannot calculate area",
"shape": "not-applicable-derived-measurement"
}
}
],
"provenance": {
"runtime": {
"path": ".cache/freecad/reference-desktop.json",
"bytes": 2298709,
"sha256": "082400ec7379e8efc2af16709032d45890d7092277967b714acb05761fd1c2a7"
},
"sources": [
{
"path": ".cache/freecad/FreeCAD/src/Mod/Measure/App/MeasureArea.cpp",
"bytes": 5328,
"sha256": "86506348c36a9a440881da0b605a74c38079c3c606ca6f7660df53665eda5281"
},
{
"path": ".cache/freecad/FreeCAD/src/Mod/Measure/App/MeasureArea.h",
"bytes": 3125,
"sha256": "5bae7a21e82e73490a8b63cc234f1bd17e019df0d7cfcf7aa23fe91d2dc13305"
}
]
},
"classification": "opaque-fcstd-proxy",
"nextPhases": [
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I"
]
}

View File

@@ -0,0 +1,342 @@
{
"baselineId": "freecad-1.1.1-property-area-mutation",
"before": {
"editorMode": [
"ReadOnly"
],
"elements": [
{
"object": "AreaBox",
"subElements": [
"Face1"
],
"typeId": "Part::Box"
}
],
"mustExecute": false,
"objectState": [
"Up-to-date"
],
"propertyStatus": [
"24",
"27"
],
"shape": {
"applicable": false
},
"statusString": "Valid",
"value": {
"numeric": 10,
"raw": "10.0 mm^2",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
}
},
"classification": {
"derivedValueChanged": true,
"derivedValueRestored": true,
"geometry": "source-shapes-preserved-derived-measurement-has-no-shape",
"inputChanged": true,
"inputRestored": true,
"semanticStateRestored": true,
"sourceGeometryPreserved": true
},
"document": {
"objectsBefore": [
{
"name": "AreaBox",
"typeId": "Part::Box"
},
{
"name": "AreaCylinder",
"typeId": "Part::Cylinder"
},
{
"name": "AreaProbe",
"typeId": "Measure::MeasureArea"
}
],
"objectsPreserved": true,
"objectsRestored": [
{
"name": "AreaBox",
"typeId": "Part::Box"
},
{
"name": "AreaCylinder",
"typeId": "Part::Cylinder"
},
{
"name": "AreaProbe",
"typeId": "Measure::MeasureArea"
}
]
},
"edited": {
"editorMode": [
"ReadOnly"
],
"elements": [
{
"object": "AreaBox",
"subElements": [
"Face1",
"Face2"
],
"typeId": "Part::Box"
},
{
"object": "AreaCylinder",
"subElements": [
"Face1"
],
"typeId": "Part::Cylinder"
}
],
"mustExecute": false,
"objectState": [
"Up-to-date"
],
"propertyStatus": [
"24",
"27"
],
"shape": {
"applicable": false
},
"statusString": "Valid",
"value": {
"numeric": 95.398223877,
"raw": "95.39822387695312 mm^2",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
}
},
"freecadVersion": "1.1.1",
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
"input": {
"name": "Elements",
"typeId": "App::PropertyLinkSubList"
},
"object": {
"name": "AreaProbe",
"typeId": "Measure::MeasureArea"
},
"property": {
"name": "Area",
"typeId": "App::PropertyArea"
},
"recompute": {
"edit": 1,
"initial": 3,
"restore": 1
},
"restored": {
"editorMode": [
"ReadOnly"
],
"elements": [
{
"object": "AreaBox",
"subElements": [
"Face1"
],
"typeId": "Part::Box"
}
],
"mustExecute": false,
"objectState": [
"Up-to-date"
],
"propertyStatus": [
"24",
"27"
],
"shape": {
"applicable": false
},
"statusString": "Valid",
"value": {
"numeric": 10,
"raw": "10.0 mm^2",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
}
},
"schemaVersion": 1,
"sources": {
"before": [
{
"area": 160,
"bounds": [
0,
0,
0,
10,
5,
2
],
"edges": 12,
"faces": 6,
"name": "AreaBox",
"shapeType": "Solid",
"solids": 1,
"typeId": "Part::Box",
"valid": true,
"vertices": 8,
"volume": 100
},
{
"area": 131.946891451,
"bounds": [
-3,
-3,
0,
3,
3,
4
],
"edges": 3,
"faces": 3,
"name": "AreaCylinder",
"shapeType": "Solid",
"solids": 1,
"typeId": "Part::Cylinder",
"valid": true,
"vertices": 2,
"volume": 113.097335529
}
],
"edited": [
{
"area": 160,
"bounds": [
0,
0,
0,
10,
5,
2
],
"edges": 12,
"faces": 6,
"name": "AreaBox",
"shapeType": "Solid",
"solids": 1,
"typeId": "Part::Box",
"valid": true,
"vertices": 8,
"volume": 100
},
{
"area": 131.946891451,
"bounds": [
-3,
-3,
0,
3,
3,
4
],
"edges": 3,
"faces": 3,
"name": "AreaCylinder",
"shapeType": "Solid",
"solids": 1,
"typeId": "Part::Cylinder",
"valid": true,
"vertices": 2,
"volume": 113.097335529
}
],
"preserved": true,
"restored": [
{
"area": 160,
"bounds": [
0,
0,
0,
10,
5,
2
],
"edges": 12,
"faces": 6,
"name": "AreaBox",
"shapeType": "Solid",
"solids": 1,
"typeId": "Part::Box",
"valid": true,
"vertices": 8,
"volume": 100
},
{
"area": 131.946891451,
"bounds": [
-3,
-3,
0,
3,
3,
4
],
"edges": 3,
"faces": 3,
"name": "AreaCylinder",
"shapeType": "Solid",
"solids": 1,
"typeId": "Part::Cylinder",
"valid": true,
"vertices": 2,
"volume": 113.097335529
}
]
},
"status": "pass",
"touchedAfterEdit": {
"elements": [
{
"object": "AreaBox",
"subElements": [
"Face1",
"Face2"
],
"typeId": "Part::Box"
},
{
"object": "AreaCylinder",
"subElements": [
"Face1"
],
"typeId": "Part::Cylinder"
}
],
"mustExecute": false,
"objectState": [
"Touched"
],
"value": {
"numeric": 95.398223877,
"raw": "95.39822387695312 mm^2",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
}
},
"touchedAfterRestore": {
"elements": [
{
"object": "AreaBox",
"subElements": [
"Face1"
],
"typeId": "Part::Box"
}
],
"mustExecute": false,
"objectState": [
"Touched"
],
"value": {
"numeric": 10,
"raw": "10.0 mm^2",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
}
}
}

View File

@@ -0,0 +1,71 @@
{
"schemaVersion": 1,
"status": "pass",
"taskId": "PROP-app-propertyarea-I",
"baseline": {
"freecadVersion": "1.1.1",
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
},
"propertyType": "App::PropertyArea",
"recordCount": 1,
"phaseEvidence": {
"A": [
"config/freecad-property-area-inventory.json",
"check:freecad-property-area-inventory"
],
"B": [
"config/freecad-property-area-success.json",
"check:freecad-property-area-success"
],
"C": [
"config/freecad-property-area-failure.json",
"check:freecad-property-area-failure"
],
"D": [
"config/freecad-property-area-mutation.json",
"check:freecad-property-area-mutation"
],
"E": [
"src/facade/types.ts",
"src/facade/fcstd.ts",
"src/facade/mockFacade.ts",
"tests/propertyAreaFacade.test.ts",
"test:freecad-property-area-facade"
],
"F": [
"tests/propertyAreaTransaction.test.ts",
"test:freecad-property-area-transaction"
],
"G": [
"config/freecad-property-area-roundtrip.json",
"check:freecad-property-area-roundtrip"
],
"H": [
"config/chrome-property-area-verification.json",
"check:chrome-property-area"
]
},
"promotion": {
"from": "opaque-fcstd-proxy",
"to": "native-editable-codec",
"facadeValueModel": "read-only-derived-mm^2-with-link-sub-list-input",
"inputType": "App::PropertyLinkSubList",
"fcstdAreaElement": "Float",
"fcstdElementsElement": "LinkSubList",
"nativeRoundTripArea": 20,
"browserRoundTripArea": 0,
"browserRoundTripElementCount": 0,
"sourceGeometryPreserved": true,
"zeroUnknownDrift": true
},
"exactBlockerSync": {
"nativeEditableTypes": 30,
"nativeEditableRecords": 4361,
"opaqueTypes": 50,
"opaqueRecords": 466,
"exactPromotionReady": false,
"exactBlocker": "50 runtime property types and 466 records remain opaque-only; complete native document and property semantics"
},
"systemExact": false,
"generatedAt": "2026-08-17T08:49:33.776Z"
}

View File

@@ -0,0 +1,305 @@
{
"schemaVersion": 1,
"status": "pass",
"baselineId": "freecad-1.1.1-property-area-roundtrip",
"freecadVersion": "1.1.1",
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
"archives": {
"nativeInitial": {
"path": ".cache/freecad/property-area-roundtrip/native-initial.FCStd",
"bytes": 2635,
"sha256": "2c50a95d69ab8069be75a92dbd35531cb6089ce2bb2fe420cff1e8e4ca523bd4"
},
"webEdited": {
"path": ".cache/freecad/property-area-roundtrip/web-edited.FCStd",
"bytes": 2523,
"sha256": "3b37fb932987756ea69c4f6ee784056ade0625f7c6504c11fb59bca55b95b595"
},
"nativeResaved": {
"path": ".cache/freecad/property-area-roundtrip/native-resaved.FCStd",
"bytes": 2650,
"sha256": "09b15d8d030c15dddc20f9a89b8a1244ecd2e279eb973ab2b572e382dcc062d0"
}
},
"nativeInitial": {
"measure": {
"area": {
"numeric": 10,
"raw": "10.0 mm^2",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
},
"areaTypeId": "App::PropertyArea",
"editorMode": [
"ReadOnly"
],
"elements": [
{
"object": "AreaBox",
"subElements": [
"Face1"
],
"typeId": "Part::Box"
}
],
"elementsTypeId": "App::PropertyLinkSubList",
"name": "AreaProbe",
"propertyStatus": [
"24",
"27"
],
"shape": {
"applicable": false
},
"state": [
"Up-to-date"
],
"statusString": "Valid",
"typeId": "Measure::MeasureArea"
},
"objectSet": [
{
"name": "AreaBox",
"typeId": "Part::Box"
},
{
"name": "AreaProbe",
"typeId": "Measure::MeasureArea"
}
],
"source": {
"area": 160,
"bounds": [
0,
0,
0,
10,
5,
2
],
"edges": 12,
"faces": 6,
"height": 2,
"length": 10,
"name": "AreaBox",
"shapeType": "Solid",
"solids": 1,
"typeId": "Part::Box",
"valid": true,
"vertices": 8,
"volume": 100,
"width": 5
}
},
"web": {
"before": {
"area": {
"name": "Area",
"typeId": "App::PropertyArea",
"element": "Float",
"value": "10.0000000000000000",
"nativeStatus": 150994944,
"statusNames": [
"PropReadOnly",
"PropOutput"
]
},
"elements": {
"name": "Elements",
"typeId": "App::PropertyLinkSubList",
"element": "LinkSubList",
"value": "{\"schemaVersion\":1,\"entries\":[{\"objectId\":\"AreaBox\",\"subElement\":\"Face1\"}]}",
"linkSubs": [
{
"objectId": "AreaBox",
"subElement": "Face1"
}
]
}
},
"after": {
"area": {
"name": "Area",
"typeId": "App::PropertyArea",
"element": "Float",
"value": "20",
"nativeStatus": 150994944,
"statusNames": [
"PropReadOnly",
"PropOutput"
]
},
"elements": {
"name": "Elements",
"typeId": "App::PropertyLinkSubList",
"element": "LinkSubList",
"value": "{\"schemaVersion\":1,\"entries\":[{\"objectId\":\"AreaBox\",\"subElement\":\"Face1\"},{\"objectId\":\"AreaBox\",\"subElement\":\"Face2\"}]}",
"linkSubs": [
{
"objectId": "AreaBox",
"subElement": "Face1"
},
{
"objectId": "AreaBox",
"subElement": "Face2"
}
]
}
},
"objectSetPreserved": true,
"semanticObjectsPreserved": true,
"opaquePathsPreserved": 1,
"opaqueEntriesPreserved": true
},
"nativeAfter": {
"reopened": {
"measure": {
"area": {
"numeric": 20,
"raw": "20.0 mm^2",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
},
"areaTypeId": "App::PropertyArea",
"editorMode": [
"ReadOnly"
],
"elements": [
{
"object": "AreaBox",
"subElements": [
"Face1",
"Face2"
],
"typeId": "Part::Box"
}
],
"elementsTypeId": "App::PropertyLinkSubList",
"name": "AreaProbe",
"propertyStatus": [
"24",
"27"
],
"shape": {
"applicable": false
},
"state": [
"Up-to-date"
],
"statusString": "Valid",
"typeId": "Measure::MeasureArea"
},
"objectSet": [
{
"name": "AreaBox",
"typeId": "Part::Box"
},
{
"name": "AreaProbe",
"typeId": "Measure::MeasureArea"
}
],
"source": {
"area": 160,
"bounds": [
0,
0,
0,
10,
5,
2
],
"edges": 12,
"faces": 6,
"height": 2,
"length": 10,
"name": "AreaBox",
"shapeType": "Solid",
"solids": 1,
"typeId": "Part::Box",
"valid": true,
"vertices": 8,
"volume": 100,
"width": 5
}
},
"resaved": {
"measure": {
"area": {
"numeric": 20,
"raw": "20.0 mm^2",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
},
"areaTypeId": "App::PropertyArea",
"editorMode": [
"ReadOnly"
],
"elements": [
{
"object": "AreaBox",
"subElements": [
"Face1",
"Face2"
],
"typeId": "Part::Box"
}
],
"elementsTypeId": "App::PropertyLinkSubList",
"name": "AreaProbe",
"propertyStatus": [
"24",
"27"
],
"shape": {
"applicable": false
},
"state": [
"Up-to-date"
],
"statusString": "Valid",
"typeId": "Measure::MeasureArea"
},
"objectSet": [
{
"name": "AreaBox",
"typeId": "Part::Box"
},
{
"name": "AreaProbe",
"typeId": "Measure::MeasureArea"
}
],
"source": {
"area": 160,
"bounds": [
0,
0,
0,
10,
5,
2
],
"edges": 12,
"faces": 6,
"height": 2,
"length": 10,
"name": "AreaBox",
"shapeType": "Solid",
"solids": 1,
"typeId": "Part::Box",
"valid": true,
"vertices": 8,
"volume": 100,
"width": 5
}
}
},
"classification": {
"webArea": 20,
"webElementCount": 2,
"reopenedArea": 20,
"resavedArea": 20,
"nativeOutputMatches": true,
"sourceGeometryPreserved": true,
"unknownSemanticDrift": false,
"zeroUnknownDrift": true
}
}

View File

@@ -0,0 +1,315 @@
{
"baselineId": "freecad-1.1.1-property-area-success",
"cases": [
{
"areaTypeId": "App::PropertyArea",
"editorMode": [
"ReadOnly"
],
"elements": [],
"elementsTypeId": "App::PropertyLinkSubList",
"expectedArea": 0,
"id": "empty-default",
"object": {
"name": "AreaProbe",
"state": [
"Up-to-date"
],
"status": "Valid",
"typeId": "Measure::MeasureArea"
},
"propertyStatus": [
"24",
"27"
],
"shape": {
"applicable": false
},
"value": {
"numeric": 0,
"raw": "0.0 mm^2",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
}
},
{
"areaTypeId": "App::PropertyArea",
"editorMode": [
"ReadOnly"
],
"elements": [
{
"area": 10,
"edges": 4,
"faces": 1,
"object": "AreaBox",
"shapeNull": false,
"shapeType": "Face",
"shapeValid": true,
"subElement": "Face1",
"vertices": 4
}
],
"elementsTypeId": "App::PropertyLinkSubList",
"expectedArea": 10,
"id": "planar-face",
"object": {
"name": "AreaProbe",
"state": [
"Up-to-date"
],
"status": "Valid",
"typeId": "Measure::MeasureArea"
},
"propertyStatus": [
"24",
"27"
],
"shape": {
"applicable": false
},
"value": {
"numeric": 10,
"raw": "10.0 mm^2",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
}
},
{
"areaTypeId": "App::PropertyArea",
"editorMode": [
"ReadOnly"
],
"elements": [
{
"area": 75.398223686,
"edges": 3,
"faces": 1,
"object": "AreaCylinder",
"shapeNull": false,
"shapeType": "Face",
"shapeValid": true,
"subElement": "Face1",
"vertices": 2
}
],
"elementsTypeId": "App::PropertyLinkSubList",
"expectedArea": 75.398223686,
"id": "cylindrical-face",
"object": {
"name": "AreaProbe",
"state": [
"Up-to-date"
],
"status": "Valid",
"typeId": "Measure::MeasureArea"
},
"propertyStatus": [
"24",
"27"
],
"shape": {
"applicable": false
},
"value": {
"numeric": 75.398223877,
"raw": "75.39822387695312 mm^2",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
}
},
{
"areaTypeId": "App::PropertyArea",
"editorMode": [
"ReadOnly"
],
"elements": [
{
"area": 50.265482457,
"edges": 3,
"faces": 1,
"object": "AreaSphere",
"shapeNull": false,
"shapeType": "Face",
"shapeValid": true,
"subElement": "Face1",
"vertices": 2
}
],
"elementsTypeId": "App::PropertyLinkSubList",
"expectedArea": 50.265482457,
"id": "surface-face",
"object": {
"name": "AreaProbe",
"state": [
"Up-to-date"
],
"status": "Valid",
"typeId": "Measure::MeasureArea"
},
"propertyStatus": [
"24",
"27"
],
"shape": {
"applicable": false
},
"value": {
"numeric": 50.265483856,
"raw": "50.26548385620117 mm^2",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
}
},
{
"areaTypeId": "App::PropertyArea",
"editorMode": [
"ReadOnly"
],
"elements": [
{
"area": 160,
"edges": 12,
"faces": 6,
"object": "AreaBox",
"shapeNull": false,
"shapeType": "Solid",
"shapeValid": true,
"subElement": "",
"vertices": 8
}
],
"elementsTypeId": "App::PropertyLinkSubList",
"expectedArea": 160,
"id": "solid-volume",
"object": {
"name": "AreaProbe",
"state": [
"Up-to-date"
],
"status": "Valid",
"typeId": "Measure::MeasureArea"
},
"propertyStatus": [
"24",
"27"
],
"shape": {
"applicable": false
},
"value": {
"numeric": 160,
"raw": "160.0 mm^2",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
}
},
{
"areaTypeId": "App::PropertyArea",
"editorMode": [
"ReadOnly"
],
"elements": [
{
"area": 10,
"edges": 4,
"faces": 1,
"object": "AreaBox",
"shapeNull": false,
"shapeType": "Face",
"shapeValid": true,
"subElement": "Face1",
"vertices": 4
},
{
"area": 10,
"edges": 4,
"faces": 1,
"object": "AreaBox",
"shapeNull": false,
"shapeType": "Face",
"shapeValid": true,
"subElement": "Face2",
"vertices": 4
},
{
"area": 75.398223686,
"edges": 3,
"faces": 1,
"object": "AreaCylinder",
"shapeNull": false,
"shapeType": "Face",
"shapeValid": true,
"subElement": "Face1",
"vertices": 2
}
],
"elementsTypeId": "App::PropertyLinkSubList",
"expectedArea": 95.398223686,
"id": "multi-element-sum",
"object": {
"name": "AreaProbe",
"state": [
"Up-to-date"
],
"status": "Valid",
"typeId": "Measure::MeasureArea"
},
"propertyStatus": [
"24",
"27"
],
"shape": {
"applicable": false
},
"value": {
"numeric": 95.398223877,
"raw": "95.39822387695312 mm^2",
"unit": "Unit: mm^2 (2,0,0,0,0,0,0,0) [Area]"
}
}
],
"diagnostics": {
"documentObjectCount": 4,
"exception": null
},
"freecadVersion": "1.1.1",
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
"input": {
"group": "Measurement",
"name": "Elements",
"typeId": "App::PropertyLinkSubList"
},
"object": {
"name": "AreaProbe",
"typeId": "Measure::MeasureArea"
},
"property": {
"group": "Measurement",
"name": "Area",
"typeId": "App::PropertyArea"
},
"schemaVersion": 1,
"sources": [
{
"name": "AreaBox",
"state": [
"Up-to-date"
],
"status": "Valid",
"typeId": "Part::Box"
},
{
"name": "AreaCylinder",
"state": [
"Up-to-date"
],
"status": "Valid",
"typeId": "Part::Cylinder"
},
{
"name": "AreaSphere",
"state": [
"Up-to-date"
],
"status": "Valid",
"typeId": "Part::Sphere"
}
],
"status": "pass"
}

View File

@@ -0,0 +1,729 @@
{
"baselineId": "freecad-1.1.1-property-boollist-failure",
"cancellationBoundary": {
"classification": "synchronous-property-setter-and-link-extension",
"reason": "no-native-cancel-hook",
"replacement": "abort-active-document-transaction",
"supported": false
},
"freecadVersion": "1.1.1",
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
"links": [
{
"directWrite": {
"after": [
true,
true
],
"exception": {
"message": "Object attribute 'VisibilityList' is read-only",
"type": "AttributeError"
},
"preserved": true,
"requested": [
false,
true
]
},
"editorMode": [
"Hidden"
],
"initial": [
true,
true
],
"invalidElement": {
"after": [
true,
true
],
"name": "MissingElement",
"preserved": true,
"result": -1
},
"objectState": [
"Up-to-date"
],
"objectTypeId": "App::Link",
"objectsAfter": [
{
"name": "TargetA",
"typeId": "Part::Feature"
},
{
"name": "TargetB",
"typeId": "Part::Feature"
},
{
"name": "TargetGroup",
"typeId": "App::DocumentObjectGroup"
},
{
"name": "LinkProbe",
"typeId": "App::Link"
}
],
"objectsBefore": [
{
"name": "TargetA",
"typeId": "Part::Feature"
},
{
"name": "TargetB",
"typeId": "Part::Feature"
},
{
"name": "TargetGroup",
"typeId": "App::DocumentObjectGroup"
},
{
"name": "LinkProbe",
"typeId": "App::Link"
}
],
"objectsPreserved": true,
"propertyTypeId": "App::PropertyBoolList",
"status": [
"Immutable",
"Hidden",
"LockDynamic"
],
"statusString": "Valid",
"transaction": {
"activeAfterAbort": {
"id": 0,
"name": ""
},
"activeAfterEdit": {
"id": 2,
"name": "property-boollist-link-cancel"
},
"afterAbort": [
true,
true
],
"before": [
true,
true
],
"edited": [
false,
true
],
"hideResult": 1,
"pendingAfterAbort": false,
"pendingAfterEdit": true,
"recoveryRecomputeResult": true,
"restored": true,
"stateAfterAbort": [
"Touched"
],
"stateAfterRecovery": [
"Up-to-date"
],
"statusAfterAbort": "Touched",
"statusAfterRecovery": "Valid"
}
},
{
"directWrite": {
"after": [
true,
true
],
"exception": {
"message": "Object attribute 'VisibilityList' is read-only",
"type": "AttributeError"
},
"preserved": true,
"requested": [
false,
true
]
},
"editorMode": [
"Hidden"
],
"initial": [
true,
true
],
"invalidElement": {
"after": [
true,
true
],
"name": "MissingElement",
"preserved": true,
"result": -1
},
"objectState": [
"Up-to-date"
],
"objectTypeId": "App::LinkGroup",
"objectsAfter": [
{
"name": "TargetA",
"typeId": "Part::Feature"
},
{
"name": "TargetB",
"typeId": "Part::Feature"
},
{
"name": "TargetGroup",
"typeId": "App::DocumentObjectGroup"
},
{
"name": "LinkGroupProbe",
"typeId": "App::LinkGroup"
}
],
"objectsBefore": [
{
"name": "TargetA",
"typeId": "Part::Feature"
},
{
"name": "TargetB",
"typeId": "Part::Feature"
},
{
"name": "TargetGroup",
"typeId": "App::DocumentObjectGroup"
},
{
"name": "LinkGroupProbe",
"typeId": "App::LinkGroup"
}
],
"objectsPreserved": true,
"propertyTypeId": "App::PropertyBoolList",
"status": [
"Immutable",
"Hidden",
"LockDynamic"
],
"statusString": "Valid",
"transaction": {
"activeAfterAbort": {
"id": 0,
"name": ""
},
"activeAfterEdit": {
"id": 3,
"name": "property-boollist-link-cancel"
},
"afterAbort": [
true,
true
],
"before": [
true,
true
],
"edited": [
false,
true
],
"hideResult": 1,
"pendingAfterAbort": false,
"pendingAfterEdit": true,
"recoveryRecomputeResult": true,
"restored": true,
"stateAfterAbort": [
"Touched"
],
"stateAfterRecovery": [
"Up-to-date"
],
"statusAfterAbort": "Touched",
"statusAfterRecovery": "Valid"
}
},
{
"directWrite": {
"after": [
true,
true
],
"exception": {
"message": "Object attribute 'VisibilityList' is read-only",
"type": "AttributeError"
},
"preserved": true,
"requested": [
false,
true
]
},
"editorMode": [
"Hidden"
],
"initial": [
true,
true
],
"invalidElement": {
"after": [
true,
true
],
"name": "MissingElement",
"preserved": true,
"result": -1
},
"objectState": [
"Up-to-date"
],
"objectTypeId": "App::LinkGroupPython",
"objectsAfter": [
{
"name": "TargetA",
"typeId": "Part::Feature"
},
{
"name": "TargetB",
"typeId": "Part::Feature"
},
{
"name": "TargetGroup",
"typeId": "App::DocumentObjectGroup"
},
{
"name": "LinkGroupPythonProbe",
"typeId": "App::LinkGroupPython"
}
],
"objectsBefore": [
{
"name": "TargetA",
"typeId": "Part::Feature"
},
{
"name": "TargetB",
"typeId": "Part::Feature"
},
{
"name": "TargetGroup",
"typeId": "App::DocumentObjectGroup"
},
{
"name": "LinkGroupPythonProbe",
"typeId": "App::LinkGroupPython"
}
],
"objectsPreserved": true,
"propertyTypeId": "App::PropertyBoolList",
"status": [
"Immutable",
"Hidden",
"LockDynamic"
],
"statusString": "Valid",
"transaction": {
"activeAfterAbort": {
"id": 0,
"name": ""
},
"activeAfterEdit": {
"id": 4,
"name": "property-boollist-link-cancel"
},
"afterAbort": [
true,
true
],
"before": [
true,
true
],
"edited": [
false,
true
],
"hideResult": 1,
"pendingAfterAbort": false,
"pendingAfterEdit": true,
"recoveryRecomputeResult": true,
"restored": true,
"stateAfterAbort": [
"Touched"
],
"stateAfterRecovery": [
"Up-to-date"
],
"statusAfterAbort": "Touched",
"statusAfterRecovery": "Valid"
}
},
{
"directWrite": {
"after": [
true,
true
],
"exception": {
"message": "Object attribute 'VisibilityList' is read-only",
"type": "AttributeError"
},
"preserved": true,
"requested": [
false,
true
]
},
"editorMode": [
"Hidden"
],
"initial": [
true,
true
],
"invalidElement": {
"after": [
true,
true
],
"name": "MissingElement",
"preserved": true,
"result": -1
},
"objectState": [
"Up-to-date"
],
"objectTypeId": "App::LinkPython",
"objectsAfter": [
{
"name": "TargetA",
"typeId": "Part::Feature"
},
{
"name": "TargetB",
"typeId": "Part::Feature"
},
{
"name": "TargetGroup",
"typeId": "App::DocumentObjectGroup"
},
{
"name": "LinkPythonProbe",
"typeId": "App::LinkPython"
}
],
"objectsBefore": [
{
"name": "TargetA",
"typeId": "Part::Feature"
},
{
"name": "TargetB",
"typeId": "Part::Feature"
},
{
"name": "TargetGroup",
"typeId": "App::DocumentObjectGroup"
},
{
"name": "LinkPythonProbe",
"typeId": "App::LinkPython"
}
],
"objectsPreserved": true,
"propertyTypeId": "App::PropertyBoolList",
"status": [
"Immutable",
"Hidden",
"LockDynamic"
],
"statusString": "Valid",
"transaction": {
"activeAfterAbort": {
"id": 0,
"name": ""
},
"activeAfterEdit": {
"id": 5,
"name": "property-boollist-link-cancel"
},
"afterAbort": [
true,
true
],
"before": [
true,
true
],
"edited": [
false,
true
],
"hideResult": 1,
"pendingAfterAbort": false,
"pendingAfterEdit": true,
"recoveryRecomputeResult": true,
"restored": true,
"stateAfterAbort": [
"Touched"
],
"stateAfterRecovery": [
"Up-to-date"
],
"statusAfterAbort": "Touched",
"statusAfterRecovery": "Valid"
}
}
],
"propertyType": "App::PropertyBoolList",
"schemaVersion": 1,
"status": "pass",
"writable": {
"acceptedCoercions": [
{
"after": [
true
],
"afterObjects": [
{
"name": "BoolListProbe",
"typeId": "App::FeatureTest"
}
],
"before": [
false
],
"beforeObjects": [
{
"name": "BoolListProbe",
"typeId": "App::FeatureTest"
}
],
"exception": null,
"id": "scalar-integer",
"objectsPreserved": true,
"requested": "7"
},
{
"after": [
true,
false,
false,
false,
true
],
"afterObjects": [
{
"name": "BoolListProbe",
"typeId": "App::FeatureTest"
}
],
"before": [
false
],
"beforeObjects": [
{
"name": "BoolListProbe",
"typeId": "App::FeatureTest"
}
],
"exception": null,
"id": "bitstring",
"objectsPreserved": true,
"requested": "'10201'"
}
],
"disabled": {
"after": [
false
],
"afterObjects": [
{
"name": "BoolListProbe",
"typeId": "App::FeatureTest"
}
],
"before": [
false
],
"beforeObjects": [
{
"name": "BoolListProbe",
"typeId": "App::FeatureTest"
}
],
"classification": "editor-read-only-and-python-immutable",
"editorMode": [
"ReadOnly"
],
"exception": {
"message": "Object attribute 'BoolList' is read-only",
"type": "AttributeError"
},
"objectsPreserved": true,
"requested": [
true,
false
],
"restoredEditorMode": [],
"restoredStatus": [],
"status": [
"Immutable",
"ReadOnly"
],
"valuePreserved": true
},
"documentIntegrity": {
"finalObjects": [
{
"name": "BoolListProbe",
"typeId": "App::FeatureTest"
}
],
"initialObjects": [
{
"name": "BoolListProbe",
"typeId": "App::FeatureTest"
}
],
"objectsPreserved": true
},
"failures": [
{
"after": [
false
],
"afterObjects": [
{
"name": "BoolListProbe",
"typeId": "App::FeatureTest"
}
],
"before": [
false
],
"beforeObjects": [
{
"name": "BoolListProbe",
"typeId": "App::FeatureTest"
}
],
"exception": {
"message": "type in list must be bool or int, not NoneType",
"type": "TypeError"
},
"id": "none",
"objectsPreserved": true,
"polluted": false,
"requested": "None",
"valuePreserved": true
},
{
"after": [
false
],
"afterObjects": [
{
"name": "BoolListProbe",
"typeId": "App::FeatureTest"
}
],
"before": [
false
],
"beforeObjects": [
{
"name": "BoolListProbe",
"typeId": "App::FeatureTest"
}
],
"exception": {
"message": "type in list must be bool or int, not float",
"type": "TypeError"
},
"id": "float-item",
"objectsPreserved": true,
"polluted": false,
"requested": "[True, 1.5]",
"valuePreserved": true
},
{
"after": [
false
],
"afterObjects": [
{
"name": "BoolListProbe",
"typeId": "App::FeatureTest"
}
],
"before": [
false
],
"beforeObjects": [
{
"name": "BoolListProbe",
"typeId": "App::FeatureTest"
}
],
"exception": {
"message": "type in list must be bool or int, not str",
"type": "TypeError"
},
"id": "string-item",
"objectsPreserved": true,
"polluted": false,
"requested": "[False, 'bad']",
"valuePreserved": true
}
],
"initial": [
false
],
"object": {
"name": "BoolListProbe",
"typeId": "App::FeatureTest"
},
"property": {
"name": "BoolList",
"typeId": "App::PropertyBoolList"
},
"transaction": {
"activeAfterAbort": {
"id": 0,
"name": ""
},
"activeAfterEdit": {
"id": 1,
"name": "property-boollist-cancel"
},
"afterAbort": [
false
],
"before": [
false
],
"edited": [
true,
false,
true
],
"objectsAfter": [
{
"name": "BoolListProbe",
"typeId": "App::FeatureTest"
}
],
"objectsBefore": [
{
"name": "BoolListProbe",
"typeId": "App::FeatureTest"
}
],
"objectsRestored": true,
"pendingAfterAbort": false,
"pendingAfterEdit": true,
"restored": true,
"undoMode": 1
}
}
}

View File

@@ -0,0 +1,190 @@
{
"schemaVersion": 1,
"status": "pass",
"baseline": {
"freecadVersion": "1.1.1",
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
},
"propertyType": "App::PropertyBoolList",
"recordCount": 7,
"records": [
{
"objectTypeId": "App::FeatureTest",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "BoolList",
"group": "",
"status": [],
"defaultValue": [
false
],
"valueModel": {
"kind": "boolean-list",
"writable": true,
"elementType": "bool",
"cardinality": "variable"
},
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "App::FeatureTest",
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "App::FeatureTestException",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "BoolList",
"group": "",
"status": [],
"defaultValue": [
false
],
"valueModel": {
"kind": "boolean-list",
"writable": true,
"elementType": "bool",
"cardinality": "variable"
},
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "App::FeatureTestException",
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "App::Link",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "VisibilityList",
"group": " Link",
"status": [
"Immutable",
"Hidden",
"LockDynamic"
],
"defaultValue": [],
"valueModel": {
"kind": "boolean-list",
"writable": false,
"elementType": "bool",
"cardinality": "variable"
},
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "App::Link",
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "App::LinkGroup",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "VisibilityList",
"group": " Link",
"status": [
"Immutable",
"Hidden",
"LockDynamic"
],
"defaultValue": [],
"valueModel": {
"kind": "boolean-list",
"writable": false,
"elementType": "bool",
"cardinality": "variable"
},
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "App::LinkGroup",
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "App::LinkGroupPython",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "VisibilityList",
"group": " Link",
"status": [
"Immutable",
"Hidden",
"LockDynamic"
],
"defaultValue": [],
"valueModel": {
"kind": "boolean-list",
"writable": false,
"elementType": "bool",
"cardinality": "variable"
},
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "App::LinkGroupPython",
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "App::LinkPython",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "VisibilityList",
"group": " Link",
"status": [
"Immutable",
"Hidden",
"LockDynamic"
],
"defaultValue": [],
"valueModel": {
"kind": "boolean-list",
"writable": false,
"elementType": "bool",
"cardinality": "variable"
},
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "App::LinkPython",
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "Surface::GeomFillSurface",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "ReversedList",
"group": "",
"status": [],
"defaultValue": [
false
],
"valueModel": {
"kind": "boolean-list",
"writable": true,
"elementType": "bool",
"cardinality": "variable"
},
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "Surface::GeomFillSurface",
"source": "Document.supportedTypes runtime inventory"
}
}
],
"source": {
"path": ".cache/freecad/reference-desktop.json",
"bytes": 2298709,
"sha256": "082400ec7379e8efc2af16709032d45890d7092277967b714acb05761fd1c2a7"
},
"classification": "opaque-fcstd-proxy",
"nextPhases": [
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I"
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,80 @@
{
"schemaVersion": 1,
"status": "pass",
"taskId": "PROP-app-propertyboollist-I",
"baseline": {
"freecadVersion": "1.1.1",
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
},
"propertyType": "App::PropertyBoolList",
"recordCount": 7,
"phaseEvidence": {
"A": [
"config/freecad-property-boollist-inventory.json",
"check:freecad-property-boollist-inventory"
],
"B": [
"config/freecad-property-boollist-success.json",
"check:freecad-property-boollist-success"
],
"C": [
"config/freecad-property-boollist-failure.json",
"check:freecad-property-boollist-failure"
],
"D": [
"config/freecad-property-boollist-mutation.json",
"check:freecad-property-boollist-mutation"
],
"E": [
"src/facade/types.ts",
"src/facade/fcstd.ts",
"src/facade/mockFacade.ts",
"src/App.tsx",
"tests/propertyBoolListFacade.test.ts",
"test:freecad-property-boollist-facade"
],
"F": [
"tests/propertyBoolListTransaction.test.ts",
"test:freecad-property-boollist-transaction"
],
"G": [
"config/freecad-property-boollist-roundtrip.json",
"check:freecad-property-boollist-roundtrip"
],
"H": [
"config/chrome-property-boollist-verification.json",
"check:chrome-property-boollist"
]
},
"promotion": {
"from": "opaque-fcstd-proxy",
"to": "native-editable-codec",
"facadeValueModel": "variable-boolean-array",
"writableRecords": 3,
"immutableHiddenRecords": 4,
"fcstdElement": "BoolList",
"nativeRoundTripValue": [
true,
false,
true,
false
],
"browserRoundTripValue": [
true,
false,
true,
false
],
"zeroUnknownDrift": true
},
"exactBlockerSync": {
"nativeEditableTypes": 30,
"nativeEditableRecords": 4361,
"opaqueTypes": 50,
"opaqueRecords": 466,
"exactPromotionReady": false,
"exactBlocker": "50 runtime property types and 466 records remain opaque-only; complete native document and property semantics"
},
"systemExact": false,
"generatedAt": "2026-08-17T08:49:33.825Z"
}

View File

@@ -0,0 +1,137 @@
{
"schemaVersion": 1,
"status": "pass",
"baselineId": "freecad-1.1.1-property-boollist-roundtrip",
"freecadVersion": "1.1.1",
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
"archives": {
"nativeInitial": {
"path": ".cache/freecad/property-boollist-roundtrip/native-initial.FCStd",
"bytes": 2508,
"sha256": "8522c2c4b77c177deb9f19be98ecb8367ee1b803e8da1ec752f1406c0cc87e8d"
},
"webEdited": {
"path": ".cache/freecad/property-boollist-roundtrip/web-edited.FCStd",
"bytes": 2326,
"sha256": "1e351de85a66dfa7946422387a035ac9b05b337842db453360a0b7296b69b2c5"
},
"nativeResaved": {
"path": ".cache/freecad/property-boollist-roundtrip/native-resaved.FCStd",
"bytes": 2508,
"sha256": "a496ce0e2c5f987c11515e53d3bc8ff8b52471b2087483e1ef123373ac508293"
}
},
"nativeInitial": {
"object": {
"editorMode": [],
"hasShapeProperty": false,
"name": "BoolListProbe",
"propertyStatus": [],
"propertyTypeId": "App::PropertyBoolList",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"typeId": "App::FeatureTest",
"value": [
false
]
},
"objectSet": [
{
"name": "BoolListProbe",
"typeId": "App::FeatureTest"
}
]
},
"web": {
"before": {
"name": "BoolList",
"typeId": "App::PropertyBoolList",
"element": "BoolList",
"value": "[false]"
},
"after": {
"name": "BoolList",
"typeId": "App::PropertyBoolList",
"element": "BoolList",
"value": "[true,false,true,false]"
},
"objectSetPreserved": true,
"semanticObjectsPreserved": true,
"opaquePathsPreserved": 4,
"opaqueEntriesPreserved": true
},
"nativeAfter": {
"reopened": {
"object": {
"editorMode": [],
"hasShapeProperty": false,
"name": "BoolListProbe",
"propertyStatus": [],
"propertyTypeId": "App::PropertyBoolList",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"typeId": "App::FeatureTest",
"value": [
true,
false,
true,
false
]
},
"objectSet": [
{
"name": "BoolListProbe",
"typeId": "App::FeatureTest"
}
]
},
"resaved": {
"object": {
"editorMode": [],
"hasShapeProperty": false,
"name": "BoolListProbe",
"propertyStatus": [],
"propertyTypeId": "App::PropertyBoolList",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"typeId": "App::FeatureTest",
"value": [
true,
false,
true,
false
]
},
"objectSet": [
{
"name": "BoolListProbe",
"typeId": "App::FeatureTest"
}
]
}
},
"classification": {
"webValue": "[true,false,true,false]",
"reopenedValue": [
true,
false,
true,
false
],
"resavedValue": [
true,
false,
true,
false
],
"nativeOutputMatches": true,
"unknownSemanticDrift": false,
"zeroUnknownDrift": true
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,639 @@
{
"baselineId": "freecad-1.1.1-property-color-failure",
"cancellationBoundary": {
"classification": "synchronous-property-setter",
"reason": "no-native-cancel-hook",
"replacement": "abort-active-document-transaction",
"supported": false
},
"coercions": [
{
"accepted": true,
"after": [
2.0,
-1.0,
0.5,
1.5
],
"afterObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"before": [
0.0,
0.0,
0.0,
1.0
],
"beforeObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"exception": null,
"id": "float-out-of-range",
"objectsPreserved": true,
"requested": "(2.0, -1.0, 0.5, 1.5)",
"valuePreserved": false
},
{
"accepted": true,
"after": [
-0.003921569,
1.003921628,
2.003921509,
-1.0
],
"afterObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"before": [
0.0,
0.0,
0.0,
1.0
],
"beforeObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"exception": null,
"id": "integer-out-of-range",
"objectsPreserved": true,
"requested": "(-1, 256, 511, -255)",
"valuePreserved": false
},
{
"accepted": true,
"after": [
0.003921569,
0.0,
0.003921569,
0.0
],
"afterObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"before": [
0.0,
0.0,
0.0,
1.0
],
"beforeObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"exception": null,
"id": "boolean-tuple",
"objectsPreserved": true,
"requested": "(True, False, True, False)",
"valuePreserved": false
},
{
"accepted": true,
"after": [
1.0,
1.0,
1.0,
1.0
],
"afterObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"before": [
0.0,
0.0,
0.0,
1.0
],
"beforeObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"exception": null,
"id": "packed-max",
"objectsPreserved": true,
"requested": "4294967295",
"valuePreserved": false
},
{
"accepted": true,
"after": [
0.0,
0.0,
0.0,
0.0
],
"afterObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"before": [
0.0,
0.0,
0.0,
1.0
],
"beforeObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"exception": null,
"id": "packed-wrap",
"objectsPreserved": true,
"requested": "4294967296",
"valuePreserved": false
},
{
"accepted": true,
"after": [
1.0,
1.0,
1.0,
1.0
],
"afterObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"before": [
0.0,
0.0,
0.0,
1.0
],
"beforeObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"exception": null,
"id": "packed-negative",
"objectsPreserved": true,
"requested": "-1",
"valuePreserved": false
}
],
"disabled": {
"before": [
0.0,
0.0,
0.0,
1.0
],
"classification": "editor-readonly-python-mutable-until-immutable",
"editorMode": [
"ReadOnly"
],
"editorReadOnlyAfter": [
0.200000003,
0.300000012,
0.400000006,
0.5
],
"editorReadOnlyException": null,
"editorReadOnlyRequested": [
0.2,
0.3,
0.4,
0.5
],
"immutableAfter": [
0.0,
0.0,
0.0,
1.0
],
"immutableException": {
"message": "Object attribute 'Colour' is read-only",
"type": "AttributeError"
},
"immutableRequested": [
0.6,
0.7,
0.8,
0.9
],
"immutableStatus": [
"Immutable",
"ReadOnly"
],
"immutableValuePreserved": true,
"objectsPreserved": true,
"pythonBypassesEditorReadOnly": true,
"restoredEditorMode": [],
"restoredStatus": []
},
"documentIntegrity": {
"finalObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"initialObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"objectsPreserved": true
},
"failures": [
{
"after": [
0.0,
0.0,
0.0,
1.0
],
"afterObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"before": [
0.0,
0.0,
0.0,
1.0
],
"beforeObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"exception": {
"message": "type must be integer or tuple of float or tuple integer, not NoneType",
"type": "TypeError"
},
"id": "none",
"objectsPreserved": true,
"polluted": false,
"requested": "None",
"valuePreserved": true
},
{
"after": [
0.0,
0.0,
0.0,
1.0
],
"afterObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"before": [
0.0,
0.0,
0.0,
1.0
],
"beforeObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"exception": {
"message": "type must be integer or tuple of float or tuple integer, not list",
"type": "TypeError"
},
"id": "list",
"objectsPreserved": true,
"polluted": false,
"requested": "[0.1, 0.2, 0.3]",
"valuePreserved": true
},
{
"after": [
0.0,
0.0,
0.0,
1.0
],
"afterObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"before": [
0.0,
0.0,
0.0,
1.0
],
"beforeObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"exception": {
"message": "type must be integer or tuple of float or tuple integer, not tuple",
"type": "TypeError"
},
"id": "short-tuple",
"objectsPreserved": true,
"polluted": false,
"requested": "(0.1, 0.2)",
"valuePreserved": true
},
{
"after": [
0.0,
0.0,
0.0,
1.0
],
"afterObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"before": [
0.0,
0.0,
0.0,
1.0
],
"beforeObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"exception": {
"message": "type must be integer or tuple of float or tuple integer, not tuple",
"type": "TypeError"
},
"id": "long-tuple",
"objectsPreserved": true,
"polluted": false,
"requested": "(0.1, 0.2, 0.3, 0.4, 0.5)",
"valuePreserved": true
},
{
"after": [
0.0,
0.0,
0.0,
1.0
],
"afterObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"before": [
0.0,
0.0,
0.0,
1.0
],
"beforeObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"exception": {
"message": "Type in tuple must be float or integer",
"type": "TypeError"
},
"id": "string-first",
"objectsPreserved": true,
"polluted": false,
"requested": "('bad', 0.2, 0.3)",
"valuePreserved": true
},
{
"after": [
0.0,
0.0,
0.0,
1.0
],
"afterObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"before": [
0.0,
0.0,
0.0,
1.0
],
"beforeObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"exception": {
"message": "Type in tuple must be consistent (float)",
"type": "TypeError"
},
"id": "mixed-after-float",
"objectsPreserved": true,
"polluted": false,
"requested": "(0.1, 2, 0.3)",
"valuePreserved": true
},
{
"after": [
0.0,
0.0,
0.0,
1.0
],
"afterObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"before": [
0.0,
0.0,
0.0,
1.0
],
"beforeObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"exception": {
"message": "Type in tuple must be consistent (integer)",
"type": "TypeError"
},
"id": "mixed-after-integer",
"objectsPreserved": true,
"polluted": false,
"requested": "(1, 0.2, 3)",
"valuePreserved": true
},
{
"after": [
0.0,
0.0,
0.0,
1.0
],
"afterObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"before": [
0.0,
0.0,
0.0,
1.0
],
"beforeObjects": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"exception": {
"message": "type must be integer or tuple of float or tuple integer, not float",
"type": "TypeError"
},
"id": "scalar-float",
"objectsPreserved": true,
"polluted": false,
"requested": "0.5",
"valuePreserved": true
}
],
"freecadVersion": "1.1.1",
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
"initial": [
0.0,
0.0,
0.0,
1.0
],
"object": {
"name": "ColorProbe",
"typeId": "App::FeatureTest"
},
"property": {
"name": "Colour",
"typeId": "App::PropertyColor"
},
"propertyType": "App::PropertyColor",
"schemaVersion": 1,
"status": "pass",
"transaction": {
"activeAfterAbort": {
"id": 0,
"name": ""
},
"activeAfterEdit": {
"id": 1,
"name": "property-color-cancel"
},
"afterAbort": [
0.0,
0.0,
0.0,
1.0
],
"afterRecompute": [
0.0,
0.0,
0.0,
1.0
],
"before": [
0.0,
0.0,
0.0,
1.0
],
"edited": [
0.75,
0.5,
0.25,
0.125
],
"objectsAfter": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"objectsBefore": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
],
"objectsRestored": true,
"pendingAfterAbort": false,
"pendingAfterEdit": true,
"recoveryRecomputeResult": true,
"restored": true,
"stateAfterAbort": {
"state": [
"Touched"
],
"statusString": "Touched"
},
"stateAfterEdit": {
"state": [
"Touched"
],
"statusString": "Touched"
},
"stateAfterRecompute": {
"state": [
"Up-to-date"
],
"statusString": "Valid"
},
"undoMode": 1
}
}

View File

@@ -0,0 +1,523 @@
{
"schemaVersion": 1,
"status": "pass",
"baseline": {
"freecadVersion": "1.1.1",
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
},
"propertyType": "App::PropertyColor",
"recordCount": 8,
"records": [
{
"objectTypeId": "App::FeatureTest",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "Colour",
"group": "",
"status": [],
"defaultValue": [
0,
0,
0,
1
],
"valueModel": {
"kind": "rgba-color",
"channels": [
"red",
"green",
"blue",
"alpha"
],
"canonicalRepresentation": "four-channel-float-tuple",
"packedRepresentation": "0xRRGGBBAA",
"alphaSemantics": "1-opaque-0-transparent",
"writable": true
},
"inputs": [
{
"kind": "float-tuple",
"cardinality": [
3,
4
],
"componentsMustHaveSameType": true,
"omittedAlpha": 1
},
{
"kind": "integer-tuple",
"cardinality": [
3,
4
],
"componentsMustHaveSameType": true,
"normalizationDivisor": 255,
"omittedAlpha": 1
},
{
"kind": "packed-integer",
"encoding": "0xRRGGBBAA"
}
],
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "App::FeatureTest",
"source": "Document.supportedTypes runtime inventory",
"shapeRequired": false
}
},
{
"objectTypeId": "App::FeatureTestException",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "Colour",
"group": "",
"status": [],
"defaultValue": [
0,
0,
0,
1
],
"valueModel": {
"kind": "rgba-color",
"channels": [
"red",
"green",
"blue",
"alpha"
],
"canonicalRepresentation": "four-channel-float-tuple",
"packedRepresentation": "0xRRGGBBAA",
"alphaSemantics": "1-opaque-0-transparent",
"writable": true
},
"inputs": [
{
"kind": "float-tuple",
"cardinality": [
3,
4
],
"componentsMustHaveSameType": true,
"omittedAlpha": 1
},
{
"kind": "integer-tuple",
"cardinality": [
3,
4
],
"componentsMustHaveSameType": true,
"normalizationDivisor": 255,
"omittedAlpha": 1
},
{
"kind": "packed-integer",
"encoding": "0xRRGGBBAA"
}
],
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "App::FeatureTestException",
"source": "Document.supportedTypes runtime inventory",
"shapeRequired": false
}
},
{
"objectTypeId": "App::Part",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "Color",
"group": "",
"status": [],
"defaultValue": [
1,
1,
1,
0
],
"valueModel": {
"kind": "rgba-color",
"channels": [
"red",
"green",
"blue",
"alpha"
],
"canonicalRepresentation": "four-channel-float-tuple",
"packedRepresentation": "0xRRGGBBAA",
"alphaSemantics": "1-opaque-0-transparent",
"writable": true
},
"inputs": [
{
"kind": "float-tuple",
"cardinality": [
3,
4
],
"componentsMustHaveSameType": true,
"omittedAlpha": 1
},
{
"kind": "integer-tuple",
"cardinality": [
3,
4
],
"componentsMustHaveSameType": true,
"normalizationDivisor": 255,
"omittedAlpha": 1
},
{
"kind": "packed-integer",
"encoding": "0xRRGGBBAA"
}
],
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "App::Part",
"source": "Document.supportedTypes runtime inventory",
"shapeRequired": false
}
},
{
"objectTypeId": "Assembly::AssemblyLink",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "Color",
"group": "",
"status": [],
"defaultValue": [
1,
1,
1,
0
],
"valueModel": {
"kind": "rgba-color",
"channels": [
"red",
"green",
"blue",
"alpha"
],
"canonicalRepresentation": "four-channel-float-tuple",
"packedRepresentation": "0xRRGGBBAA",
"alphaSemantics": "1-opaque-0-transparent",
"writable": true
},
"inputs": [
{
"kind": "float-tuple",
"cardinality": [
3,
4
],
"componentsMustHaveSameType": true,
"omittedAlpha": 1
},
{
"kind": "integer-tuple",
"cardinality": [
3,
4
],
"componentsMustHaveSameType": true,
"normalizationDivisor": 255,
"omittedAlpha": 1
},
{
"kind": "packed-integer",
"encoding": "0xRRGGBBAA"
}
],
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "Assembly::AssemblyLink",
"source": "Document.supportedTypes runtime inventory",
"shapeRequired": false
}
},
{
"objectTypeId": "Assembly::AssemblyObject",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "Color",
"group": "",
"status": [],
"defaultValue": [
1,
1,
1,
0
],
"valueModel": {
"kind": "rgba-color",
"channels": [
"red",
"green",
"blue",
"alpha"
],
"canonicalRepresentation": "four-channel-float-tuple",
"packedRepresentation": "0xRRGGBBAA",
"alphaSemantics": "1-opaque-0-transparent",
"writable": true
},
"inputs": [
{
"kind": "float-tuple",
"cardinality": [
3,
4
],
"componentsMustHaveSameType": true,
"omittedAlpha": 1
},
{
"kind": "integer-tuple",
"cardinality": [
3,
4
],
"componentsMustHaveSameType": true,
"normalizationDivisor": 255,
"omittedAlpha": 1
},
{
"kind": "packed-integer",
"encoding": "0xRRGGBBAA"
}
],
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "Assembly::AssemblyObject",
"source": "Document.supportedTypes runtime inventory",
"shapeRequired": false
}
},
{
"objectTypeId": "TechDraw::DrawViewAnnotation",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "TextColor",
"group": "Annotation",
"status": [],
"defaultValue": [
0,
0,
0,
1
],
"valueModel": {
"kind": "rgba-color",
"channels": [
"red",
"green",
"blue",
"alpha"
],
"canonicalRepresentation": "four-channel-float-tuple",
"packedRepresentation": "0xRRGGBBAA",
"alphaSemantics": "1-opaque-0-transparent",
"writable": true
},
"inputs": [
{
"kind": "float-tuple",
"cardinality": [
3,
4
],
"componentsMustHaveSameType": true,
"omittedAlpha": 1
},
{
"kind": "integer-tuple",
"cardinality": [
3,
4
],
"componentsMustHaveSameType": true,
"normalizationDivisor": 255,
"omittedAlpha": 1
},
{
"kind": "packed-integer",
"encoding": "0xRRGGBBAA"
}
],
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawViewAnnotation",
"source": "Document.supportedTypes runtime inventory",
"shapeRequired": false
}
},
{
"objectTypeId": "TechDraw::DrawViewDraft",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "Color",
"group": "Draft view",
"status": [],
"defaultValue": [
0,
0,
0,
1
],
"valueModel": {
"kind": "rgba-color",
"channels": [
"red",
"green",
"blue",
"alpha"
],
"canonicalRepresentation": "four-channel-float-tuple",
"packedRepresentation": "0xRRGGBBAA",
"alphaSemantics": "1-opaque-0-transparent",
"writable": true
},
"inputs": [
{
"kind": "float-tuple",
"cardinality": [
3,
4
],
"componentsMustHaveSameType": true,
"omittedAlpha": 1
},
{
"kind": "integer-tuple",
"cardinality": [
3,
4
],
"componentsMustHaveSameType": true,
"normalizationDivisor": 255,
"omittedAlpha": 1
},
{
"kind": "packed-integer",
"encoding": "0xRRGGBBAA"
}
],
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawViewDraft",
"source": "Document.supportedTypes runtime inventory",
"shapeRequired": false
}
},
{
"objectTypeId": "TechDraw::DrawViewSpreadsheet",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "TextColor",
"group": "Spreadsheet",
"status": [],
"defaultValue": [
0,
0,
0,
1
],
"valueModel": {
"kind": "rgba-color",
"channels": [
"red",
"green",
"blue",
"alpha"
],
"canonicalRepresentation": "four-channel-float-tuple",
"packedRepresentation": "0xRRGGBBAA",
"alphaSemantics": "1-opaque-0-transparent",
"writable": true
},
"inputs": [
{
"kind": "float-tuple",
"cardinality": [
3,
4
],
"componentsMustHaveSameType": true,
"omittedAlpha": 1
},
{
"kind": "integer-tuple",
"cardinality": [
3,
4
],
"componentsMustHaveSameType": true,
"normalizationDivisor": 255,
"omittedAlpha": 1
},
{
"kind": "packed-integer",
"encoding": "0xRRGGBBAA"
}
],
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawViewSpreadsheet",
"source": "Document.supportedTypes runtime inventory",
"shapeRequired": false
}
}
],
"storage": {
"xmlElement": "PropertyColor",
"attribute": "value",
"encoding": "unsigned-decimal-packed-0xRRGGBBAA",
"legacyBeforeVersion": "1.1",
"legacyConversion": "invert-alpha-byte"
},
"provenance": {
"runtime": {
"path": ".cache/freecad/reference-desktop.json",
"bytes": 2298709,
"sha256": "082400ec7379e8efc2af16709032d45890d7092277967b714acb05761fd1c2a7"
},
"sources": [
{
"path": ".cache/freecad/FreeCAD/src/App/PropertyStandard.h",
"bytes": 37529,
"sha256": "3555ab386b4815329b09604bbd70626c2b24b66f90a7ff2c31052b55fd3c9244"
},
{
"path": ".cache/freecad/FreeCAD/src/App/PropertyStandard.cpp",
"bytes": 99757,
"sha256": "eeefbbd7020c85c21e2e6b5f777088261668492845cf4d172e31f600fe9b96fd"
},
{
"path": ".cache/freecad/FreeCAD/src/Base/Color.h",
"bytes": 8885,
"sha256": "4d4630c87209f0df85db30608026fc4389936719a301136c3eb389f0e48bf864"
},
{
"path": ".cache/freecad/FreeCAD/src/Base/Color.cpp",
"bytes": 5857,
"sha256": "19f55140ccc547a194fcf49b090a7648089e4ea1ee0406d4f0a591dd5abc6d7c"
}
]
},
"classification": "opaque-fcstd-proxy",
"nextPhases": [
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I"
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,80 @@
{
"schemaVersion": 1,
"status": "pass",
"taskId": "PROP-app-propertycolor-I",
"baseline": {
"freecadVersion": "1.1.1",
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
},
"propertyType": "App::PropertyColor",
"recordCount": 8,
"phaseEvidence": {
"A": [
"config/freecad-property-color-inventory.json",
"check:freecad-property-color-inventory"
],
"B": [
"config/freecad-property-color-success.json",
"check:freecad-property-color-success"
],
"C": [
"config/freecad-property-color-failure.json",
"check:freecad-property-color-failure"
],
"D": [
"config/freecad-property-color-mutation.json",
"check:freecad-property-color-mutation"
],
"E": [
"src/facade/types.ts",
"src/facade/fcstd.ts",
"src/facade/mockFacade.ts",
"src/App.tsx",
"tests/propertyColorFacade.test.ts",
"test:freecad-property-color-facade"
],
"F": [
"tests/propertyColorTransaction.test.ts",
"test:freecad-property-color-transaction"
],
"G": [
"config/freecad-property-color-roundtrip.json",
"check:freecad-property-color-roundtrip"
],
"H": [
"config/chrome-property-color-verification.json",
"check:chrome-property-color"
]
},
"promotion": {
"from": "opaque-fcstd-proxy",
"to": "native-editable-codec",
"facadeValueModel": "four-finite-rgba-channels-with-8-bit-fcstd-packing",
"writableRecords": 8,
"fcstdElement": "PropertyColor",
"fcstdPackedValue": "862362060",
"nativeRoundTripValue": [
0.200000003,
0.400000006,
0.600000024,
0.800000012
],
"browserRoundTripValue": [
0.2,
0.4,
0.6,
0.8
],
"zeroUnknownDrift": true
},
"exactBlockerSync": {
"nativeEditableTypes": 30,
"nativeEditableRecords": 4361,
"opaqueTypes": 50,
"opaqueRecords": 466,
"exactPromotionReady": false,
"exactBlocker": "50 runtime property types and 466 records remain opaque-only; complete native document and property semantics"
},
"systemExact": false,
"generatedAt": "2026-08-17T08:49:33.829Z"
}

View File

@@ -0,0 +1,146 @@
{
"schemaVersion": 1,
"status": "pass",
"baselineId": "freecad-1.1.1-property-color-roundtrip",
"freecadVersion": "1.1.1",
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
"archives": {
"nativeInitial": {
"path": ".cache/freecad/property-color-roundtrip/native-initial.FCStd",
"bytes": 2508,
"sha256": "93d6c2b60ffdd65f10bd4ca13e5dfcedf19c3a1b2c452d1e6a087e99be259c85"
},
"webEdited": {
"path": ".cache/freecad/property-color-roundtrip/web-edited.FCStd",
"bytes": 2324,
"sha256": "0572127ba788503c7c2bbe8d2b0f1ae1796fb5946ddc6c3610d8d6b15fbba37d"
},
"nativeResaved": {
"path": ".cache/freecad/property-color-roundtrip/native-resaved.FCStd",
"bytes": 2505,
"sha256": "e665faea155fb2d1aaa6a7c02bb07a060280098d4a92f52f568b8e37b5c3249d"
}
},
"nativeInitial": {
"object": {
"editorMode": [],
"hasShapeProperty": false,
"name": "ColorProbe",
"propertyStatus": [],
"propertyTypeId": "App::PropertyColor",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"typeId": "App::FeatureTest",
"value": [
0.06666667,
0.13333334,
0.200000003,
0.266666681
]
},
"objectSet": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
]
},
"web": {
"before": {
"name": "Colour",
"typeId": "App::PropertyColor",
"element": "PropertyColor",
"value": "287454020"
},
"after": {
"name": "Colour",
"typeId": "App::PropertyColor",
"element": "PropertyColor",
"value": "862362060"
},
"objectSetPreserved": true,
"semanticObjectsPreserved": true,
"opaquePathsPreserved": 4,
"opaqueEntriesPreserved": true
},
"nativeAfter": {
"reopened": {
"object": {
"editorMode": [],
"hasShapeProperty": false,
"name": "ColorProbe",
"propertyStatus": [],
"propertyTypeId": "App::PropertyColor",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"typeId": "App::FeatureTest",
"value": [
0.200000003,
0.400000006,
0.600000024,
0.800000012
]
},
"objectSet": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
]
},
"resaved": {
"object": {
"editorMode": [],
"hasShapeProperty": false,
"name": "ColorProbe",
"propertyStatus": [],
"propertyTypeId": "App::PropertyColor",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"typeId": "App::FeatureTest",
"value": [
0.200000003,
0.400000006,
0.600000024,
0.800000012
]
},
"objectSet": [
{
"name": "ColorProbe",
"typeId": "App::FeatureTest"
}
]
}
},
"classification": {
"requestedValue": [
0.2,
0.4,
0.6,
0.8
],
"webValue": "862362060",
"reopenedValue": [
0.200000003,
0.400000006,
0.600000024,
0.800000012
],
"resavedValue": [
0.200000003,
0.400000006,
0.600000024,
0.800000012
],
"nativeOutputMatches": true,
"unknownSemanticDrift": false,
"zeroUnknownDrift": true
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,174 @@
{
"schemaVersion": 1,
"status": "pass",
"baseline": {
"freecadVersion": "1.1.1",
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
},
"propertyType": "App::PropertyColorList",
"recordCount": 2,
"records": [
{
"objectTypeId": "App::FeatureTest",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "ColourList",
"group": "",
"status": [],
"defaultValue": [
[
0,
0,
0,
1
]
],
"valueModel": {
"kind": "ordered-rgba-color-list",
"elementRepresentation": "four-channel-float-tuple",
"packedElementRepresentation": "0xRRGGBBAA",
"alphaSemantics": "1-opaque-0-transparent",
"writable": true
},
"inputs": {
"collection": [
"sequence",
"iterable",
"single-tuple-color-value",
"single-non-sequence-color-value",
"integer-index-dictionary"
],
"dictionaryAppendIndexes": [
-1,
"current-size"
],
"elementSetters": [
"float-tuple-3-or-4",
"integer-tuple-3-or-4",
"packed-integer-0xRRGGBBAA"
]
},
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "App::FeatureTest",
"source": "Document.supportedTypes runtime inventory",
"shapeRequired": false
}
},
{
"objectTypeId": "App::FeatureTestException",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "ColourList",
"group": "",
"status": [],
"defaultValue": [
[
0,
0,
0,
1
]
],
"valueModel": {
"kind": "ordered-rgba-color-list",
"elementRepresentation": "four-channel-float-tuple",
"packedElementRepresentation": "0xRRGGBBAA",
"alphaSemantics": "1-opaque-0-transparent",
"writable": true
},
"inputs": {
"collection": [
"sequence",
"iterable",
"single-tuple-color-value",
"single-non-sequence-color-value",
"integer-index-dictionary"
],
"dictionaryAppendIndexes": [
-1,
"current-size"
],
"elementSetters": [
"float-tuple-3-or-4",
"integer-tuple-3-or-4",
"packed-integer-0xRRGGBBAA"
]
},
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "App::FeatureTestException",
"source": "Document.supportedTypes runtime inventory",
"shapeRequired": false
}
}
],
"storage": {
"xmlElement": "ColorList",
"fileAttribute": "file",
"nonEmptyExternalResourceName": "property-name",
"emptyResourceName": "",
"externalBinary": {
"byteOrder": "little-endian",
"count": "uint32",
"element": "uint32-packed-0xRRGGBBAA"
},
"legacyBeforeVersion": "1.1",
"legacyConversion": "invert-alpha-channel"
},
"provenance": {
"runtime": {
"path": ".cache/freecad/reference-desktop.json",
"bytes": 2298709,
"sha256": "082400ec7379e8efc2af16709032d45890d7092277967b714acb05761fd1c2a7"
},
"sources": [
{
"path": ".cache/freecad/FreeCAD/src/App/Property.h",
"bytes": 38213,
"sha256": "a1e7320ff880133a2131db148dc6c87659de5c765387c2d41995c9650f12d8b6"
},
{
"path": ".cache/freecad/FreeCAD/src/App/Property.cpp",
"bytes": 12499,
"sha256": "7d229c0a781694f3c507afbdaae25c8ee7f316088ce25e8e487bb7112bff5c70"
},
{
"path": ".cache/freecad/FreeCAD/src/App/PropertyStandard.h",
"bytes": 37529,
"sha256": "3555ab386b4815329b09604bbd70626c2b24b66f90a7ff2c31052b55fd3c9244"
},
{
"path": ".cache/freecad/FreeCAD/src/App/PropertyStandard.cpp",
"bytes": 99757,
"sha256": "eeefbbd7020c85c21e2e6b5f777088261668492845cf4d172e31f600fe9b96fd"
},
{
"path": ".cache/freecad/FreeCAD/src/Base/Color.h",
"bytes": 8885,
"sha256": "4d4630c87209f0df85db30608026fc4389936719a301136c3eb389f0e48bf864"
},
{
"path": ".cache/freecad/FreeCAD/src/Base/Stream.h",
"bytes": 19302,
"sha256": "6e38309e26a986c4d6c6c09a78815c6e854ee40b9057590f992fc321525e4203"
},
{
"path": ".cache/freecad/FreeCAD/src/Base/Stream.cpp",
"bytes": 22807,
"sha256": "52762550a00e94b737ebd866e6d649828a4517d143a1f0313844f57b7affa577"
}
]
},
"classification": "opaque-fcstd-proxy",
"nextPhases": [
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I"
]
}

View File

@@ -0,0 +1,418 @@
{
"baselineId": "freecad-1.1.1-property-colorlist-mutation",
"caseCount": 2,
"cases": [
{
"before": {
"editorMode": [],
"objectSet": [
{
"name": "FeatureTestColorListMutation",
"typeId": "App::FeatureTest"
}
],
"objectState": [
"Up-to-date"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyColorList",
"shape": {
"applicable": false,
"reason": "host-has-no-shape-property"
},
"statusString": "Valid",
"value": [
[
0.0,
0.0,
0.0,
1.0
]
]
},
"editRecomputeResult": true,
"edited": {
"editorMode": [],
"objectSet": [
{
"name": "FeatureTestColorListMutation",
"typeId": "App::FeatureTest"
}
],
"objectState": [
"Up-to-date"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyColorList",
"shape": {
"applicable": false,
"reason": "host-has-no-shape-property"
},
"statusString": "Valid",
"value": [
[
0.125,
0.375,
0.625,
0.875
],
[
0.06666667,
0.13333334,
0.200000003,
0.266666681
],
[
1.0,
0.0,
0.501960814,
0.250980407
],
[
0.0,
0.0,
0.0,
0.0
]
]
},
"hostExecution": "normal",
"mutationDetected": true,
"objectName": "FeatureTestColorListMutation",
"objectTypeId": "App::FeatureTest",
"propertyName": "ColourList",
"restoreRecomputeResult": true,
"restored": {
"editorMode": [],
"objectSet": [
{
"name": "FeatureTestColorListMutation",
"typeId": "App::FeatureTest"
}
],
"objectState": [
"Up-to-date"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyColorList",
"shape": {
"applicable": false,
"reason": "host-has-no-shape-property"
},
"statusString": "Valid",
"value": [
[
0.0,
0.0,
0.0,
1.0
]
]
},
"restoredExactly": true,
"target": [
[
0.125,
0.375,
0.625,
0.875
],
287454020,
[
255,
0,
128,
64
],
[
0.0,
0.0,
0.0,
0.0
]
],
"touchedAfterEdit": {
"editorMode": [],
"objectSet": [
{
"name": "FeatureTestColorListMutation",
"typeId": "App::FeatureTest"
}
],
"objectState": [
"Touched"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyColorList",
"shape": {
"applicable": false,
"reason": "host-has-no-shape-property"
},
"statusString": "Touched",
"value": [
[
0.125,
0.375,
0.625,
0.875
],
[
0.06666667,
0.13333334,
0.200000003,
0.266666681
],
[
1.0,
0.0,
0.501960814,
0.250980407
],
[
0.0,
0.0,
0.0,
0.0
]
]
},
"touchedAfterRestore": {
"editorMode": [],
"objectSet": [
{
"name": "FeatureTestColorListMutation",
"typeId": "App::FeatureTest"
}
],
"objectState": [
"Touched"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyColorList",
"shape": {
"applicable": false,
"reason": "host-has-no-shape-property"
},
"statusString": "Touched",
"value": [
[
0.0,
0.0,
0.0,
1.0
]
]
}
},
{
"before": {
"editorMode": [],
"objectSet": [
{
"name": "FeatureTestExceptionColorListMutation",
"typeId": "App::FeatureTestException"
}
],
"objectState": [
"Up-to-date"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyColorList",
"shape": {
"applicable": false,
"reason": "host-has-no-shape-property"
},
"statusString": "Valid",
"value": [
[
0.0,
0.0,
0.0,
1.0
]
]
},
"editRecomputeResult": true,
"edited": {
"editorMode": [],
"objectSet": [
{
"name": "FeatureTestExceptionColorListMutation",
"typeId": "App::FeatureTestException"
}
],
"objectState": [
"Touched",
"Invalid"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyColorList",
"shape": {
"applicable": false,
"reason": "host-has-no-shape-property"
},
"statusString": "FeatureTestException::execute(): Testexception ;-)",
"value": [
[
0.125,
0.375,
0.625,
0.875
],
[
0.06666667,
0.13333334,
0.200000003,
0.266666681
],
[
1.0,
0.0,
0.501960814,
0.250980407
],
[
0.0,
0.0,
0.0,
0.0
]
]
},
"hostExecution": "intrinsic-test-exception",
"mutationDetected": true,
"objectName": "FeatureTestExceptionColorListMutation",
"objectTypeId": "App::FeatureTestException",
"propertyName": "ColourList",
"restoreRecomputeResult": true,
"restored": {
"editorMode": [],
"objectSet": [
{
"name": "FeatureTestExceptionColorListMutation",
"typeId": "App::FeatureTestException"
}
],
"objectState": [
"Touched",
"Invalid"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyColorList",
"shape": {
"applicable": false,
"reason": "host-has-no-shape-property"
},
"statusString": "FeatureTestException::execute(): Testexception ;-)",
"value": [
[
0.0,
0.0,
0.0,
1.0
]
]
},
"restoredExactly": true,
"target": [
[
0.125,
0.375,
0.625,
0.875
],
287454020,
[
255,
0,
128,
64
],
[
0.0,
0.0,
0.0,
0.0
]
],
"touchedAfterEdit": {
"editorMode": [],
"objectSet": [
{
"name": "FeatureTestExceptionColorListMutation",
"typeId": "App::FeatureTestException"
}
],
"objectState": [
"Touched"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyColorList",
"shape": {
"applicable": false,
"reason": "host-has-no-shape-property"
},
"statusString": "Touched",
"value": [
[
0.125,
0.375,
0.625,
0.875
],
[
0.06666667,
0.13333334,
0.200000003,
0.266666681
],
[
1.0,
0.0,
0.501960814,
0.250980407
],
[
0.0,
0.0,
0.0,
0.0
]
]
},
"touchedAfterRestore": {
"editorMode": [],
"objectSet": [
{
"name": "FeatureTestExceptionColorListMutation",
"typeId": "App::FeatureTestException"
}
],
"objectState": [
"Touched",
"Invalid"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyColorList",
"shape": {
"applicable": false,
"reason": "host-has-no-shape-property"
},
"statusString": "FeatureTestException::execute(): Testexception ;-)",
"value": [
[
0.0,
0.0,
0.0,
1.0
]
]
}
}
],
"freecadVersion": "1.1.1",
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
"propertyType": "App::PropertyColorList",
"schemaVersion": 1,
"status": "pass"
}

View File

@@ -0,0 +1,97 @@
{
"schemaVersion": 1,
"status": "pass",
"taskId": "PROP-app-propertycolorlist-I",
"baseline": {
"freecadVersion": "1.1.1",
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
},
"propertyType": "App::PropertyColorList",
"recordCount": 2,
"phaseEvidence": {
"A": [
"config/freecad-property-colorlist-inventory.json",
"check:freecad-property-colorlist-inventory"
],
"B": [
"config/freecad-property-colorlist-success.json",
"check:freecad-property-colorlist-success"
],
"C": [
"config/freecad-property-colorlist-failure.json",
"check:freecad-property-colorlist-failure"
],
"D": [
"config/freecad-property-colorlist-mutation.json",
"check:freecad-property-colorlist-mutation"
],
"E": [
"src/facade/types.ts",
"src/facade/fcstd.ts",
"src/facade/mockFacade.ts",
"src/App.tsx",
"tests/propertyColorListFacade.test.ts",
"test:freecad-property-colorlist-facade"
],
"F": [
"tests/propertyColorListTransaction.test.ts",
"test:freecad-property-colorlist-transaction"
],
"G": [
"config/freecad-property-colorlist-roundtrip.json",
"check:freecad-property-colorlist-roundtrip"
],
"H": [
"config/chrome-property-colorlist-verification.json",
"check:chrome-property-colorlist"
]
},
"promotion": {
"from": "opaque-fcstd-proxy",
"to": "native-editable-codec",
"facadeValueModel": "ordered-variable-rgba-array-with-external-8-bit-fcstd-packing",
"writableRecords": 2,
"fcstdElement": "ColorList",
"fcstdResourcePath": "ColourList",
"fcstdResourceBytes": 12,
"nativeRoundTripValue": [
[
0.200000003,
0.400000006,
0.600000024,
0.800000012
],
[
0.06666667,
0.13333334,
0.200000003,
0.266666681
]
],
"browserRoundTripValue": [
[
0.2,
0.4,
0.6,
0.8
],
[
0.06666666666666667,
0.13333333333333333,
0.2,
0.4
]
],
"zeroUnknownDrift": true
},
"exactBlockerSync": {
"nativeEditableTypes": 30,
"nativeEditableRecords": 4361,
"opaqueTypes": 50,
"opaqueRecords": 466,
"exactPromotionReady": false,
"exactBlocker": "50 runtime property types and 466 records remain opaque-only; complete native document and property semantics"
},
"systemExact": false,
"generatedAt": "2026-08-17T08:49:33.826Z"
}

View File

@@ -0,0 +1,198 @@
{
"schemaVersion": 1,
"status": "pass",
"baselineId": "freecad-1.1.1-property-colorlist-roundtrip",
"freecadVersion": "1.1.1",
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
"propertyType": "App::PropertyColorList",
"archives": {
"nativeInitial": {
"path": ".cache/freecad/property-colorlist-roundtrip/native-initial.FCStd",
"bytes": 2510,
"sha256": "e4df2d68ecaae973613b1c8026e98502d69fc961943619fbb1624926f3b2e0af"
},
"webEdited": {
"path": ".cache/freecad/property-colorlist-roundtrip/web-edited.FCStd",
"bytes": 2330,
"sha256": "1efb3343cf3c9eb3e3f843287fdab2890727a631aff8ea574b60eeaf955181ca"
},
"nativeResaved": {
"path": ".cache/freecad/property-colorlist-roundtrip/native-resaved.FCStd",
"bytes": 2511,
"sha256": "0b14d095c2ecf85a19c588bf2b55bddea64f64a99f686fc2e837b98a2454a13f"
}
},
"nativeInitial": {
"object": {
"editorMode": [],
"hasShapeProperty": false,
"name": "ColorListProbe",
"propertyStatus": [],
"propertyTypeId": "App::PropertyColorList",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"typeId": "App::FeatureTest",
"value": [
[
0.06666667,
0.13333334,
0.200000003,
0.266666681
]
]
},
"objectSet": [
{
"name": "ColorListProbe",
"typeId": "App::FeatureTest"
}
]
},
"web": {
"before": {
"name": "ColourList",
"typeId": "App::PropertyColorList",
"element": "ColorList",
"value": "[[0.06666666666666667,0.13333333333333333,0.2,0.26666666666666666]]",
"resourcePath": "ColourList"
},
"after": {
"name": "ColourList",
"typeId": "App::PropertyColorList",
"element": "ColorList",
"value": "[[0.2,0.4,0.6,0.8],[0.06666666666666667,0.13333333333333333,0.2,0.26666666666666666]]",
"resourcePath": "ColourList"
},
"resource": {
"path": "ColourList",
"pathPreserved": true,
"beforeBytes": 8,
"afterBytes": 12,
"changed": true
},
"objectSetPreserved": true,
"semanticObjectsPreserved": true,
"opaquePathsPreserved": 3,
"opaqueEntriesPreserved": true
},
"nativeAfter": {
"reopened": {
"object": {
"editorMode": [],
"hasShapeProperty": false,
"name": "ColorListProbe",
"propertyStatus": [],
"propertyTypeId": "App::PropertyColorList",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"typeId": "App::FeatureTest",
"value": [
[
0.200000003,
0.400000006,
0.600000024,
0.800000012
],
[
0.06666667,
0.13333334,
0.200000003,
0.266666681
]
]
},
"objectSet": [
{
"name": "ColorListProbe",
"typeId": "App::FeatureTest"
}
]
},
"resaved": {
"object": {
"editorMode": [],
"hasShapeProperty": false,
"name": "ColorListProbe",
"propertyStatus": [],
"propertyTypeId": "App::PropertyColorList",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"typeId": "App::FeatureTest",
"value": [
[
0.200000003,
0.400000006,
0.600000024,
0.800000012
],
[
0.06666667,
0.13333334,
0.200000003,
0.266666681
]
]
},
"objectSet": [
{
"name": "ColorListProbe",
"typeId": "App::FeatureTest"
}
]
}
},
"classification": {
"requestedValue": [
[
0.2,
0.4,
0.6,
0.8
],
[
0.06666666666666667,
0.13333333333333333,
0.2,
0.26666666666666666
]
],
"webValue": "[[0.2,0.4,0.6,0.8],[0.06666666666666667,0.13333333333333333,0.2,0.26666666666666666]]",
"reopenedValue": [
[
0.200000003,
0.400000006,
0.600000024,
0.800000012
],
[
0.06666667,
0.13333334,
0.200000003,
0.266666681
]
],
"resavedValue": [
[
0.200000003,
0.400000006,
0.600000024,
0.800000012
],
[
0.06666667,
0.13333334,
0.200000003,
0.266666681
]
],
"nativeOutputMatches": true,
"unknownSemanticDrift": false,
"zeroUnknownDrift": true
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,201 @@
{
"schemaVersion": 1,
"status": "pass",
"baseline": {
"freecadVersion": "1.1.1",
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
},
"propertyType": "App::PropertyDirection",
"recordCount": 2,
"records": [
{
"objectTypeId": "Part::Mirroring",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "Normal",
"group": "Plane",
"status": [],
"defaultDisplayValue": "Vector (0.0, 0.0, 1.0)",
"defaultValue": [
0,
0,
1
],
"valueModel": {
"kind": "three-component-direction-vector",
"representation": "Base::Vector3d",
"normalizationAtPropertyBoundary": "none",
"unit": "Length",
"writable": true
},
"inputs": {
"accepted": [
"Base.Vector",
"tuple-of-three-float-or-integer-components"
],
"listAccepted": false,
"componentPaths": [
"x",
"y",
"z"
]
},
"editor": "Gui::PropertyEditor::PropertyDirectionItem",
"dependencies": [
{
"propertyName": "Source",
"role": "shape-source",
"requiredForExecution": true
},
{
"propertyName": "Base",
"role": "plane-origin",
"requiredForExecution": true
},
{
"propertyName": "MirrorPlane",
"role": "optional-plane-override",
"requiredForExecution": false,
"overrides": [
"Base",
"Normal"
],
"overriddenStatus": "ReadOnly"
}
],
"applicability": {
"requiredObjectTypeId": "Part::Mirroring",
"source": "Document.supportedTypes runtime inventory",
"propertyWriteRequiresShape": false,
"hostExecutionRequiresShapeInputs": true,
"nonZeroRequiredByConsumer": true,
"consumer": "gp_Ax2(gp_Pnt(Base), gp_Dir(Normal))"
}
},
{
"objectTypeId": "Part::ProjectOnSurface",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "Direction",
"group": "Projection",
"status": [],
"defaultDisplayValue": "Vector (0.0, 0.0, 1.0)",
"defaultValue": [
0,
0,
1
],
"valueModel": {
"kind": "three-component-direction-vector",
"representation": "Base::Vector3d",
"normalizationAtPropertyBoundary": "none",
"unit": "Length",
"writable": true
},
"inputs": {
"accepted": [
"Base.Vector",
"tuple-of-three-float-or-integer-components"
],
"listAccepted": false,
"componentPaths": [
"x",
"y",
"z"
]
},
"editor": "Gui::PropertyEditor::PropertyDirectionItem",
"dependencies": [
{
"propertyName": "SupportFace",
"role": "single-support-face",
"requiredForExecution": true
},
{
"propertyName": "Projection",
"role": "projected-shape-list",
"requiredForExecution": true
}
],
"applicability": {
"requiredObjectTypeId": "Part::ProjectOnSurface",
"source": "Document.supportedTypes runtime inventory",
"propertyWriteRequiresShape": false,
"hostExecutionRequiresShapeInputs": true,
"nonZeroRequiredByConsumer": true,
"consumer": "gp_Dir(Direction)"
}
}
],
"storage": {
"inheritedFrom": "App::PropertyVector",
"xmlElement": "PropertyVector",
"attributes": [
"valueX",
"valueY",
"valueZ"
],
"scalarEncoding": "decimal-double",
"externalResource": false
},
"provenance": {
"runtime": {
"path": ".cache/freecad/reference-desktop.json",
"bytes": 2298709,
"sha256": "082400ec7379e8efc2af16709032d45890d7092277967b714acb05761fd1c2a7"
},
"sources": [
{
"path": ".cache/freecad/FreeCAD/src/App/PropertyGeo.h",
"bytes": 15791,
"sha256": "641182ca1267b318af377b9d1cf22a9cc0c365939866bafc8e5b51dc26d9a928"
},
{
"path": ".cache/freecad/FreeCAD/src/App/PropertyGeo.cpp",
"bytes": 43128,
"sha256": "9e1553f42f8c537c8aee4d64d3bd06d4b8be0abc93e7b258901ee543fc52c553"
},
{
"path": ".cache/freecad/FreeCAD/src/Gui/propertyeditor/PropertyItem.h",
"bytes": 41826,
"sha256": "aaade89f5386b5d061b1b2d09a4fd01e7a27e3c601117fc00e44e115f347d9ed"
},
{
"path": ".cache/freecad/FreeCAD/src/Gui/propertyeditor/PropertyItem.cpp",
"bytes": 142093,
"sha256": "bf2f7cb4c01034425f4ebd46f901ada03c5fa02dcffbc1d3936e49ef7bc43b52"
},
{
"path": ".cache/freecad/FreeCAD/src/Mod/Part/App/FeatureMirroring.h",
"bytes": 2808,
"sha256": "f1d4bab8dccf115d1d81791afea90c4ac12768a0b07ce3cfcfc08718e1158876"
},
{
"path": ".cache/freecad/FreeCAD/src/Mod/Part/App/FeatureMirroring.cpp",
"bytes": 14307,
"sha256": "ce26935b3326ff5ddaf5a6e67ac5a7c52c03c1e6adf2e4f37b162fc6b755830e"
},
{
"path": ".cache/freecad/FreeCAD/src/Mod/Part/App/FeatureProjectOnSurface.h",
"bytes": 4249,
"sha256": "79a3a3126d696d43f29a12802df9c006bc29f4a8ac9b2fa4619806e57691435d"
},
{
"path": ".cache/freecad/FreeCAD/src/Mod/Part/App/FeatureProjectOnSurface.cpp",
"bytes": 16425,
"sha256": "19b4edfdb60d219aa2c120e7a90b390ca3cda438ed0bff72f43fa8ed09d3e5ed"
}
]
},
"classification": "opaque-fcstd-proxy",
"nextPhases": [
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I"
]
}

View File

@@ -0,0 +1,527 @@
{
"baselineId": "freecad-1.1.1-property-direction-mutation",
"caseCount": 2,
"cases": [
{
"caseId": "Mirroring",
"editedValue": [
0.25,
-0.5,
1.5
],
"geometryChanged": true,
"geometryRestored": true,
"objectName": "DirectionMirror",
"objectTypeId": "Part::Mirroring",
"objectsPreserved": true,
"phases": {
"afterRecompute": {
"editorMode": [],
"mustExecute": false,
"objectSet": [
{
"name": "MirrorSource",
"typeId": "Part::Box"
},
{
"name": "DirectionMirror",
"typeId": "Part::Mirroring"
}
],
"objectState": [
"Up-to-date"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyDirection",
"recomputeResult": true,
"shape": {
"area": 52.0,
"bounds": [
-1.170731707,
0.0,
-3.609756098,
2.195121951,
4.951219512,
1.756097561
],
"brepSha256": "78c098a6fa65ccee51c306e1af3d908c067c4866d0a937f225b35e5c4f00ce7f",
"edges": 12,
"faces": 6,
"isNull": false,
"shapeType": "Solid",
"solids": 1,
"valid": true,
"vertices": 8,
"volume": 24.0
},
"statusString": "Valid",
"value": [
0.25,
-0.5,
1.5
]
},
"afterRestoreRecompute": {
"editorMode": [],
"mustExecute": false,
"objectSet": [
{
"name": "MirrorSource",
"typeId": "Part::Box"
},
{
"name": "DirectionMirror",
"typeId": "Part::Mirroring"
}
],
"objectState": [
"Up-to-date"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyDirection",
"recomputeResult": true,
"shape": {
"area": 52.0,
"bounds": [
0.0,
0.0,
-4.0,
2.0,
3.0,
0.0
],
"brepSha256": "ba65608213dd700751777e936c8f7cdd2b84a9e043a4deeec8e57eec3614b69b",
"edges": 12,
"faces": 6,
"isNull": false,
"shapeType": "Solid",
"solids": 1,
"valid": true,
"vertices": 8,
"volume": 24.0
},
"statusString": "Valid",
"value": [
0.0,
0.0,
1.0
]
},
"afterRestoreSet": {
"editorMode": [],
"mustExecute": true,
"objectSet": [
{
"name": "MirrorSource",
"typeId": "Part::Box"
},
{
"name": "DirectionMirror",
"typeId": "Part::Mirroring"
}
],
"objectState": [
"Touched"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyDirection",
"recomputeResult": null,
"shape": {
"area": 52.0,
"bounds": [
0.0,
0.0,
-4.0,
2.0,
3.0,
0.0
],
"brepSha256": "ba65608213dd700751777e936c8f7cdd2b84a9e043a4deeec8e57eec3614b69b",
"edges": 12,
"faces": 6,
"isNull": false,
"shapeType": "Solid",
"solids": 1,
"valid": true,
"vertices": 8,
"volume": 24.0
},
"statusString": "Touched",
"value": [
0.0,
0.0,
1.0
]
},
"afterSet": {
"editorMode": [],
"mustExecute": true,
"objectSet": [
{
"name": "MirrorSource",
"typeId": "Part::Box"
},
{
"name": "DirectionMirror",
"typeId": "Part::Mirroring"
}
],
"objectState": [
"Touched"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyDirection",
"recomputeResult": null,
"shape": {
"area": 52.0,
"bounds": [
-1.170731707,
0.0,
-3.609756098,
2.195121951,
4.951219512,
1.756097561
],
"brepSha256": "78c098a6fa65ccee51c306e1af3d908c067c4866d0a937f225b35e5c4f00ce7f",
"edges": 12,
"faces": 6,
"isNull": false,
"shapeType": "Solid",
"solids": 1,
"valid": true,
"vertices": 8,
"volume": 24.0
},
"statusString": "Touched",
"value": [
0.25,
-0.5,
1.5
]
},
"before": {
"editorMode": [],
"mustExecute": false,
"objectSet": [
{
"name": "MirrorSource",
"typeId": "Part::Box"
},
{
"name": "DirectionMirror",
"typeId": "Part::Mirroring"
}
],
"objectState": [
"Up-to-date"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyDirection",
"recomputeResult": true,
"shape": {
"area": 52.0,
"bounds": [
0.0,
0.0,
-4.0,
2.0,
3.0,
0.0
],
"brepSha256": "ba65608213dd700751777e936c8f7cdd2b84a9e043a4deeec8e57eec3614b69b",
"edges": 12,
"faces": 6,
"isNull": false,
"shapeType": "Solid",
"solids": 1,
"valid": true,
"vertices": 8,
"volume": 24.0
},
"statusString": "Valid",
"value": [
0.0,
0.0,
1.0
]
}
},
"propertyName": "Normal",
"valueChanged": true,
"valueRestored": true
},
{
"caseId": "ProjectOnSurface",
"editedValue": [
0.25,
-0.5,
1.5
],
"geometryChanged": true,
"geometryRestored": true,
"objectName": "DirectionProjection",
"objectTypeId": "Part::ProjectOnSurface",
"objectsPreserved": true,
"phases": {
"afterRecompute": {
"editorMode": [],
"mustExecute": false,
"objectSet": [
{
"name": "ProjectionSupport",
"typeId": "Part::Feature"
},
{
"name": "ProjectionWire",
"typeId": "Part::Feature"
},
{
"name": "DirectionProjection",
"typeId": "Part::ProjectOnSurface"
}
],
"objectState": [
"Up-to-date"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyDirection",
"recomputeResult": true,
"shape": {
"area": 0.0,
"bounds": [
-3.166666667,
-4.666666667,
-0.0,
4.833333333,
1.333333333,
0.0
],
"brepSha256": "3c78808d667362064af03623580275fc042383070d13822c577066173f4ea7d8",
"edges": 4,
"faces": 0,
"isNull": false,
"shapeType": "Compound",
"solids": 0,
"valid": true,
"vertices": 4,
"volume": 0.0
},
"statusString": "Valid",
"value": [
0.25,
-0.5,
1.5
]
},
"afterRestoreRecompute": {
"editorMode": [],
"mustExecute": false,
"objectSet": [
{
"name": "ProjectionSupport",
"typeId": "Part::Feature"
},
{
"name": "ProjectionWire",
"typeId": "Part::Feature"
},
{
"name": "DirectionProjection",
"typeId": "Part::ProjectOnSurface"
}
],
"objectState": [
"Up-to-date"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyDirection",
"recomputeResult": true,
"shape": {
"area": 0.0,
"bounds": [
-4.0,
-3.0,
0.0,
4.0,
3.0,
0.0
],
"brepSha256": "ba5241977c38224f66ffb495b32d3468bdcde322f177ed8047ddac5423d197de",
"edges": 4,
"faces": 0,
"isNull": false,
"shapeType": "Compound",
"solids": 0,
"valid": true,
"vertices": 4,
"volume": 0.0
},
"statusString": "Valid",
"value": [
0.0,
0.0,
1.0
]
},
"afterRestoreSet": {
"editorMode": [],
"mustExecute": false,
"objectSet": [
{
"name": "ProjectionSupport",
"typeId": "Part::Feature"
},
{
"name": "ProjectionWire",
"typeId": "Part::Feature"
},
{
"name": "DirectionProjection",
"typeId": "Part::ProjectOnSurface"
}
],
"objectState": [
"Touched"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyDirection",
"recomputeResult": null,
"shape": {
"area": 0.0,
"bounds": [
-3.166666667,
-4.666666667,
-0.0,
4.833333333,
1.333333333,
0.0
],
"brepSha256": "3c78808d667362064af03623580275fc042383070d13822c577066173f4ea7d8",
"edges": 4,
"faces": 0,
"isNull": false,
"shapeType": "Compound",
"solids": 0,
"valid": true,
"vertices": 4,
"volume": 0.0
},
"statusString": "Touched",
"value": [
0.0,
0.0,
1.0
]
},
"afterSet": {
"editorMode": [],
"mustExecute": false,
"objectSet": [
{
"name": "ProjectionSupport",
"typeId": "Part::Feature"
},
{
"name": "ProjectionWire",
"typeId": "Part::Feature"
},
{
"name": "DirectionProjection",
"typeId": "Part::ProjectOnSurface"
}
],
"objectState": [
"Touched"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyDirection",
"recomputeResult": null,
"shape": {
"area": 0.0,
"bounds": [
-4.0,
-3.0,
0.0,
4.0,
3.0,
0.0
],
"brepSha256": "ba5241977c38224f66ffb495b32d3468bdcde322f177ed8047ddac5423d197de",
"edges": 4,
"faces": 0,
"isNull": false,
"shapeType": "Compound",
"solids": 0,
"valid": true,
"vertices": 4,
"volume": 0.0
},
"statusString": "Touched",
"value": [
0.25,
-0.5,
1.5
]
},
"before": {
"editorMode": [],
"mustExecute": false,
"objectSet": [
{
"name": "ProjectionSupport",
"typeId": "Part::Feature"
},
{
"name": "ProjectionWire",
"typeId": "Part::Feature"
},
{
"name": "DirectionProjection",
"typeId": "Part::ProjectOnSurface"
}
],
"objectState": [
"Up-to-date"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyDirection",
"recomputeResult": true,
"shape": {
"area": 0.0,
"bounds": [
-4.0,
-3.0,
0.0,
4.0,
3.0,
0.0
],
"brepSha256": "ba5241977c38224f66ffb495b32d3468bdcde322f177ed8047ddac5423d197de",
"edges": 4,
"faces": 0,
"isNull": false,
"shapeType": "Compound",
"solids": 0,
"valid": true,
"vertices": 4,
"volume": 0.0
},
"statusString": "Valid",
"value": [
0.0,
0.0,
1.0
]
}
},
"propertyName": "Direction",
"valueChanged": true,
"valueRestored": true
}
],
"freecadVersion": "1.1.1",
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
"propertyType": "App::PropertyDirection",
"schemaVersion": 1,
"status": "pass"
}

View File

@@ -0,0 +1,77 @@
{
"schemaVersion": 1,
"status": "pass",
"taskId": "PROP-app-propertydirection-I",
"baseline": {
"freecadVersion": "1.1.1",
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
},
"propertyType": "App::PropertyDirection",
"recordCount": 2,
"phaseEvidence": {
"A": [
"config/freecad-property-direction-inventory.json",
"check:freecad-property-direction-inventory"
],
"B": [
"config/freecad-property-direction-success.json",
"check:freecad-property-direction-success"
],
"C": [
"config/freecad-property-direction-failure.json",
"check:freecad-property-direction-failure"
],
"D": [
"config/freecad-property-direction-mutation.json",
"check:freecad-property-direction-mutation"
],
"E": [
"src/facade/types.ts",
"src/facade/fcstd.ts",
"src/facade/mockFacade.ts",
"src/App.tsx",
"tests/propertyDirectionFacade.test.ts",
"test:freecad-property-direction-facade"
],
"F": [
"tests/propertyDirectionTransaction.test.ts",
"test:freecad-property-direction-transaction"
],
"G": [
"config/freecad-property-direction-roundtrip.json",
"check:freecad-property-direction-roundtrip"
],
"H": [
"config/chrome-property-direction-verification.json",
"check:chrome-property-direction"
]
},
"promotion": {
"from": "opaque-fcstd-proxy",
"to": "native-editable-codec",
"facadeValueModel": "three-finite-vector-components-with-native-propertyvector-fcstd-payload",
"writableRecords": 2,
"fcstdElement": "PropertyVector",
"nativeRoundTripValue": {
"x": 0.25,
"y": -0.5,
"z": 1.5
},
"browserRoundTripValue": {
"x": 0.25,
"y": -0.5,
"z": 1.5
},
"zeroUnknownDrift": true
},
"exactBlockerSync": {
"nativeEditableTypes": 30,
"nativeEditableRecords": 4361,
"opaqueTypes": 50,
"opaqueRecords": 466,
"exactPromotionReady": false,
"exactBlocker": "50 runtime property types and 466 records remain opaque-only; complete native document and property semantics"
},
"systemExact": false,
"generatedAt": "2026-08-17T08:49:33.839Z"
}

View File

@@ -0,0 +1,328 @@
{
"schemaVersion": 1,
"status": "pass",
"baselineId": "freecad-1.1.1-property-direction-roundtrip",
"freecadVersion": "1.1.1",
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
"propertyType": "App::PropertyDirection",
"archives": {
"nativeInitial": {
"path": ".cache/freecad/property-direction-roundtrip/native-initial.FCStd",
"bytes": 3782,
"sha256": "e9e16561486feced5a81240c3815aca41ed2c13a1694119c053af6e1cb84a545"
},
"webEdited": {
"path": ".cache/freecad/property-direction-roundtrip/web-edited.FCStd",
"bytes": 3722,
"sha256": "7249873d594722059ef328cb0513b8eb8e1f7aa14a46b21bef504b009b0dad21"
},
"nativeResaved": {
"path": ".cache/freecad/property-direction-roundtrip/native-resaved.FCStd",
"bytes": 3981,
"sha256": "5f12251fbdf2a763d42838cc0ba109930fd452e5e48808f00506f34aececb874"
},
"nativeRepeatResaved": {
"path": ".cache/freecad/property-direction-roundtrip/native-resaved-repeat.FCStd",
"bytes": 3990,
"sha256": "a455f01e576b6d481eb0474b3048e7657c017bc1165aa11c7ebb43d7ad065f2c"
}
},
"nativeInitial": {
"object": {
"editorMode": [],
"name": "DirectionMirror",
"propertyStatus": [],
"propertyTypeId": "App::PropertyDirection",
"shape": {
"area": 52,
"bounds": [
0,
0,
-4,
2,
3,
0
],
"brepSha256": "88b166d7ee48d61dfcfc8ff0331c32ab6dfe18f4fcfe9ca29ade01c15d6b9406",
"edges": 12,
"faces": 6,
"isNull": false,
"shapeType": "Solid",
"solids": 1,
"valid": true,
"vertices": 8,
"volume": 24
},
"state": [
"Up-to-date"
],
"statusString": "Valid",
"typeId": "Part::Mirroring",
"value": {
"x": 0,
"y": 0,
"z": 1
}
},
"objectSet": [
{
"name": "MirrorSource",
"typeId": "Part::Box"
},
{
"name": "DirectionMirror",
"typeId": "Part::Mirroring"
}
]
},
"web": {
"before": {
"name": "Normal",
"typeId": "App::PropertyDirection",
"element": "PropertyVector",
"value": "{\"x\":0,\"y\":0,\"z\":1}"
},
"after": {
"name": "Normal",
"typeId": "App::PropertyDirection",
"element": "PropertyVector",
"value": "{\"x\":0.25,\"y\":-0.5,\"z\":1.5}"
},
"targetMarkedTouched": true,
"webOutputMatches": true,
"objectSetPreserved": true,
"semanticObjectsPreserved": true,
"opaquePathsPreserved": 3,
"opaqueEntriesPreserved": true
},
"nativeAfter": {
"reopened": {
"object": {
"editorMode": [],
"name": "DirectionMirror",
"propertyStatus": [],
"propertyTypeId": "App::PropertyDirection",
"shape": {
"area": 52,
"bounds": [
-1.170731707,
0,
-3.609756098,
2.195121951,
4.951219512,
1.756097561
],
"brepSha256": "78c098a6fa65ccee51c306e1af3d908c067c4866d0a937f225b35e5c4f00ce7f",
"edges": 12,
"faces": 6,
"isNull": false,
"shapeType": "Solid",
"solids": 1,
"valid": true,
"vertices": 8,
"volume": 24
},
"state": [
"Up-to-date"
],
"statusString": "Valid",
"typeId": "Part::Mirroring",
"value": {
"x": 0.25,
"y": -0.5,
"z": 1.5
}
},
"objectSet": [
{
"name": "MirrorSource",
"typeId": "Part::Box"
},
{
"name": "DirectionMirror",
"typeId": "Part::Mirroring"
}
]
},
"resaved": {
"object": {
"editorMode": [],
"name": "DirectionMirror",
"propertyStatus": [],
"propertyTypeId": "App::PropertyDirection",
"shape": {
"area": 52,
"bounds": [
-1.170731707,
0,
-3.609756098,
2.195121951,
4.951219512,
1.756097561
],
"brepSha256": "d2f2dec7c559cb100c4966733f07f8313886144c3fdb22d4e6f4b5185bb549c6",
"edges": 12,
"faces": 6,
"isNull": false,
"shapeType": "Solid",
"solids": 1,
"valid": true,
"vertices": 8,
"volume": 24
},
"state": [
"Up-to-date"
],
"statusString": "Valid",
"typeId": "Part::Mirroring",
"value": {
"x": 0.25,
"y": -0.5,
"z": 1.5
}
},
"objectSet": [
{
"name": "MirrorSource",
"typeId": "Part::Box"
},
{
"name": "DirectionMirror",
"typeId": "Part::Mirroring"
}
]
}
},
"nativeRepeat": {
"reopened": {
"object": {
"editorMode": [],
"name": "DirectionMirror",
"propertyStatus": [],
"propertyTypeId": "App::PropertyDirection",
"shape": {
"area": 52,
"bounds": [
-1.170731707,
0,
-3.609756098,
2.195121951,
4.951219512,
1.756097561
],
"brepSha256": "78c098a6fa65ccee51c306e1af3d908c067c4866d0a937f225b35e5c4f00ce7f",
"edges": 12,
"faces": 6,
"isNull": false,
"shapeType": "Solid",
"solids": 1,
"valid": true,
"vertices": 8,
"volume": 24
},
"state": [
"Up-to-date"
],
"statusString": "Valid",
"typeId": "Part::Mirroring",
"value": {
"x": 0.25,
"y": -0.5,
"z": 1.5
}
},
"objectSet": [
{
"name": "MirrorSource",
"typeId": "Part::Box"
},
{
"name": "DirectionMirror",
"typeId": "Part::Mirroring"
}
]
},
"resaved": {
"object": {
"editorMode": [],
"name": "DirectionMirror",
"propertyStatus": [],
"propertyTypeId": "App::PropertyDirection",
"shape": {
"area": 52,
"bounds": [
-1.170731707,
0,
-3.609756098,
2.195121951,
4.951219512,
1.756097561
],
"brepSha256": "d2f2dec7c559cb100c4966733f07f8313886144c3fdb22d4e6f4b5185bb549c6",
"edges": 12,
"faces": 6,
"isNull": false,
"shapeType": "Solid",
"solids": 1,
"valid": true,
"vertices": 8,
"volume": 24
},
"state": [
"Up-to-date"
],
"statusString": "Valid",
"typeId": "Part::Mirroring",
"value": {
"x": 0.25,
"y": -0.5,
"z": 1.5
}
},
"objectSet": [
{
"name": "MirrorSource",
"typeId": "Part::Box"
},
{
"name": "DirectionMirror",
"typeId": "Part::Mirroring"
}
]
}
},
"classification": {
"requestedValue": {
"x": 0.25,
"y": -0.5,
"z": 1.5
},
"webValue": {
"x": 0.25,
"y": -0.5,
"z": 1.5
},
"reopenedValue": {
"x": 0.25,
"y": -0.5,
"z": 1.5
},
"resavedValue": {
"x": 0.25,
"y": -0.5,
"z": 1.5
},
"nativeOutputMatches": true,
"nativeShapeChanged": true,
"nativeShapeStructureStable": true,
"nativeBrepReserialized": true,
"nativeBrepEvolutionReproduced": true,
"nativeAllowedEvolution": {
"classification": "native-allowed-evolution",
"dimension": "brep-serialization",
"reason": "FreeCAD save/reopen reserializes the recomputed Shape while direction, bounds, topology, mass properties and validity remain stable."
},
"unknownSemanticDrift": false,
"zeroUnknownDrift": true
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,308 @@
{
"baselineId": "freecad-1.1.1-property-file-failure",
"cancellationBoundary": {
"classification": "synchronous-property-setter",
"reason": "no-native-cancel-hook",
"replacement": "abort-active-document-transaction",
"supported": false
},
"disabled": {
"after": {
"editorMode": [
"ReadOnly"
],
"objectSet": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"objectState": [
"Touched",
"Invalid"
],
"propertyStatus": [
"Immutable",
"ReadOnly"
],
"propertyTypeId": "App::PropertyFile",
"statusString": "File does not exist",
"value": ""
},
"afterObjects": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"before": {
"editorMode": [],
"objectSet": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"objectState": [
"Touched",
"Invalid"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyFile",
"statusString": "File does not exist",
"value": ""
},
"beforeObjects": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"classification": "editor-read-only-and-python-immutable",
"editorMode": [
"ReadOnly"
],
"exception": {
"message": "Object attribute 'FileName' is read-only",
"type": "AttributeError"
},
"restoredEditorMode": [],
"restoredStatus": [],
"status": [
"Immutable",
"ReadOnly"
]
},
"documentIntegrity": {
"finalObjects": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"initialObjects": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"objectCount": 1,
"objectsPreserved": true
},
"failures": [
{
"after": {
"editorMode": [],
"objectSet": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"objectState": [
"Touched",
"Invalid"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyFile",
"statusString": "File does not exist",
"value": "/definitely/missing/bitbybit-file.stl"
},
"afterObjects": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"assignmentException": null,
"before": {
"editorMode": [],
"objectSet": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"objectState": [
"Up-to-date"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyFile",
"statusString": "Valid",
"value": ""
},
"beforeObjects": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"id": "missing-path",
"objectsPreserved": true,
"recomputeException": null,
"requested": "/definitely/missing/bitbybit-file.stl"
},
{
"after": {
"editorMode": [],
"objectSet": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"objectState": [
"Touched",
"Invalid"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyFile",
"statusString": "File does not exist",
"value": "/definitely/missing/bitbybit-file.stl"
},
"afterObjects": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"assignmentException": {
"message": "type must be str or unicode, not int",
"type": "TypeError"
},
"before": {
"editorMode": [],
"objectSet": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"objectState": [
"Touched",
"Invalid"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyFile",
"statusString": "File does not exist",
"value": "/definitely/missing/bitbybit-file.stl"
},
"beforeObjects": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"id": "wrong-type",
"objectsPreserved": true,
"recomputeException": null,
"requested": 12345
}
],
"freecadVersion": "1.1.1",
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
"initial": {
"editorMode": [],
"objectSet": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"objectState": [
"Up-to-date"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyFile",
"statusString": "Valid",
"value": ""
},
"object": {
"name": "FileProbe",
"typeId": "Mesh::Import"
},
"property": {
"name": "FileName",
"typeId": "App::PropertyFile"
},
"schemaVersion": 1,
"status": "pass",
"transaction": {
"activeAfterAbort": {
"id": 0,
"name": ""
},
"activeAfterEdit": {
"id": 1,
"name": "property-file-cancel"
},
"afterAbort": {
"editorMode": [],
"objectSet": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"objectState": [
"Touched",
"Invalid"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyFile",
"statusString": "File does not exist",
"value": ""
},
"before": {
"editorMode": [],
"objectSet": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"objectState": [
"Touched",
"Invalid"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyFile",
"statusString": "File does not exist",
"value": ""
},
"edited": {
"editorMode": [],
"objectSet": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"objectState": [
"Touched",
"Invalid"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyFile",
"statusString": "File does not exist",
"value": "/tmp/transaction-file.stl"
},
"objectsAfter": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"objectsBefore": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"objectsRestored": true,
"pendingAfterAbort": false,
"pendingAfterEdit": true,
"restored": true,
"undoMode": 1
}
}

View File

@@ -0,0 +1,619 @@
{
"schemaVersion": 1,
"status": "pass",
"baseline": {
"freecadVersion": "1.1.1",
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
},
"propertyType": "App::PropertyFile",
"recordCount": 16,
"records": [
{
"objectTypeId": "Mesh::Import",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "FileName",
"group": "",
"status": [],
"defaultRaw": "",
"valueModel": {
"kind": "path-string",
"representation": "App::PropertyString-derived UTF-8 path",
"defaultValue": "",
"writable": true,
"externalResource": true,
"browserEditBoundary": "host-absolute-paths are not written into the browser project; use an explicit project resource reference"
},
"inputs": {
"accepted": [
"string",
"{filename:string,filter?:string}"
],
"componentPaths": [
"filename",
"filter"
],
"emptyStringAccepted": true
},
"editor": "Gui::PropertyEditor::PropertyFileItem",
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "Mesh::Import",
"source": "Document.supportedTypes runtime inventory",
"propertyWriteRequiresShape": false
}
},
{
"objectTypeId": "TechDraw::DrawComplexSection",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "FileGeomPattern",
"group": "Cut Surface Format",
"status": [],
"defaultRaw": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/PAT/FCPAT.pat",
"valueModel": {
"kind": "path-string",
"representation": "App::PropertyString-derived UTF-8 path",
"defaultValue": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/PAT/FCPAT.pat",
"writable": true,
"externalResource": true,
"browserEditBoundary": "host-absolute-paths are not written into the browser project; use an explicit project resource reference"
},
"inputs": {
"accepted": [
"string",
"{filename:string,filter?:string}"
],
"componentPaths": [
"filename",
"filter"
],
"emptyStringAccepted": true
},
"editor": "Gui::PropertyEditor::PropertyFileItem",
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawComplexSection",
"source": "Document.supportedTypes runtime inventory",
"propertyWriteRequiresShape": false
}
},
{
"objectTypeId": "TechDraw::DrawComplexSection",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "FileHatchPattern",
"group": "Cut Surface Format",
"status": [],
"defaultRaw": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/Patterns/simple.svg",
"valueModel": {
"kind": "path-string",
"representation": "App::PropertyString-derived UTF-8 path",
"defaultValue": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/Patterns/simple.svg",
"writable": true,
"externalResource": true,
"browserEditBoundary": "host-absolute-paths are not written into the browser project; use an explicit project resource reference"
},
"inputs": {
"accepted": [
"string",
"{filename:string,filter?:string}"
],
"componentPaths": [
"filename",
"filter"
],
"emptyStringAccepted": true
},
"editor": "Gui::PropertyEditor::PropertyFileItem",
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawComplexSection",
"source": "Document.supportedTypes runtime inventory",
"propertyWriteRequiresShape": false
}
},
{
"objectTypeId": "TechDraw::DrawComplexSectionPython",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "FileGeomPattern",
"group": "Cut Surface Format",
"status": [],
"defaultRaw": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/PAT/FCPAT.pat",
"valueModel": {
"kind": "path-string",
"representation": "App::PropertyString-derived UTF-8 path",
"defaultValue": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/PAT/FCPAT.pat",
"writable": true,
"externalResource": true,
"browserEditBoundary": "host-absolute-paths are not written into the browser project; use an explicit project resource reference"
},
"inputs": {
"accepted": [
"string",
"{filename:string,filter?:string}"
],
"componentPaths": [
"filename",
"filter"
],
"emptyStringAccepted": true
},
"editor": "Gui::PropertyEditor::PropertyFileItem",
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawComplexSectionPython",
"source": "Document.supportedTypes runtime inventory",
"propertyWriteRequiresShape": false
}
},
{
"objectTypeId": "TechDraw::DrawComplexSectionPython",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "FileHatchPattern",
"group": "Cut Surface Format",
"status": [],
"defaultRaw": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/Patterns/simple.svg",
"valueModel": {
"kind": "path-string",
"representation": "App::PropertyString-derived UTF-8 path",
"defaultValue": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/Patterns/simple.svg",
"writable": true,
"externalResource": true,
"browserEditBoundary": "host-absolute-paths are not written into the browser project; use an explicit project resource reference"
},
"inputs": {
"accepted": [
"string",
"{filename:string,filter?:string}"
],
"componentPaths": [
"filename",
"filter"
],
"emptyStringAccepted": true
},
"editor": "Gui::PropertyEditor::PropertyFileItem",
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawComplexSectionPython",
"source": "Document.supportedTypes runtime inventory",
"propertyWriteRequiresShape": false
}
},
{
"objectTypeId": "TechDraw::DrawGeomHatch",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "FilePattern",
"group": "GeomHatch",
"status": [],
"defaultRaw": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/PAT/FCPAT.pat",
"valueModel": {
"kind": "path-string",
"representation": "App::PropertyString-derived UTF-8 path",
"defaultValue": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/PAT/FCPAT.pat",
"writable": true,
"externalResource": true,
"browserEditBoundary": "host-absolute-paths are not written into the browser project; use an explicit project resource reference"
},
"inputs": {
"accepted": [
"string",
"{filename:string,filter?:string}"
],
"componentPaths": [
"filename",
"filter"
],
"emptyStringAccepted": true
},
"editor": "Gui::PropertyEditor::PropertyFileItem",
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawGeomHatch",
"source": "Document.supportedTypes runtime inventory",
"propertyWriteRequiresShape": false
}
},
{
"objectTypeId": "TechDraw::DrawHatch",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "HatchPattern",
"group": "Hatch",
"status": [],
"defaultRaw": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/Patterns/simple.svg",
"valueModel": {
"kind": "path-string",
"representation": "App::PropertyString-derived UTF-8 path",
"defaultValue": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/Patterns/simple.svg",
"writable": true,
"externalResource": true,
"browserEditBoundary": "host-absolute-paths are not written into the browser project; use an explicit project resource reference"
},
"inputs": {
"accepted": [
"string",
"{filename:string,filter?:string}"
],
"componentPaths": [
"filename",
"filter"
],
"emptyStringAccepted": true
},
"editor": "Gui::PropertyEditor::PropertyFileItem",
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawHatch",
"source": "Document.supportedTypes runtime inventory",
"propertyWriteRequiresShape": false
}
},
{
"objectTypeId": "TechDraw::DrawParametricTemplate",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "Template",
"group": "Page",
"status": [],
"defaultRaw": "",
"valueModel": {
"kind": "path-string",
"representation": "App::PropertyString-derived UTF-8 path",
"defaultValue": "",
"writable": true,
"externalResource": true,
"browserEditBoundary": "host-absolute-paths are not written into the browser project; use an explicit project resource reference"
},
"inputs": {
"accepted": [
"string",
"{filename:string,filter?:string}"
],
"componentPaths": [
"filename",
"filter"
],
"emptyStringAccepted": true
},
"editor": "Gui::PropertyEditor::PropertyFileItem",
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawParametricTemplate",
"source": "Document.supportedTypes runtime inventory",
"propertyWriteRequiresShape": false
}
},
{
"objectTypeId": "TechDraw::DrawSVGTemplate",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "Template",
"group": "Template",
"status": [],
"defaultRaw": "",
"valueModel": {
"kind": "path-string",
"representation": "App::PropertyString-derived UTF-8 path",
"defaultValue": "",
"writable": true,
"externalResource": true,
"browserEditBoundary": "host-absolute-paths are not written into the browser project; use an explicit project resource reference"
},
"inputs": {
"accepted": [
"string",
"{filename:string,filter?:string}"
],
"componentPaths": [
"filename",
"filter"
],
"emptyStringAccepted": true
},
"editor": "Gui::PropertyEditor::PropertyFileItem",
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawSVGTemplate",
"source": "Document.supportedTypes runtime inventory",
"propertyWriteRequiresShape": false
}
},
{
"objectTypeId": "TechDraw::DrawTileWeld",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "SymbolFile",
"group": "TileWeld",
"status": [],
"defaultRaw": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/Symbols/Welding/blankTile.svg",
"valueModel": {
"kind": "path-string",
"representation": "App::PropertyString-derived UTF-8 path",
"defaultValue": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/Symbols/Welding/blankTile.svg",
"writable": true,
"externalResource": true,
"browserEditBoundary": "host-absolute-paths are not written into the browser project; use an explicit project resource reference"
},
"inputs": {
"accepted": [
"string",
"{filename:string,filter?:string}"
],
"componentPaths": [
"filename",
"filter"
],
"emptyStringAccepted": true
},
"editor": "Gui::PropertyEditor::PropertyFileItem",
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawTileWeld",
"source": "Document.supportedTypes runtime inventory",
"propertyWriteRequiresShape": false
}
},
{
"objectTypeId": "TechDraw::DrawTileWeldPython",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "SymbolFile",
"group": "TileWeld",
"status": [],
"defaultRaw": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/Symbols/Welding/blankTile.svg",
"valueModel": {
"kind": "path-string",
"representation": "App::PropertyString-derived UTF-8 path",
"defaultValue": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/Symbols/Welding/blankTile.svg",
"writable": true,
"externalResource": true,
"browserEditBoundary": "host-absolute-paths are not written into the browser project; use an explicit project resource reference"
},
"inputs": {
"accepted": [
"string",
"{filename:string,filter?:string}"
],
"componentPaths": [
"filename",
"filter"
],
"emptyStringAccepted": true
},
"editor": "Gui::PropertyEditor::PropertyFileItem",
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawTileWeldPython",
"source": "Document.supportedTypes runtime inventory",
"propertyWriteRequiresShape": false
}
},
{
"objectTypeId": "TechDraw::DrawViewImage",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "ImageFile",
"group": "Image",
"status": [],
"defaultRaw": "",
"valueModel": {
"kind": "path-string",
"representation": "App::PropertyString-derived UTF-8 path",
"defaultValue": "",
"writable": true,
"externalResource": true,
"browserEditBoundary": "host-absolute-paths are not written into the browser project; use an explicit project resource reference"
},
"inputs": {
"accepted": [
"string",
"{filename:string,filter?:string}"
],
"componentPaths": [
"filename",
"filter"
],
"emptyStringAccepted": true
},
"editor": "Gui::PropertyEditor::PropertyFileItem",
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawViewImage",
"source": "Document.supportedTypes runtime inventory",
"propertyWriteRequiresShape": false
}
},
{
"objectTypeId": "TechDraw::DrawViewSection",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "FileGeomPattern",
"group": "Cut Surface Format",
"status": [],
"defaultRaw": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/PAT/FCPAT.pat",
"valueModel": {
"kind": "path-string",
"representation": "App::PropertyString-derived UTF-8 path",
"defaultValue": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/PAT/FCPAT.pat",
"writable": true,
"externalResource": true,
"browserEditBoundary": "host-absolute-paths are not written into the browser project; use an explicit project resource reference"
},
"inputs": {
"accepted": [
"string",
"{filename:string,filter?:string}"
],
"componentPaths": [
"filename",
"filter"
],
"emptyStringAccepted": true
},
"editor": "Gui::PropertyEditor::PropertyFileItem",
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawViewSection",
"source": "Document.supportedTypes runtime inventory",
"propertyWriteRequiresShape": false
}
},
{
"objectTypeId": "TechDraw::DrawViewSection",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "FileHatchPattern",
"group": "Cut Surface Format",
"status": [],
"defaultRaw": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/Patterns/simple.svg",
"valueModel": {
"kind": "path-string",
"representation": "App::PropertyString-derived UTF-8 path",
"defaultValue": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/Patterns/simple.svg",
"writable": true,
"externalResource": true,
"browserEditBoundary": "host-absolute-paths are not written into the browser project; use an explicit project resource reference"
},
"inputs": {
"accepted": [
"string",
"{filename:string,filter?:string}"
],
"componentPaths": [
"filename",
"filter"
],
"emptyStringAccepted": true
},
"editor": "Gui::PropertyEditor::PropertyFileItem",
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawViewSection",
"source": "Document.supportedTypes runtime inventory",
"propertyWriteRequiresShape": false
}
},
{
"objectTypeId": "TechDraw::DrawViewSectionPython",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "FileGeomPattern",
"group": "Cut Surface Format",
"status": [],
"defaultRaw": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/PAT/FCPAT.pat",
"valueModel": {
"kind": "path-string",
"representation": "App::PropertyString-derived UTF-8 path",
"defaultValue": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/PAT/FCPAT.pat",
"writable": true,
"externalResource": true,
"browserEditBoundary": "host-absolute-paths are not written into the browser project; use an explicit project resource reference"
},
"inputs": {
"accepted": [
"string",
"{filename:string,filter?:string}"
],
"componentPaths": [
"filename",
"filter"
],
"emptyStringAccepted": true
},
"editor": "Gui::PropertyEditor::PropertyFileItem",
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawViewSectionPython",
"source": "Document.supportedTypes runtime inventory",
"propertyWriteRequiresShape": false
}
},
{
"objectTypeId": "TechDraw::DrawViewSectionPython",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "FileHatchPattern",
"group": "Cut Surface Format",
"status": [],
"defaultRaw": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/Patterns/simple.svg",
"valueModel": {
"kind": "path-string",
"representation": "App::PropertyString-derived UTF-8 path",
"defaultValue": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/install-desktop/share/Mod/TechDraw/Patterns/simple.svg",
"writable": true,
"externalResource": true,
"browserEditBoundary": "host-absolute-paths are not written into the browser project; use an explicit project resource reference"
},
"inputs": {
"accepted": [
"string",
"{filename:string,filter?:string}"
],
"componentPaths": [
"filename",
"filter"
],
"emptyStringAccepted": true
},
"editor": "Gui::PropertyEditor::PropertyFileItem",
"dependencies": [],
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawViewSectionPython",
"source": "Document.supportedTypes runtime inventory",
"propertyWriteRequiresShape": false
}
}
],
"storage": {
"inheritedFrom": "App::PropertyString",
"xmlElement": "String",
"scalarEncoding": "UTF-8 path string",
"externalResource": true,
"absoluteHostPathPolicy": "preserve-or-reject; never rewrite into browser project"
},
"provenance": {
"runtime": {
"path": ".cache/freecad/reference-desktop.json",
"bytes": 2298709,
"sha256": "082400ec7379e8efc2af16709032d45890d7092277967b714acb05761fd1c2a7"
},
"sources": [
{
"path": ".cache/freecad/FreeCAD/src/App/PropertyFile.h",
"bytes": 5474,
"sha256": "1e5d3fea7bebde48fafccbaf9edca92cdc9b727ccaaa74a50b70929a1fe02412"
},
{
"path": ".cache/freecad/FreeCAD/src/App/PropertyFile.cpp",
"bytes": 22084,
"sha256": "ee1b7a3a675d93b3beaca52ce819201e9d240c99e6eb08b391bd81e076ac21fe"
},
{
"path": ".cache/freecad/FreeCAD/src/Gui/propertyeditor/PropertyItem.h",
"bytes": 41826,
"sha256": "aaade89f5386b5d061b1b2d09a4fd01e7a27e3c601117fc00e44e115f347d9ed"
},
{
"path": ".cache/freecad/FreeCAD/src/Gui/propertyeditor/PropertyItem.cpp",
"bytes": 142093,
"sha256": "bf2f7cb4c01034425f4ebd46f901ada03c5fa02dcffbc1d3936e49ef7bc43b52"
}
]
},
"classification": "opaque-fcstd-proxy",
"nextPhases": [
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I"
]
}

View File

@@ -0,0 +1,82 @@
{
"baselineId": "freecad-1.1.1-property-file-mutation",
"classification": {
"invalidEditedPath": true,
"objectSetStable": true,
"restoreExact": true,
"unknownSemanticDrift": false,
"valueChanged": true
},
"freecadVersion": "1.1.1",
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
"object": {
"name": "FileProbe",
"typeId": "Mesh::Import"
},
"phases": {
"before": {
"editorMode": [],
"objectSet": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"objectState": [
"Up-to-date"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyFile",
"recomputeResult": false,
"statusString": "Valid",
"value": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/FreeCAD/data/tests/mesh.obj"
},
"edited": {
"editorMode": [],
"objectSet": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"objectState": [
"Touched",
"Invalid"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyFile",
"recomputeResult": true,
"statusString": "File does not exist",
"value": "/tmp/property-file-alternate.stl"
},
"restored": {
"editorMode": [],
"objectSet": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"objectState": [
"Up-to-date"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyFile",
"recomputeResult": true,
"statusString": "Valid",
"value": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/FreeCAD/data/tests/mesh.obj"
}
},
"property": {
"name": "FileName",
"typeId": "App::PropertyFile"
},
"propertyType": "App::PropertyFile",
"requested": {
"before": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/FreeCAD/data/tests/mesh.obj",
"edited": "/tmp/property-file-alternate.stl",
"restored": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/FreeCAD/data/tests/mesh.obj"
},
"schemaVersion": 1,
"status": "pass"
}

View File

@@ -0,0 +1,71 @@
{
"schemaVersion": 1,
"status": "pass",
"taskId": "PROP-app-propertyfile-I",
"baseline": {
"freecadVersion": "1.1.1",
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
},
"propertyType": "App::PropertyFile",
"recordCount": 16,
"phaseEvidence": {
"A": [
"config/freecad-property-file-inventory.json",
"check:freecad-property-file-inventory"
],
"B": [
"config/freecad-property-file-success.json",
"check:freecad-property-file-success"
],
"C": [
"config/freecad-property-file-failure.json",
"check:freecad-property-file-failure"
],
"D": [
"config/freecad-property-file-mutation.json",
"check:freecad-property-file-mutation"
],
"E": [
"src/facade/types.ts",
"src/facade/fcstd.ts",
"src/facade/mockFacade.ts",
"src/App.tsx",
"tests/propertyFileFacade.test.ts",
"test:freecad-property-file-facade"
],
"F": [
"tests/propertyFileTransaction.test.ts",
"test:freecad-property-file-transaction"
],
"G": [
"config/freecad-property-file-roundtrip.json",
"check:freecad-property-file-roundtrip"
],
"H": [
"config/chrome-property-file-verification.json",
"check:chrome-property-file"
]
},
"promotion": {
"from": "opaque-fcstd-proxy",
"to": "native-editable-codec",
"facadeValueModel": "safe-project-relative-path-string-with-native-string-fcstd-payload",
"writableRecords": 16,
"objectTypeCount": 12,
"fcstdElement": "String",
"nativeRoundTripValue": ".cache/freecad/property-file-roundtrip/alternate.obj",
"browserRoundTripValue": "project-files/chrome-updated.obj",
"externalResourceBoundary": "project-relative-path; asset bytes remain external to FCStd",
"zeroUnknownDrift": true
},
"exactBlockerSync": {
"nativeEditableTypes": 30,
"nativeEditableRecords": 4361,
"opaqueTypes": 50,
"opaqueRecords": 466,
"exactPromotionReady": false,
"exactBlocker": "50 runtime property types and 466 records remain opaque-only; complete native document and property semantics"
},
"systemExact": false,
"generatedAt": "2026-08-17T08:49:33.800Z"
}

View File

@@ -0,0 +1,191 @@
{
"schemaVersion": 1,
"status": "pass",
"baselineId": "freecad-1.1.1-property-file-roundtrip",
"freecadVersion": "1.1.1",
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
"propertyType": "App::PropertyFile",
"assets": {
"initial": {
"path": ".cache/freecad/FreeCAD/data/tests/mesh.obj",
"bytes": 429,
"sha256": "581dfc5ad60f64ff3f21a376aaab962675b396725a13d4a49e11c67c1c773738"
},
"target": {
"path": ".cache/freecad/property-file-roundtrip/alternate.obj",
"bytes": 66,
"sha256": "da9f1a2a70c4c8b781cdac75d547ea829de315e9108eb5c883b76d3756387a08"
}
},
"archives": {
"nativeInitial": {
"path": ".cache/freecad/property-file-roundtrip/native-initial.FCStd",
"bytes": 1611,
"sha256": "9577f735da4b4a800992a87ba156ba4c3b5a51e74ec4e1ac0acd9fae19b339e4"
},
"webEdited": {
"path": ".cache/freecad/property-file-roundtrip/web-edited.FCStd",
"bytes": 1470,
"sha256": "47ce9d56bd59cced3418396dbddca136925d4514c3e5c744657f3de8fb8c0c5e"
},
"nativeResaved": {
"path": ".cache/freecad/property-file-roundtrip/native-resaved.FCStd",
"bytes": 1519,
"sha256": "eba5caac14066c3b294728360ae96df64c6e958db1e196a0a6128d6a50982485"
}
},
"nativeInitial": {
"object": {
"asset": {
"bytes": 429,
"exists": true,
"sha256": "581dfc5ad60f64ff3f21a376aaab962675b396725a13d4a49e11c67c1c773738"
},
"editorMode": [],
"hasMeshProperty": true,
"hasShapeProperty": false,
"mesh": {
"bounds": [
-5,
-5,
-5,
5,
5,
5
],
"facets": 12,
"isEmpty": false,
"points": 8
},
"name": "FileProbe",
"propertyStatus": [],
"propertyTypeId": "App::PropertyFile",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"typeId": "Mesh::Import",
"value": ".cache/freecad/FreeCAD/data/tests/mesh.obj"
},
"objectSet": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
]
},
"web": {
"before": {
"name": "FileName",
"typeId": "App::PropertyFile",
"element": "String",
"value": ".cache/freecad/FreeCAD/data/tests/mesh.obj"
},
"after": {
"name": "FileName",
"typeId": "App::PropertyFile",
"element": "String",
"value": ".cache/freecad/property-file-roundtrip/alternate.obj"
},
"targetMarkedTouched": true,
"webOutputMatches": true,
"semanticObjectsPreserved": true,
"opaquePathsPreserved": 1,
"opaqueEntriesPreserved": true
},
"nativeAfter": {
"reopened": {
"object": {
"asset": {
"bytes": 66,
"exists": true,
"sha256": "da9f1a2a70c4c8b781cdac75d547ea829de315e9108eb5c883b76d3756387a08"
},
"editorMode": [],
"hasMeshProperty": true,
"hasShapeProperty": false,
"mesh": {
"bounds": [
0,
0,
0,
4,
3,
0
],
"facets": 1,
"isEmpty": false,
"points": 3
},
"name": "FileProbe",
"propertyStatus": [],
"propertyTypeId": "App::PropertyFile",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"typeId": "Mesh::Import",
"value": ".cache/freecad/property-file-roundtrip/alternate.obj"
},
"objectSet": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
]
},
"resaved": {
"object": {
"asset": {
"bytes": 66,
"exists": true,
"sha256": "da9f1a2a70c4c8b781cdac75d547ea829de315e9108eb5c883b76d3756387a08"
},
"editorMode": [],
"hasMeshProperty": true,
"hasShapeProperty": false,
"mesh": {
"bounds": [
0,
0,
0,
4,
3,
0
],
"facets": 1,
"isEmpty": false,
"points": 3
},
"name": "FileProbe",
"propertyStatus": [],
"propertyTypeId": "App::PropertyFile",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"typeId": "Mesh::Import",
"value": ".cache/freecad/property-file-roundtrip/alternate.obj"
},
"objectSet": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
]
}
},
"classification": {
"requestedValue": ".cache/freecad/property-file-roundtrip/alternate.obj",
"webValue": ".cache/freecad/property-file-roundtrip/alternate.obj",
"reopenedValue": ".cache/freecad/property-file-roundtrip/alternate.obj",
"resavedValue": ".cache/freecad/property-file-roundtrip/alternate.obj",
"nativeOutputMatches": true,
"objectSetPreserved": true,
"nativeMeshChanged": true,
"nativeMeshStable": true,
"externalResourceBoundary": "project-relative-path; asset bytes remain external to FCStd",
"unknownSemanticDrift": false,
"zeroUnknownDrift": true
}
}

View File

@@ -0,0 +1,161 @@
{
"asset": {
"bytes": 429,
"exists": true,
"path": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/FreeCAD/data/tests/mesh.obj"
},
"baselineId": "freecad-1.1.1-property-file-success",
"diagnostics": {
"documentObjectCount": 1,
"exception": null
},
"freecadVersion": "1.1.1",
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
"object": {
"name": "FileProbe",
"typeId": "Mesh::Import"
},
"phases": {
"default": {
"editorMode": [],
"mesh": {
"applicable": true,
"bounds": [
1.7976931348623157e+308,
1.7976931348623157e+308,
1.7976931348623157e+308,
-1.7976931348623157e+308,
-1.7976931348623157e+308,
-1.7976931348623157e+308
],
"facets": 0,
"isEmpty": true,
"vertices": 0
},
"mustExecute": null,
"objectSet": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"objectState": [
"Up-to-date"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyFile",
"recomputeResult": false,
"requested": "",
"statusString": "Valid",
"value": ""
},
"relative-path": {
"editorMode": [],
"mesh": {
"applicable": true,
"bounds": [
1.7976931348623157e+308,
1.7976931348623157e+308,
1.7976931348623157e+308,
-1.7976931348623157e+308,
-1.7976931348623157e+308,
-1.7976931348623157e+308
],
"facets": 0,
"isEmpty": true,
"vertices": 0
},
"mustExecute": null,
"objectSet": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"objectState": [
"Touched",
"Invalid"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyFile",
"recomputeResult": true,
"requested": "mesh-data/Cube.stl",
"statusString": "File does not exist",
"value": "mesh-data/Cube.stl"
},
"restored": {
"editorMode": [],
"mesh": {
"applicable": true,
"bounds": [
1.7976931348623157e+308,
1.7976931348623157e+308,
1.7976931348623157e+308,
-1.7976931348623157e+308,
-1.7976931348623157e+308,
-1.7976931348623157e+308
],
"facets": 0,
"isEmpty": true,
"vertices": 0
},
"mustExecute": null,
"objectSet": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"objectState": [
"Up-to-date"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyFile",
"recomputeResult": true,
"requested": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/FreeCAD/data/tests/mesh.obj",
"statusString": "Valid",
"value": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/FreeCAD/data/tests/mesh.obj"
},
"valid-mesh": {
"editorMode": [],
"mesh": {
"applicable": true,
"bounds": [
1.7976931348623157e+308,
1.7976931348623157e+308,
1.7976931348623157e+308,
-1.7976931348623157e+308,
-1.7976931348623157e+308,
-1.7976931348623157e+308
],
"facets": 0,
"isEmpty": true,
"vertices": 0
},
"mustExecute": null,
"objectSet": [
{
"name": "FileProbe",
"typeId": "Mesh::Import"
}
],
"objectState": [
"Up-to-date"
],
"propertyStatus": [],
"propertyTypeId": "App::PropertyFile",
"recomputeResult": true,
"requested": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/FreeCAD/data/tests/mesh.obj",
"statusString": "Valid",
"value": "/home/mes123456/working_Web_FreeCAD_Bitbybit/.cache/freecad/FreeCAD/data/tests/mesh.obj"
}
},
"property": {
"group": "",
"name": "FileName",
"typeId": "App::PropertyFile"
},
"propertyType": "App::PropertyFile",
"schemaVersion": 1,
"status": "pass"
}

View File

@@ -0,0 +1,865 @@
{
"acceptedRisks": [
{
"after": {
"baseName": "stable.bin",
"bytes": 0,
"editorMode": [],
"exists": false,
"isDirectory": true,
"isFile": false,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Touched"
],
"pathExists": true,
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": null,
"statusString": "Touched",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/stable.bin",
"writeBits": 0
},
"assignmentException": null,
"before": {
"baseName": "stable.bin",
"bytes": 29,
"editorMode": [],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Up-to-date"
],
"pathExists": true,
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "31f898b8e260a6dc642cf992483813de02d2cb9f4fe0f06be901d281f78f446e",
"statusString": "Valid",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/stable.bin",
"writeBits": 0
},
"directoryAccepted": true,
"id": "directory-path",
"objectsPreserved": true,
"oldFileRemoved": true,
"recovery": {
"baseName": "restored-after-directory.bin",
"bytes": 29,
"editorMode": [],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Up-to-date"
],
"pathExists": true,
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "31f898b8e260a6dc642cf992483813de02d2cb9f4fe0f06be901d281f78f446e",
"statusString": "Valid",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/restored-after-directory.bin",
"writeBits": 0
},
"requested": "'/tmp/freecad-property-fileincluded-failure-0ikgj5ie/directory'"
}
],
"baselineId": "freecad-1.1.1-property-fileincluded-failure",
"cancellationBoundary": {
"classification": "synchronous-property-setter",
"reason": "no-native-cancel-hook",
"replacement": "abort-active-document-transaction",
"supported": false
},
"documentIntegrity": {
"finalObjects": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"initialObjects": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectCount": 1,
"objectsPreserved": true
},
"editorReadOnly": {
"after": {
"baseName": "editor-write.bin",
"bytes": 34,
"editorMode": [
"ReadOnly"
],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Touched"
],
"pathExists": true,
"propertyStatus": [
"ReadOnly"
],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "72122705399a0111d36d7b74ec05f8155834ce6b394d1bd879f360e29f8bb365",
"statusString": "Touched",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/editor-write.bin",
"writeBits": 0
},
"before": {
"baseName": "restored-after-directory.bin",
"bytes": 29,
"editorMode": [],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Up-to-date"
],
"pathExists": true,
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "31f898b8e260a6dc642cf992483813de02d2cb9f4fe0f06be901d281f78f446e",
"statusString": "Valid",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/restored-after-directory.bin",
"writeBits": 0
},
"editorMode": [
"ReadOnly"
],
"exception": null,
"pythonBypassesEditorReadOnly": true
},
"failures": [
{
"after": {
"baseName": "stable.bin",
"bytes": 29,
"editorMode": [],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Up-to-date"
],
"pathExists": true,
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "31f898b8e260a6dc642cf992483813de02d2cb9f4fe0f06be901d281f78f446e",
"statusString": "Valid",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/stable.bin",
"writeBits": 0
},
"assignmentException": {
"message": "File /definitely/missing/property-fileincluded.bin does not exist.",
"type": "OSError"
},
"before": {
"baseName": "stable.bin",
"bytes": 29,
"editorMode": [],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Up-to-date"
],
"pathExists": true,
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "31f898b8e260a6dc642cf992483813de02d2cb9f4fe0f06be901d281f78f446e",
"statusString": "Valid",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/stable.bin",
"writeBits": 0
},
"id": "missing-path",
"objectSetAfter": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectSetBefore": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectsPreserved": true,
"requested": "'/definitely/missing/property-fileincluded.bin'",
"valuePreserved": true
},
{
"after": {
"baseName": "stable.bin",
"bytes": 29,
"editorMode": [],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Up-to-date"
],
"pathExists": true,
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "31f898b8e260a6dc642cf992483813de02d2cb9f4fe0f06be901d281f78f446e",
"statusString": "Valid",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/stable.bin",
"writeBits": 0
},
"assignmentException": {
"message": "Type must be string or file, not int",
"type": "TypeError"
},
"before": {
"baseName": "stable.bin",
"bytes": 29,
"editorMode": [],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Up-to-date"
],
"pathExists": true,
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "31f898b8e260a6dc642cf992483813de02d2cb9f4fe0f06be901d281f78f446e",
"statusString": "Valid",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/stable.bin",
"writeBits": 0
},
"id": "wrong-type",
"objectSetAfter": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectSetBefore": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectsPreserved": true,
"requested": "12345",
"valuePreserved": true
},
{
"after": {
"baseName": "stable.bin",
"bytes": 29,
"editorMode": [],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Up-to-date"
],
"pathExists": true,
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "31f898b8e260a6dc642cf992483813de02d2cb9f4fe0f06be901d281f78f446e",
"statusString": "Valid",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/stable.bin",
"writeBits": 0
},
"assignmentException": {
"message": "Tuple needs size of (filePath,newFileName)",
"type": "TypeError"
},
"before": {
"baseName": "stable.bin",
"bytes": 29,
"editorMode": [],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Up-to-date"
],
"pathExists": true,
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "31f898b8e260a6dc642cf992483813de02d2cb9f4fe0f06be901d281f78f446e",
"statusString": "Valid",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/stable.bin",
"writeBits": 0
},
"id": "tuple-wrong-arity",
"objectSetAfter": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectSetBefore": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectsPreserved": true,
"requested": "('/tmp/freecad-property-fileincluded-failure-0ikgj5ie/source.bin',)",
"valuePreserved": true
},
{
"after": {
"baseName": "stable.bin",
"bytes": 29,
"editorMode": [],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Up-to-date"
],
"pathExists": true,
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "31f898b8e260a6dc642cf992483813de02d2cb9f4fe0f06be901d281f78f446e",
"statusString": "Valid",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/stable.bin",
"writeBits": 0
},
"assignmentException": {
"message": "Second item in tuple must be a string, not int",
"type": "TypeError"
},
"before": {
"baseName": "stable.bin",
"bytes": 29,
"editorMode": [],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Up-to-date"
],
"pathExists": true,
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "31f898b8e260a6dc642cf992483813de02d2cb9f4fe0f06be901d281f78f446e",
"statusString": "Valid",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/stable.bin",
"writeBits": 0
},
"id": "tuple-wrong-name-type",
"objectSetAfter": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectSetBefore": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectsPreserved": true,
"requested": "('/tmp/freecad-property-fileincluded-failure-0ikgj5ie/source.bin', 123)",
"valuePreserved": true
},
{
"after": {
"baseName": "stable.bin",
"bytes": 29,
"editorMode": [],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Up-to-date"
],
"pathExists": true,
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "31f898b8e260a6dc642cf992483813de02d2cb9f4fe0f06be901d281f78f446e",
"statusString": "Valid",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/stable.bin",
"writeBits": 0
},
"assignmentException": {
"message": "PyCXX: Error creating object of type N2Py7SeqBaseINS_4CharEEE from 123",
"type": "TypeError"
},
"before": {
"baseName": "stable.bin",
"bytes": 29,
"editorMode": [],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Up-to-date"
],
"pathExists": true,
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "31f898b8e260a6dc642cf992483813de02d2cb9f4fe0f06be901d281f78f446e",
"statusString": "Valid",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/stable.bin",
"writeBits": 0
},
"id": "dictionary-wrong-filename-type",
"objectSetAfter": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectSetBefore": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectsPreserved": true,
"requested": "{'filename': 123}",
"valuePreserved": true
},
{
"after": {
"baseName": "restored-after-directory.bin",
"bytes": 29,
"editorMode": [],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Up-to-date"
],
"pathExists": true,
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "31f898b8e260a6dc642cf992483813de02d2cb9f4fe0f06be901d281f78f446e",
"statusString": "Valid",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/restored-after-directory.bin",
"writeBits": 0
},
"assignmentException": {
"message": "Not possible to set the same file!",
"type": "OSError"
},
"before": {
"baseName": "restored-after-directory.bin",
"bytes": 29,
"editorMode": [],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Up-to-date"
],
"pathExists": true,
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "31f898b8e260a6dc642cf992483813de02d2cb9f4fe0f06be901d281f78f446e",
"statusString": "Valid",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/restored-after-directory.bin",
"writeBits": 0
},
"id": "same-current-transient",
"objectSetAfter": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectSetBefore": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectsPreserved": true,
"requested": "'/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/restored-after-directory.bin'",
"valuePreserved": true
}
],
"filterOnly": {
"after": {
"baseName": "restored-after-directory.bin",
"bytes": 29,
"editorMode": [],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Up-to-date"
],
"pathExists": true,
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "31f898b8e260a6dc642cf992483813de02d2cb9f4fe0f06be901d281f78f446e",
"statusString": "Valid",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/restored-after-directory.bin",
"writeBits": 0
},
"before": {
"baseName": "restored-after-directory.bin",
"bytes": 29,
"editorMode": [],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Up-to-date"
],
"pathExists": true,
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "31f898b8e260a6dc642cf992483813de02d2cb9f4fe0f06be901d281f78f446e",
"statusString": "Valid",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/restored-after-directory.bin",
"writeBits": 0
},
"exception": null,
"objectsPreserved": true,
"valuePreserved": true
},
"freecadVersion": "1.1.1",
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
"immutable": {
"after": {
"baseName": "editor-write.bin",
"bytes": 34,
"editorMode": [],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Touched"
],
"pathExists": true,
"propertyStatus": [
"Immutable"
],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "72122705399a0111d36d7b74ec05f8155834ce6b394d1bd879f360e29f8bb365",
"statusString": "Touched",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/editor-write.bin",
"writeBits": 0
},
"before": {
"baseName": "editor-write.bin",
"bytes": 34,
"editorMode": [],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Touched"
],
"pathExists": true,
"propertyStatus": [
"Immutable"
],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "72122705399a0111d36d7b74ec05f8155834ce6b394d1bd879f360e29f8bb365",
"statusString": "Touched",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/editor-write.bin",
"writeBits": 0
},
"exception": {
"message": "Object attribute 'File' is read-only",
"type": "AttributeError"
},
"restoredStatus": [],
"status": [
"Immutable"
]
},
"initial": {
"baseName": "stable.bin",
"bytes": 29,
"editorMode": [],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Up-to-date"
],
"pathExists": true,
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "31f898b8e260a6dc642cf992483813de02d2cb9f4fe0f06be901d281f78f446e",
"statusString": "Valid",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/stable.bin",
"writeBits": 0
},
"object": {
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
},
"property": {
"name": "File",
"typeId": "App::PropertyFileIncluded"
},
"propertyType": "App::PropertyFileIncluded",
"schemaVersion": 1,
"status": "pass",
"transaction": {
"activeAfterAbort": {
"id": 0,
"name": ""
},
"activeAfterEdit": {
"id": 1,
"name": "property-fileincluded-cancel"
},
"afterAbort": {
"baseName": "editor-write.bin",
"bytes": 34,
"editorMode": [],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Touched"
],
"pathExists": true,
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "72122705399a0111d36d7b74ec05f8155834ce6b394d1bd879f360e29f8bb365",
"statusString": "Touched",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/editor-write.bin",
"writeBits": 0
},
"before": {
"baseName": "editor-write.bin",
"bytes": 34,
"editorMode": [],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Up-to-date"
],
"pathExists": true,
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "72122705399a0111d36d7b74ec05f8155834ce6b394d1bd879f360e29f8bb365",
"statusString": "Valid",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/editor-write.bin",
"writeBits": 0
},
"edited": {
"baseName": "transaction-write.bin",
"bytes": 29,
"editorMode": [],
"exists": true,
"isDirectory": false,
"isFile": true,
"objectSet": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectState": [
"Touched"
],
"pathExists": true,
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "31f898b8e260a6dc642cf992483813de02d2cb9f4fe0f06be901d281f78f446e",
"statusString": "Touched",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/transaction-write.bin",
"writeBits": 0
},
"editedPath": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_67ad6239-27ce-4f6e-b55e-3f93c28f928f_da39a3_863229/transaction-write.bin",
"editedPathExistsAfterAbort": false,
"objectsAfter": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"objectsBefore": [
{
"name": "FileProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
],
"pendingAfterAbort": false,
"pendingAfterEdit": true,
"restored": true,
"undoMode": 1
}
}

View File

@@ -0,0 +1,924 @@
{
"schemaVersion": 1,
"status": "pass",
"baseline": {
"freecadVersion": "1.1.1",
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
},
"propertyType": "App::PropertyFileIncluded",
"recordCount": 20,
"objectTypeCount": 15,
"records": [
{
"objectTypeId": "App::DocumentObjectFileIncluded",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "File",
"group": "",
"status": [],
"normalizedStatus": [],
"defaultRaw": "",
"defaultKind": "empty",
"valueModel": {
"kind": "included-file-resource",
"representation": "read-only document-transient file backed by embedded FCStd bytes",
"writableByStatus": true,
"pathIsRuntimeOnly": true,
"bytesAreAuthoritative": true
},
"inputs": {
"accepted": [
"utf8-string-path",
"bytes-path",
"open-io-file",
"[source-path,archive-name]",
"{filename:string,filter?:string}"
],
"sourceFileMustExist": true,
"emptyStringBehavior": "accepted-no-op; does not clear an existing value",
"sameTransientPathBehavior": "rejected"
},
"dependency": null,
"editor": "Gui::PropertyEditor::PropertyTransientFileItem",
"applicability": {
"requiredObjectTypeId": "App::DocumentObjectFileIncluded",
"propertyWriteRequiresShape": false,
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "App::VRMLObject",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "VrmlFile",
"group": "",
"status": [],
"normalizedStatus": [],
"defaultRaw": "",
"defaultKind": "empty",
"valueModel": {
"kind": "included-file-resource",
"representation": "read-only document-transient file backed by embedded FCStd bytes",
"writableByStatus": true,
"pathIsRuntimeOnly": true,
"bytesAreAuthoritative": true
},
"inputs": {
"accepted": [
"utf8-string-path",
"bytes-path",
"open-io-file",
"[source-path,archive-name]",
"{filename:string,filter?:string}"
],
"sourceFileMustExist": true,
"emptyStringBehavior": "accepted-no-op; does not clear an existing value",
"sameTransientPathBehavior": "rejected"
},
"dependency": null,
"editor": "Gui::PropertyEditor::PropertyTransientFileItem",
"applicability": {
"requiredObjectTypeId": "App::VRMLObject",
"propertyWriteRequiresShape": false,
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "Image::ImagePlane",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "ImageFile",
"group": "ImagePlane",
"status": [],
"normalizedStatus": [],
"defaultRaw": "",
"defaultKind": "empty",
"valueModel": {
"kind": "included-file-resource",
"representation": "read-only document-transient file backed by embedded FCStd bytes",
"writableByStatus": true,
"pathIsRuntimeOnly": true,
"bytesAreAuthoritative": true
},
"inputs": {
"accepted": [
"utf8-string-path",
"bytes-path",
"open-io-file",
"[source-path,archive-name]",
"{filename:string,filter?:string}"
],
"sourceFileMustExist": true,
"emptyStringBehavior": "accepted-no-op; does not clear an existing value",
"sameTransientPathBehavior": "rejected"
},
"dependency": null,
"editor": "Gui::PropertyEditor::PropertyTransientFileItem",
"applicability": {
"requiredObjectTypeId": "Image::ImagePlane",
"propertyWriteRequiresShape": false,
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "Robot::RobotObject",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "RobotKinematicFile",
"group": "Robot definition",
"status": [],
"normalizedStatus": [],
"defaultRaw": "",
"defaultKind": "empty",
"valueModel": {
"kind": "included-file-resource",
"representation": "read-only document-transient file backed by embedded FCStd bytes",
"writableByStatus": true,
"pathIsRuntimeOnly": true,
"bytesAreAuthoritative": true
},
"inputs": {
"accepted": [
"utf8-string-path",
"bytes-path",
"open-io-file",
"[source-path,archive-name]",
"{filename:string,filter?:string}"
],
"sourceFileMustExist": true,
"emptyStringBehavior": "accepted-no-op; does not clear an existing value",
"sameTransientPathBehavior": "rejected"
},
"dependency": null,
"editor": "Gui::PropertyEditor::PropertyTransientFileItem",
"applicability": {
"requiredObjectTypeId": "Robot::RobotObject",
"propertyWriteRequiresShape": false,
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "Robot::RobotObject",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "RobotVrmlFile",
"group": "Robot definition",
"status": [],
"normalizedStatus": [],
"defaultRaw": "",
"defaultKind": "empty",
"valueModel": {
"kind": "included-file-resource",
"representation": "read-only document-transient file backed by embedded FCStd bytes",
"writableByStatus": true,
"pathIsRuntimeOnly": true,
"bytesAreAuthoritative": true
},
"inputs": {
"accepted": [
"utf8-string-path",
"bytes-path",
"open-io-file",
"[source-path,archive-name]",
"{filename:string,filter?:string}"
],
"sourceFileMustExist": true,
"emptyStringBehavior": "accepted-no-op; does not clear an existing value",
"sameTransientPathBehavior": "rejected"
},
"dependency": null,
"editor": "Gui::PropertyEditor::PropertyTransientFileItem",
"applicability": {
"requiredObjectTypeId": "Robot::RobotObject",
"propertyWriteRequiresShape": false,
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "Sketcher::SketchObjectSF",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "SketchFlatFile",
"group": "",
"status": [],
"normalizedStatus": [],
"defaultRaw": "",
"defaultKind": "empty",
"valueModel": {
"kind": "included-file-resource",
"representation": "read-only document-transient file backed by embedded FCStd bytes",
"writableByStatus": true,
"pathIsRuntimeOnly": true,
"bytesAreAuthoritative": true
},
"inputs": {
"accepted": [
"utf8-string-path",
"bytes-path",
"open-io-file",
"[source-path,archive-name]",
"{filename:string,filter?:string}"
],
"sourceFileMustExist": true,
"emptyStringBehavior": "accepted-no-op; does not clear an existing value",
"sameTransientPathBehavior": "rejected"
},
"dependency": null,
"editor": "Gui::PropertyEditor::PropertyTransientFileItem",
"applicability": {
"requiredObjectTypeId": "Sketcher::SketchObjectSF",
"propertyWriteRequiresShape": false,
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "TechDraw::DrawComplexSection",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "PatIncluded",
"group": "Cut Surface Format",
"status": [
"ReadOnly"
],
"normalizedStatus": [
"ReadOnly"
],
"defaultRaw": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_<uuid>_da39a3_<run>/FCPAT.pat",
"defaultKind": "document-transient-copy",
"valueModel": {
"kind": "included-file-resource",
"representation": "read-only document-transient file backed by embedded FCStd bytes",
"writableByStatus": false,
"pathIsRuntimeOnly": true,
"bytesAreAuthoritative": true
},
"inputs": {
"accepted": [
"utf8-string-path",
"bytes-path",
"open-io-file",
"[source-path,archive-name]",
"{filename:string,filter?:string}"
],
"sourceFileMustExist": true,
"emptyStringBehavior": "accepted-no-op; does not clear an existing value",
"sameTransientPathBehavior": "rejected"
},
"dependency": {
"sourceProperty": "FileGeomPattern",
"relation": "host-onChanged-copies-source-bytes-into-included-property"
},
"editor": "Gui::PropertyEditor::PropertyTransientFileItem",
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawComplexSection",
"propertyWriteRequiresShape": false,
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "TechDraw::DrawComplexSection",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "SvgIncluded",
"group": "Cut Surface Format",
"status": [
"ReadOnly"
],
"normalizedStatus": [
"ReadOnly"
],
"defaultRaw": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_<uuid>_da39a3_<run>/simple.svg",
"defaultKind": "document-transient-copy",
"valueModel": {
"kind": "included-file-resource",
"representation": "read-only document-transient file backed by embedded FCStd bytes",
"writableByStatus": false,
"pathIsRuntimeOnly": true,
"bytesAreAuthoritative": true
},
"inputs": {
"accepted": [
"utf8-string-path",
"bytes-path",
"open-io-file",
"[source-path,archive-name]",
"{filename:string,filter?:string}"
],
"sourceFileMustExist": true,
"emptyStringBehavior": "accepted-no-op; does not clear an existing value",
"sameTransientPathBehavior": "rejected"
},
"dependency": {
"sourceProperty": "FileHatchPattern",
"relation": "host-onChanged-copies-source-bytes-into-included-property"
},
"editor": "Gui::PropertyEditor::PropertyTransientFileItem",
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawComplexSection",
"propertyWriteRequiresShape": false,
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "TechDraw::DrawComplexSectionPython",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "PatIncluded",
"group": "Cut Surface Format",
"status": [
"ReadOnly"
],
"normalizedStatus": [
"ReadOnly"
],
"defaultRaw": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_<uuid>_da39a3_<run>/FCPAT1.pat",
"defaultKind": "document-transient-copy",
"valueModel": {
"kind": "included-file-resource",
"representation": "read-only document-transient file backed by embedded FCStd bytes",
"writableByStatus": false,
"pathIsRuntimeOnly": true,
"bytesAreAuthoritative": true
},
"inputs": {
"accepted": [
"utf8-string-path",
"bytes-path",
"open-io-file",
"[source-path,archive-name]",
"{filename:string,filter?:string}"
],
"sourceFileMustExist": true,
"emptyStringBehavior": "accepted-no-op; does not clear an existing value",
"sameTransientPathBehavior": "rejected"
},
"dependency": {
"sourceProperty": "FileGeomPattern",
"relation": "host-onChanged-copies-source-bytes-into-included-property"
},
"editor": "Gui::PropertyEditor::PropertyTransientFileItem",
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawComplexSectionPython",
"propertyWriteRequiresShape": false,
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "TechDraw::DrawComplexSectionPython",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "SvgIncluded",
"group": "Cut Surface Format",
"status": [
"ReadOnly"
],
"normalizedStatus": [
"ReadOnly"
],
"defaultRaw": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_<uuid>_da39a3_<run>/simple1.svg",
"defaultKind": "document-transient-copy",
"valueModel": {
"kind": "included-file-resource",
"representation": "read-only document-transient file backed by embedded FCStd bytes",
"writableByStatus": false,
"pathIsRuntimeOnly": true,
"bytesAreAuthoritative": true
},
"inputs": {
"accepted": [
"utf8-string-path",
"bytes-path",
"open-io-file",
"[source-path,archive-name]",
"{filename:string,filter?:string}"
],
"sourceFileMustExist": true,
"emptyStringBehavior": "accepted-no-op; does not clear an existing value",
"sameTransientPathBehavior": "rejected"
},
"dependency": {
"sourceProperty": "FileHatchPattern",
"relation": "host-onChanged-copies-source-bytes-into-included-property"
},
"editor": "Gui::PropertyEditor::PropertyTransientFileItem",
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawComplexSectionPython",
"propertyWriteRequiresShape": false,
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "TechDraw::DrawGeomHatch",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "PatIncluded",
"group": "GeomHatch",
"status": [],
"normalizedStatus": [],
"defaultRaw": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_<uuid>_da39a3_<run>/FCPAT2.pat",
"defaultKind": "document-transient-copy",
"valueModel": {
"kind": "included-file-resource",
"representation": "read-only document-transient file backed by embedded FCStd bytes",
"writableByStatus": true,
"pathIsRuntimeOnly": true,
"bytesAreAuthoritative": true
},
"inputs": {
"accepted": [
"utf8-string-path",
"bytes-path",
"open-io-file",
"[source-path,archive-name]",
"{filename:string,filter?:string}"
],
"sourceFileMustExist": true,
"emptyStringBehavior": "accepted-no-op; does not clear an existing value",
"sameTransientPathBehavior": "rejected"
},
"dependency": {
"sourceProperty": "FilePattern",
"relation": "host-onChanged-copies-source-bytes-into-included-property"
},
"editor": "Gui::PropertyEditor::PropertyTransientFileItem",
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawGeomHatch",
"propertyWriteRequiresShape": false,
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "TechDraw::DrawHatch",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "SvgIncluded",
"group": "Hatch",
"status": [],
"normalizedStatus": [],
"defaultRaw": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_<uuid>_da39a3_<run>/simple2.svg",
"defaultKind": "document-transient-copy",
"valueModel": {
"kind": "included-file-resource",
"representation": "read-only document-transient file backed by embedded FCStd bytes",
"writableByStatus": true,
"pathIsRuntimeOnly": true,
"bytesAreAuthoritative": true
},
"inputs": {
"accepted": [
"utf8-string-path",
"bytes-path",
"open-io-file",
"[source-path,archive-name]",
"{filename:string,filter?:string}"
],
"sourceFileMustExist": true,
"emptyStringBehavior": "accepted-no-op; does not clear an existing value",
"sameTransientPathBehavior": "rejected"
},
"dependency": {
"sourceProperty": "HatchPattern",
"relation": "host-onChanged-copies-source-bytes-into-included-property"
},
"editor": "Gui::PropertyEditor::PropertyTransientFileItem",
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawHatch",
"propertyWriteRequiresShape": false,
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "TechDraw::DrawSVGTemplate",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "PageResult",
"group": "Template",
"status": [
27
],
"normalizedStatus": [
"PropOutput"
],
"defaultRaw": "",
"defaultKind": "empty",
"valueModel": {
"kind": "included-file-resource",
"representation": "read-only document-transient file backed by embedded FCStd bytes",
"writableByStatus": false,
"pathIsRuntimeOnly": true,
"bytesAreAuthoritative": true
},
"inputs": {
"accepted": [
"utf8-string-path",
"bytes-path",
"open-io-file",
"[source-path,archive-name]",
"{filename:string,filter?:string}"
],
"sourceFileMustExist": true,
"emptyStringBehavior": "accepted-no-op; does not clear an existing value",
"sameTransientPathBehavior": "rejected"
},
"dependency": {
"sourceProperty": "Template",
"relation": "host-onChanged-copies-source-bytes-into-included-property"
},
"editor": "Gui::PropertyEditor::PropertyTransientFileItem",
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawSVGTemplate",
"propertyWriteRequiresShape": false,
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "TechDraw::DrawTileWeld",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "SymbolIncluded",
"group": "TileWeld",
"status": [],
"normalizedStatus": [],
"defaultRaw": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_<uuid>_da39a3_<run>/blankTile.svg",
"defaultKind": "document-transient-copy",
"valueModel": {
"kind": "included-file-resource",
"representation": "read-only document-transient file backed by embedded FCStd bytes",
"writableByStatus": true,
"pathIsRuntimeOnly": true,
"bytesAreAuthoritative": true
},
"inputs": {
"accepted": [
"utf8-string-path",
"bytes-path",
"open-io-file",
"[source-path,archive-name]",
"{filename:string,filter?:string}"
],
"sourceFileMustExist": true,
"emptyStringBehavior": "accepted-no-op; does not clear an existing value",
"sameTransientPathBehavior": "rejected"
},
"dependency": {
"sourceProperty": "SymbolFile",
"relation": "host-onChanged-copies-source-bytes-into-included-property"
},
"editor": "Gui::PropertyEditor::PropertyTransientFileItem",
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawTileWeld",
"propertyWriteRequiresShape": false,
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "TechDraw::DrawTileWeldPython",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "SymbolIncluded",
"group": "TileWeld",
"status": [],
"normalizedStatus": [],
"defaultRaw": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_<uuid>_da39a3_<run>/blankTile1.svg",
"defaultKind": "document-transient-copy",
"valueModel": {
"kind": "included-file-resource",
"representation": "read-only document-transient file backed by embedded FCStd bytes",
"writableByStatus": true,
"pathIsRuntimeOnly": true,
"bytesAreAuthoritative": true
},
"inputs": {
"accepted": [
"utf8-string-path",
"bytes-path",
"open-io-file",
"[source-path,archive-name]",
"{filename:string,filter?:string}"
],
"sourceFileMustExist": true,
"emptyStringBehavior": "accepted-no-op; does not clear an existing value",
"sameTransientPathBehavior": "rejected"
},
"dependency": {
"sourceProperty": "SymbolFile",
"relation": "host-onChanged-copies-source-bytes-into-included-property"
},
"editor": "Gui::PropertyEditor::PropertyTransientFileItem",
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawTileWeldPython",
"propertyWriteRequiresShape": false,
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "TechDraw::DrawViewImage",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "ImageIncluded",
"group": "Image",
"status": [],
"normalizedStatus": [],
"defaultRaw": "",
"defaultKind": "empty",
"valueModel": {
"kind": "included-file-resource",
"representation": "read-only document-transient file backed by embedded FCStd bytes",
"writableByStatus": true,
"pathIsRuntimeOnly": true,
"bytesAreAuthoritative": true
},
"inputs": {
"accepted": [
"utf8-string-path",
"bytes-path",
"open-io-file",
"[source-path,archive-name]",
"{filename:string,filter?:string}"
],
"sourceFileMustExist": true,
"emptyStringBehavior": "accepted-no-op; does not clear an existing value",
"sameTransientPathBehavior": "rejected"
},
"dependency": {
"sourceProperty": "ImageFile",
"relation": "host-onChanged-copies-source-bytes-into-included-property"
},
"editor": "Gui::PropertyEditor::PropertyTransientFileItem",
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawViewImage",
"propertyWriteRequiresShape": false,
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "TechDraw::DrawViewSection",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "PatIncluded",
"group": "Cut Surface Format",
"status": [
"ReadOnly"
],
"normalizedStatus": [
"ReadOnly"
],
"defaultRaw": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_<uuid>_da39a3_<run>/FCPAT3.pat",
"defaultKind": "document-transient-copy",
"valueModel": {
"kind": "included-file-resource",
"representation": "read-only document-transient file backed by embedded FCStd bytes",
"writableByStatus": false,
"pathIsRuntimeOnly": true,
"bytesAreAuthoritative": true
},
"inputs": {
"accepted": [
"utf8-string-path",
"bytes-path",
"open-io-file",
"[source-path,archive-name]",
"{filename:string,filter?:string}"
],
"sourceFileMustExist": true,
"emptyStringBehavior": "accepted-no-op; does not clear an existing value",
"sameTransientPathBehavior": "rejected"
},
"dependency": {
"sourceProperty": "FileGeomPattern",
"relation": "host-onChanged-copies-source-bytes-into-included-property"
},
"editor": "Gui::PropertyEditor::PropertyTransientFileItem",
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawViewSection",
"propertyWriteRequiresShape": false,
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "TechDraw::DrawViewSection",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "SvgIncluded",
"group": "Cut Surface Format",
"status": [
"ReadOnly"
],
"normalizedStatus": [
"ReadOnly"
],
"defaultRaw": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_<uuid>_da39a3_<run>/simple3.svg",
"defaultKind": "document-transient-copy",
"valueModel": {
"kind": "included-file-resource",
"representation": "read-only document-transient file backed by embedded FCStd bytes",
"writableByStatus": false,
"pathIsRuntimeOnly": true,
"bytesAreAuthoritative": true
},
"inputs": {
"accepted": [
"utf8-string-path",
"bytes-path",
"open-io-file",
"[source-path,archive-name]",
"{filename:string,filter?:string}"
],
"sourceFileMustExist": true,
"emptyStringBehavior": "accepted-no-op; does not clear an existing value",
"sameTransientPathBehavior": "rejected"
},
"dependency": {
"sourceProperty": "FileHatchPattern",
"relation": "host-onChanged-copies-source-bytes-into-included-property"
},
"editor": "Gui::PropertyEditor::PropertyTransientFileItem",
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawViewSection",
"propertyWriteRequiresShape": false,
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "TechDraw::DrawViewSectionPython",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "PatIncluded",
"group": "Cut Surface Format",
"status": [
"ReadOnly"
],
"normalizedStatus": [
"ReadOnly"
],
"defaultRaw": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_<uuid>_da39a3_<run>/FCPAT4.pat",
"defaultKind": "document-transient-copy",
"valueModel": {
"kind": "included-file-resource",
"representation": "read-only document-transient file backed by embedded FCStd bytes",
"writableByStatus": false,
"pathIsRuntimeOnly": true,
"bytesAreAuthoritative": true
},
"inputs": {
"accepted": [
"utf8-string-path",
"bytes-path",
"open-io-file",
"[source-path,archive-name]",
"{filename:string,filter?:string}"
],
"sourceFileMustExist": true,
"emptyStringBehavior": "accepted-no-op; does not clear an existing value",
"sameTransientPathBehavior": "rejected"
},
"dependency": {
"sourceProperty": "FileGeomPattern",
"relation": "host-onChanged-copies-source-bytes-into-included-property"
},
"editor": "Gui::PropertyEditor::PropertyTransientFileItem",
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawViewSectionPython",
"propertyWriteRequiresShape": false,
"source": "Document.supportedTypes runtime inventory"
}
},
{
"objectTypeId": "TechDraw::DrawViewSectionPython",
"objectAvailable": true,
"probeStatus": "available",
"propertyName": "SvgIncluded",
"group": "Cut Surface Format",
"status": [
"ReadOnly"
],
"normalizedStatus": [
"ReadOnly"
],
"defaultRaw": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_<uuid>_da39a3_<run>/simple4.svg",
"defaultKind": "document-transient-copy",
"valueModel": {
"kind": "included-file-resource",
"representation": "read-only document-transient file backed by embedded FCStd bytes",
"writableByStatus": false,
"pathIsRuntimeOnly": true,
"bytesAreAuthoritative": true
},
"inputs": {
"accepted": [
"utf8-string-path",
"bytes-path",
"open-io-file",
"[source-path,archive-name]",
"{filename:string,filter?:string}"
],
"sourceFileMustExist": true,
"emptyStringBehavior": "accepted-no-op; does not clear an existing value",
"sameTransientPathBehavior": "rejected"
},
"dependency": {
"sourceProperty": "FileHatchPattern",
"relation": "host-onChanged-copies-source-bytes-into-included-property"
},
"editor": "Gui::PropertyEditor::PropertyTransientFileItem",
"applicability": {
"requiredObjectTypeId": "TechDraw::DrawViewSectionPython",
"propertyWriteRequiresShape": false,
"source": "Document.supportedTypes runtime inventory"
}
}
],
"setterSemantics": {
"externalSource": "copy bytes into the document transient directory",
"writableTransientSource": "rename into the selected transient destination",
"replacement": "delete the previous transient copy unless undo owns it",
"destinationPermissions": "read-only",
"archiveNameCollision": "append a positive integer before the extension",
"undoRedo": "Copy/Paste move or copy transient files while preserving per-property ownership"
},
"storage": {
"xmlElement": "FileIncluded",
"archiveAttribute": "file",
"archiveResource": "separate FCStd ZIP entry containing byte-identical file data",
"forceXmlAttribute": "data",
"forceXmlResource": "binary data embedded in the XML stream",
"emptyEncoding": "<FileIncluded file=\"\"/>",
"restoredValue": "document transient path; not a portable semantic path",
"browserBoundary": "project resource identity plus bytes; never expose or persist an ambient host path"
},
"provenance": {
"runtime": {
"path": ".cache/freecad/reference-desktop.json",
"bytes": 2298709,
"sha256": "082400ec7379e8efc2af16709032d45890d7092277967b714acb05761fd1c2a7"
},
"sources": [
{
"path": ".cache/freecad/FreeCAD/src/App/PropertyFile.h",
"bytes": 5474,
"sha256": "1e5d3fea7bebde48fafccbaf9edca92cdc9b727ccaaa74a50b70929a1fe02412"
},
{
"path": ".cache/freecad/FreeCAD/src/App/PropertyFile.cpp",
"bytes": 22084,
"sha256": "ee1b7a3a675d93b3beaca52ce819201e9d240c99e6eb08b391bd81e076ac21fe"
},
{
"path": ".cache/freecad/FreeCAD/src/Gui/propertyeditor/PropertyItem.h",
"bytes": 41826,
"sha256": "aaade89f5386b5d061b1b2d09a4fd01e7a27e3c601117fc00e44e115f347d9ed"
},
{
"path": ".cache/freecad/FreeCAD/src/Gui/propertyeditor/PropertyItem.cpp",
"bytes": 142093,
"sha256": "bf2f7cb4c01034425f4ebd46f901ada03c5fa02dcffbc1d3936e49ef7bc43b52"
},
{
"path": ".cache/freecad/FreeCAD/src/App/DocumentObjectFileIncluded.cpp",
"bytes": 2128,
"sha256": "0b8b27fd92ef1c722191fc512573de0875e637191b957167c7e17ada11b95bb1"
},
{
"path": ".cache/freecad/FreeCAD/src/Mod/TechDraw/App/DrawViewSection.cpp",
"bytes": 47842,
"sha256": "86c68dfa3fea97ed3f79e119f2f488726c6ea82bf6198de935e36383c444829f"
},
{
"path": ".cache/freecad/FreeCAD/src/Mod/TechDraw/App/DrawGeomHatch.cpp",
"bytes": 22708,
"sha256": "c8a653c85986b05414965424f0c88e4af1c6af41980eac3c483fc8bb6de763f2"
},
{
"path": ".cache/freecad/FreeCAD/src/Mod/TechDraw/App/DrawHatch.cpp",
"bytes": 7966,
"sha256": "ad242fbc5eb7cc4fa0f30fc9db71a549d841ea73680e6d8c7ff2909699c59fa0"
},
{
"path": ".cache/freecad/FreeCAD/src/Mod/TechDraw/App/DrawSVGTemplate.cpp",
"bytes": 13492,
"sha256": "8355e597863dcabf9ad996a3e9097988ac8ceba9b6f4635029d33f59b2a019de"
},
{
"path": ".cache/freecad/FreeCAD/src/Mod/TechDraw/App/DrawTileWeld.cpp",
"bytes": 4878,
"sha256": "c31f2ec3b244b421b39ff283c687540c4e783361f9dfb2a9ae3b3045ef30463b"
},
{
"path": ".cache/freecad/FreeCAD/src/Mod/TechDraw/App/DrawViewImage.cpp",
"bytes": 4670,
"sha256": "e76a2f5aacd374b63b21cbe37136027ee041a28b59106cdfa78fd5ecbcb2707e"
}
]
},
"classification": "opaque-fcstd-proxy",
"nextPhases": [
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I"
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,76 @@
{
"schemaVersion": 1,
"status": "pass",
"taskId": "PROP-app-propertyfileincluded-I",
"baseline": {
"freecadVersion": "1.1.1",
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
},
"propertyType": "App::PropertyFileIncluded",
"recordCount": 20,
"phaseEvidence": {
"A": [
"config/freecad-property-fileincluded-inventory.json",
"check:freecad-property-fileincluded-inventory"
],
"B": [
"config/freecad-property-fileincluded-success.json",
"check:freecad-property-fileincluded-success"
],
"C": [
"config/freecad-property-fileincluded-failure.json",
"check:freecad-property-fileincluded-failure"
],
"D": [
"config/freecad-property-fileincluded-mutation.json",
"check:freecad-property-fileincluded-mutation"
],
"E": [
"src/facade/includedFile.ts",
"src/facade/types.ts",
"src/facade/fcstd.ts",
"src/facade/mockFacade.ts",
"src/App.tsx",
"tests/propertyFileIncludedFacade.test.ts",
"test:freecad-property-fileincluded-facade"
],
"F": [
"tests/propertyFileIncludedTransaction.test.ts",
"test:freecad-property-fileincluded-transaction"
],
"G": [
"config/freecad-property-fileincluded-roundtrip.json",
"check:freecad-property-fileincluded-roundtrip"
],
"H": [
"config/chrome-property-fileincluded-verification.json",
"check:chrome-property-fileincluded"
]
},
"promotion": {
"from": "opaque-fcstd-proxy",
"to": "native-editable-codec",
"facadeValueModel": "project-resource-identity-and-authoritative-bytes-with-native-fileincluded-fcstd-resource",
"writableRecords": 11,
"readOnlyRecords": 8,
"outputRecords": 1,
"objectTypeCount": 15,
"fcstdElement": "FileIncluded",
"nativeArchiveName": "payload.bin",
"nativeRoundTripSha256": "09f4e4853de4277e25871d26f2e953c6ea9c13a73c7a01bdfcb5209d17f9a583",
"browserArchiveName": "chrome-resource.bin",
"browserRoundTripBytes": 16,
"externalResourceBoundary": "embedded FCStd ZIP entry restored to a read-only document transient file",
"zeroUnknownDrift": true
},
"exactBlockerSync": {
"nativeEditableTypes": 30,
"nativeEditableRecords": 4361,
"opaqueTypes": 50,
"opaqueRecords": 466,
"exactPromotionReady": false,
"exactBlocker": "50 runtime property types and 466 records remain opaque-only; complete native document and property semantics"
},
"systemExact": false,
"generatedAt": "2026-08-17T08:49:33.815Z"
}

View File

@@ -0,0 +1,187 @@
{
"schemaVersion": 1,
"status": "pass",
"baselineId": "freecad-1.1.1-property-fileincluded-roundtrip",
"freecadVersion": "1.1.1",
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
"propertyType": "App::PropertyFileIncluded",
"assets": {
"initial": {
"path": ".cache/freecad/property-fileincluded-roundtrip/initial.bin",
"bytes": 13,
"sha256": "974b81bb5869530635082c3c33edafbc4aad32b11ac01031432d0ae657be1336"
},
"target": {
"path": ".cache/freecad/property-fileincluded-roundtrip/target.bin",
"bytes": 20,
"sha256": "09f4e4853de4277e25871d26f2e953c6ea9c13a73c7a01bdfcb5209d17f9a583"
}
},
"archives": {
"nativeInitial": {
"path": ".cache/freecad/property-fileincluded-roundtrip/native-initial.FCStd",
"bytes": 1357,
"sha256": "5f6f0be7bb04019652c5e43c3398604f0ce6f72782e027158f3b4b6acac4af4e"
},
"webEdited": {
"path": ".cache/freecad/property-fileincluded-roundtrip/web-edited.FCStd",
"bytes": 1206,
"sha256": "b826b63e1f4807fd8914c2e51098d544544e79a6efc3a1b14e522d9965f49790"
},
"nativeResaved": {
"path": ".cache/freecad/property-fileincluded-roundtrip/native-resaved.FCStd",
"bytes": 1364,
"sha256": "2e1a5836ab2404ec59d344ebdc45cf4c81ee6887402e5ae1548ce4ca7e7f477e"
}
},
"nativeInitial": {
"object": {
"baseName": "payload.bin",
"bytes": 13,
"editorMode": [],
"exists": true,
"hasShapeProperty": false,
"mode": 256,
"name": "IncludedProbe",
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "974b81bb5869530635082c3c33edafbc4aad32b11ac01031432d0ae657be1336",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"typeId": "App::DocumentObjectFileIncluded",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_9dbdcbfb-2e87-49ea-9bf0-99bb6c6f3833_f49955_361283/payload.bin",
"writeBits": 0
},
"objectSet": [
{
"name": "IncludedProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
]
},
"web": {
"before": {
"name": "File",
"typeId": "App::PropertyFileIncluded",
"element": "FileIncluded",
"value": "{\"path\":\"payload.bin\",\"mediaType\":\"application/octet-stream\",\"byteLength\":13,\"contentHash\":\"aefb8d38\",\"status\":\"available\"}",
"resourcePath": "payload.bin",
"includedFileResource": {
"path": "payload.bin",
"mediaType": "application/octet-stream",
"byteLength": 13,
"contentHash": "aefb8d38",
"status": "available"
}
},
"after": {
"name": "File",
"typeId": "App::PropertyFileIncluded",
"element": "FileIncluded",
"value": "{\"path\":\"payload.bin\",\"mediaType\":\"application/octet-stream\",\"byteLength\":20,\"contentHash\":\"2a7d5998\",\"status\":\"available\"}",
"resourcePath": "payload.bin",
"includedFileResource": {
"path": "payload.bin",
"mediaType": "application/octet-stream",
"byteLength": 20,
"contentHash": "2a7d5998",
"status": "available"
}
},
"resource": {
"path": "payload.bin",
"pathPreserved": true,
"beforeBytes": 13,
"afterBytes": 20,
"beforeSha256": "974b81bb5869530635082c3c33edafbc4aad32b11ac01031432d0ae657be1336",
"afterSha256": "09f4e4853de4277e25871d26f2e953c6ea9c13a73c7a01bdfcb5209d17f9a583",
"changed": true
},
"targetMarkedTouched": true,
"webOutputMatches": true,
"semanticObjectsPreserved": true,
"opaquePathsPreserved": 0,
"opaqueEntriesPreserved": true
},
"nativeAfter": {
"reopened": {
"object": {
"baseName": "payload.bin",
"bytes": 20,
"editorMode": [],
"exists": true,
"hasShapeProperty": false,
"mode": 256,
"name": "IncludedProbe",
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "09f4e4853de4277e25871d26f2e953c6ea9c13a73c7a01bdfcb5209d17f9a583",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"typeId": "App::DocumentObjectFileIncluded",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_9dbdcbfb-2e87-49ea-9bf0-99bb6c6f3833_037685_844069/payload.bin",
"writeBits": 0
},
"objectSet": [
{
"name": "IncludedProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
]
},
"resaved": {
"object": {
"baseName": "payload.bin",
"bytes": 20,
"editorMode": [],
"exists": true,
"hasShapeProperty": false,
"mode": 256,
"name": "IncludedProbe",
"propertyStatus": [],
"propertyTypeId": "App::PropertyFileIncluded",
"sha256": "09f4e4853de4277e25871d26f2e953c6ea9c13a73c7a01bdfcb5209d17f9a583",
"state": [
"Up-to-date"
],
"statusString": "Valid",
"typeId": "App::DocumentObjectFileIncluded",
"underTransientDir": true,
"value": "/home/mes123456/.cache/FreeCAD/v1-1/Cache/FreeCAD_Doc_9dbdcbfb-2e87-49ea-9bf0-99bb6c6f3833_35b665_844069/payload.bin",
"writeBits": 0
},
"objectSet": [
{
"name": "IncludedProbe",
"typeId": "App::DocumentObjectFileIncluded"
}
]
}
},
"nativeResavedResource": {
"path": "payload.bin",
"mediaType": "application/octet-stream",
"byteLength": 20,
"contentHash": "2a7d5998",
"status": "available"
},
"classification": {
"archiveName": "payload.bin",
"initialSha256": "974b81bb5869530635082c3c33edafbc4aad32b11ac01031432d0ae657be1336",
"targetSha256": "09f4e4853de4277e25871d26f2e953c6ea9c13a73c7a01bdfcb5209d17f9a583",
"reopenedSha256": "09f4e4853de4277e25871d26f2e953c6ea9c13a73c7a01bdfcb5209d17f9a583",
"resavedSha256": "09f4e4853de4277e25871d26f2e953c6ea9c13a73c7a01bdfcb5209d17f9a583",
"nativeOutputMatches": true,
"objectSetPreserved": true,
"resavedResourceMatches": true,
"externalResourceBoundary": "embedded FCStd ZIP entry restored to a read-only document transient file",
"unknownSemanticDrift": false,
"zeroUnknownDrift": true
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -41,7 +41,7 @@
"id": "EX03",
"title": "Application document, property and recompute semantics",
"tasks": [
{ "id": "EX-DOC-01", "title": "Implement every native property type, flag, editor and serialization rule", "priority": "P0", "status": "in_progress", "dependencies": ["EX-ORA-01"], "deliverables": ["Complete Property schema", "Status and editor metadata", "Binary and XML codecs"], "acceptance": ["Every runtime property fixture round-trips without type coercion or unknown loss"], "evidence": ["check:freecad-type-properties", "check:freecad-native-property-semantics", "check:freecad-property-status", "check:freecad-fcstd-roundtrip"], "exactBlockedBy": ["Of 85 runtime property types and 5510 records, 58 types/523 records remain opaque-only; all 15 observed status classes now have typed Facade behavior, including LockDynamic dynamic mutation and PartialTrigger partial-document observer transactions, but the remaining codecs, editors and complete document observer semantics are not closed"] },
{ "id": "EX-DOC-01", "title": "Implement every native property type, flag, editor and serialization rule", "priority": "P0", "status": "in_progress", "dependencies": ["EX-ORA-01"], "deliverables": ["Complete Property schema", "Status and editor metadata", "Binary and XML codecs"], "acceptance": ["Every runtime property fixture round-trips without type coercion or unknown loss"], "evidence": ["check:freecad-type-properties", "check:freecad-native-property-semantics", "check:freecad-property-status", "check:freecad-fcstd-roundtrip"], "exactBlockedBy": ["Of 85 runtime property types and 5510 records, 50 types/466 records remain opaque-only; all 15 observed status classes now have typed Facade behavior, including LockDynamic dynamic mutation and PartialTrigger partial-document observer transactions, but the remaining codecs, editors and complete document observer semantics are not closed"] },
{ "id": "EX-DOC-02", "title": "Match transactions, DAG recompute, partial failure and document observers", "priority": "P0", "status": "in_progress", "dependencies": ["EX-DOC-01", "EX-TSN-04"], "deliverables": ["Transaction and observer event oracle", "Partial recompute scheduler", "Failure recovery contract"], "acceptance": ["Undo, redo, abort, stale and cyclic dependency behavior matches FreeCAD"], "evidence": ["check:document-closure", "test:facade"], "exactBlockedBy": ["Observer ordering and every partial-recompute branch are not yet oracle-backed"] },
{ "id": "EX-DOC-03", "title": "Complete expressions, links, extensions, groups and App object lifecycle", "priority": "P0", "status": "in_progress", "dependencies": ["EX-DOC-01"], "deliverables": ["Expression dependency grammar", "Link and extension lifecycle", "Group and clone semantics"], "acceptance": ["Copy, clone, delete, relink and expression edits survive native round-trip"], "evidence": ["check:fcstd-closure", "check:chrome-production-document"], "exactBlockedBy": ["FeaturePython-backed extensions remain non-executable"] },
{ "id": "EX-DOC-04", "title": "Complete multi-document, external link, merge and recovery workflows", "priority": "P1", "status": "pending", "dependencies": ["EX-DOC-02", "EX-DOC-03"], "deliverables": ["Cross-document Link corpus", "Merge and conflict semantics", "Crash and autosave recovery"], "acceptance": ["Open, close, relink, merge and recovery match the native document graph"], "evidence": ["check:chrome-persistence", "check:project-migration"], "exactBlockedBy": ["Current application is project-first and does not implement every desktop multi-document workflow"] },
@@ -63,7 +63,7 @@
"id": "EX05",
"title": "FCStd and all import/export entrypoints",
"tasks": [
{ "id": "EX-FC-01", "title": "Round-trip every native FCStd object, property, extension and resource", "priority": "P0", "status": "in_progress", "dependencies": ["EX-DOC-04", "EX-TSN-04"], "deliverables": ["Complete native archive model", "Unknown object preservation", "FreeCAD-Web-FreeCAD mutation corpus"], "acceptance": ["No supported object, property, GUI state or resource drifts after mutation and resave"], "evidence": ["check:freecad-native-property-semantics", "check:freecad-isomorphic-provenance", "check:fcstd-closure", "check:chrome-fcstd-roundtrip"], "exactBlockedBy": ["FCStd supports 23 native property codecs plus opaque preservation for 62 runtime types; exhaustive native mutation and resave remains open"] },
{ "id": "EX-FC-01", "title": "Round-trip every native FCStd object, property, extension and resource", "priority": "P0", "status": "in_progress", "dependencies": ["EX-DOC-04", "EX-TSN-04"], "deliverables": ["Complete native archive model", "Unknown object preservation", "FreeCAD-Web-FreeCAD mutation corpus"], "acceptance": ["No supported object, property, GUI state or resource drifts after mutation and resave"], "evidence": ["check:freecad-native-property-semantics", "check:freecad-isomorphic-provenance", "check:fcstd-closure", "check:chrome-fcstd-roundtrip"], "exactBlockedBy": ["FCStd supports 35 native property codecs plus opaque preservation for 50 runtime types; exhaustive native mutation and resave remains open"] },
{ "id": "EX-FMT-01", "title": "Close BREP, STEP and IGES import/export semantics", "priority": "P0", "status": "in_progress", "dependencies": ["EX-KER-01"], "deliverables": ["Assembly/color/name import", "Unit and tolerance handling", "Deterministic exports"], "acceptance": ["Native and Web topology, metadata and diagnostics match for each format"] , "evidence": ["check:chrome-secondary-formats", "check:browser-occt"], "exactBlockedBy": ["Advanced STEP/IGES metadata and assembly cases are incomplete"] },
{ "id": "EX-FMT-02", "title": "Close STL, OBJ, PLY, DXF, SVG and PDF round-trips", "priority": "P1", "status": "in_progress", "dependencies": ["EX-MESH-01", "EX-DRAFT-01", "EX-TD-01"], "deliverables": ["Mesh and 2D format codecs", "Style/layer metadata", "Import-export failure corpus"], "acceptance": ["All supported entities and metadata round-trip or fail with a registered difference"] , "evidence": ["check:chrome-secondary-formats", "check:document-closure"], "exactBlockedBy": ["Several formats remain read-only or omit advanced entity metadata"] },
{ "id": "EX-FMT-03", "title": "Close IFC, CSV and G-code native object semantics", "priority": "P1", "status": "in_progress", "dependencies": ["EX-BIM-01", "EX-SS-01", "EX-CAM-01"], "deliverables": ["IFC schema and property sets", "Spreadsheet CSV dialect parity", "Path/G-code object round-trip"], "acceptance": ["Import, edit, export and native reopen preserve the declared object graph"] , "evidence": ["check:chrome-bim", "check:document-closure", "check:cam-parity"], "exactBlockedBy": ["IFC and G-code entrypoint inventory still records unsupported desktop semantics"] },

View File

@@ -24,7 +24,7 @@
"wrong-document-root": 77
},
"timing": {
"p95Ms": 0.131,
"maxMs": 2.695
"p95Ms": 0.13,
"maxMs": 2.66
}
}

View File

@@ -41,7 +41,7 @@
"zero-revolution-axis": 67
},
"timing": {
"p95Ms": 0.025,
"maxMs": 1.112
"p95Ms": 0.02,
"maxMs": 0.997
}
}

View File

@@ -22,7 +22,7 @@
"invalid": 800
},
"timing": {
"p95Ms": 0.033,
"maxMs": 0.795
"p95Ms": 0.03,
"maxMs": 0.659
}
}

View File

@@ -23,14 +23,14 @@
"sha256": "1679307fb0f01e9d7b9f37a081458bf44583e4d1899edf9224b49a1435ce7105"
},
{
"path": "assets/index-BnRqhr3m.css",
"bytes": 65976,
"sha256": "b8eacf86224d2705e3c27367b3a0b166f4d662a5b8142d34a8abcdeef58753ec"
"path": "assets/index-CNTlr1np.js",
"bytes": 1210736,
"sha256": "4d9e8b6e6e70a13d6a5c34a39eaa62a537de8cefde60d09125392b5a14512363"
},
{
"path": "assets/index-BrkUKPvE.js",
"bytes": 1143618,
"sha256": "4324ab6351a3ef214762115d5b5ffc706883ccaf1e9b0f90577f912da1e4a223"
"path": "assets/index-CSuKYsCZ.css",
"bytes": 67322,
"sha256": "32d3157ecf81272245f0d8aa1a11887cefb8aa9502f966df90a83797519df208"
},
{
"path": "assets/nativeHistoryWorkerEntry-BEDB1h7o.js",
@@ -335,7 +335,7 @@
{
"path": "index.html",
"bytes": 678,
"sha256": "e3cfab4e89c7bc19c51f2529bb2c6c84a61064168029a3bdfee2260a49a71097"
"sha256": "233c411801542bf802d4d701437c593620350c13fd1eec069c00d083b80a764d"
},
{
"path": "manifest.webmanifest",
@@ -390,7 +390,7 @@
{
"path": "sw.js",
"bytes": 1390,
"sha256": "98ec667a774f8370ed654e457b86d4943b2f1eb89e228bd4e7e652b31a51b982"
"sha256": "041bc2f315a15f659a5471f382af087e61a8c4405fd8a725c068ddf898e7386e"
},
{
"path": "vendor/camotics/camotics-sweep.wasm",
@@ -412,7 +412,7 @@
"status": "signed",
"algorithm": "Ed25519",
"keyId": "bitbybit-local-release-2026",
"payloadSha256": "5172b35d4d194483ac1934a1653259b1c7f5bb78c5ab4a68f7e5033cf2a22b86",
"signature": "FoaYFhliT+/njf8hXECKj5IoCeHPj1MnpbTBIw/FxzYpfyrgQ01nuPkwslM4okUk3d97cncjaXnEkDA7lZBtDw=="
"payloadSha256": "7cfc2e7f4b34be4c4b5deb75ace67753f9e219ef51b5be74f5a5c1d4f895f3cb",
"signature": "9fhwYyVCjTXXsQUvePx8I31qBp2FsW6b1YOW6UUtR2FDhrqwPtttqLrxSPcH6S88++u805jHATBE5cTijm4VBw=="
}
}

View File

@@ -81,7 +81,7 @@ EX-DOC-01 -> EX-DOC-03 ---------^
### P0-C关闭 App 文档语义
对应 `EX-DOC-01/02/03`。85 种运行时 Property、5510 条记录中,22 种/4304 条已有通用原生 codec5 种/683 条已有专用 codec仍有 58 种/523 条只能 opaque 保存。15 类已观察到的 Property status 均已进入类型化 Facade 行为;`LockDynamic` 的动态属性增删改事务和 `PartialTrigger` 的 partial-document observer 行为已有原生 oracle 与 Facade 测试。后续依次补齐剩余 Property codec/editor、完整 observer 顺序、局部重算失败、Extension 和 FeaturePython 边界。
对应 `EX-DOC-01/02/03`。85 种运行时 Property、5510 条记录中,30 种/4361 条已有通用原生 codec5 种/683 条已有专用 codec仍有 50 种/466 条只能 opaque 保存。15 类已观察到的 Property status 均已进入类型化 Facade 行为;`LockDynamic` 的动态属性增删改事务和 `PartialTrigger` 的 partial-document observer 行为已有原生 oracle 与 Facade 测试。后续依次补齐剩余 Property codec/editor、完整 observer 顺序、局部重算失败、Extension 和 FeaturePython 边界。
### P0-D关闭核心建模语义

View File

@@ -3,10 +3,10 @@
生成日期2026-08-15。基线FreeCAD 1.1.1 / `0108fd4b4850cc46e625b60e53cea7a7bbe69f8d`
- 唯一活动任务:`TSN-PAIR-chamfer-rotate`
- 微任务1756 total / 339 completed / 1 in_progress / 1416 pending
- 有序操作对:213/361 classified / 148 unknown
- Property27/85 native types / 58 opaque types
- 唯一活动任务:`PROP-app-propertyfont-A`
- 微任务1756 total / 559 completed / 1 in_progress / 1196 pending
- 有序操作对:361/361 classified / 0 unknown
- Property35/85 native types / 50 opaque types
- exact 任务5/52 completed
- 模块能力0 exact / 26 compatible / 5 proxy / 3 development
@@ -15,8 +15,8 @@
| `ORA-GUI-BASELINE` | 106 | 106 | 0 | 0 | `-` |
| `ORA-GUI-WORKFLOWS` | 7 | 7 | 0 | 0 | `-` |
| `TSN-RECOVERY-DRIFT` | 13 | 13 | 0 | 0 | `-` |
| `TSN-ORDERED-PAIRS` | 361 | 213 | 1 | 147 | `TSN-PAIR-chamfer-rotate` |
| `PROPERTY-CODECS` | 522 | 0 | 0 | 522 | `-` |
| `TSN-ORDERED-PAIRS` | 361 | 361 | 0 | 0 | `-` |
| `PROPERTY-CODECS` | 522 | 72 | 1 | 449 | `PROP-app-propertyfont-A` |
| `DOCUMENT-SEMANTICS` | 90 | 0 | 0 | 90 | `-` |
| `CORE-MODELING` | 171 | 0 | 0 | 171 | `-` |
| `FCSTD-AND-FORMATS` | 72 | 0 | 0 | 72 | `-` |

View File

@@ -0,0 +1,451 @@
# WEB FreeCAD 对真实 FreeCAD 差分实施计划
## 1. 文档职责
本文定义 WEB FreeCAD 如何通过真实执行逐项对标锁定版 FreeCAD并把发现、复现、纠正、回归和能力提升拆成可执行的最小任务。本文不维护实时完成数或下一任务名称动态状态只读取
1. `config/freecad-active-work-queue.json`:唯一 `nextTask`、依赖、状态和退出条件。
2. `docs/freecad-active-work-status.generated.zh-CN.md`:同一生成器产生的状态摘要。
3. `config/freecad-web-exact-parity-plan.json`:系统级 exact 任务和阻断项。
4. `config/release-capability-matrix.json`34 个模块可对外声明的能力等级。
5. `config/*oracle*.json``config/*verification*.json`:真实执行证据。
若文档描述与机器报告冲突以机器报告为准。界面相似、命令存在、OCCT 能生成相似 Shape、Node 单测通过,都不能单独证明与 FreeCAD 对标。
## 2. 对标目标和红线
目标基线固定为 FreeCAD `1.1.1`、Git 提交 `0108fd4b4850cc46e625b60e53cea7a7bbe69f8d`。WEB FreeCAD 必须在浏览器可实现范围内逐项匹配:
- 命令可见性、启用条件、上下文和失败诊断。
- 对象 TypeId、属性类型、默认值、状态位、editor 行为和生命周期。
- Document 对象图、依赖 DAG、recompute、事务、observer、Undo/Redo 和失败恢复。
- Shape 有效性、拓扑数量、质量属性、边界、公差、placement 和 builder 历史。
- Generated/Modified/Deleted、ElementMap2、MappedNameRef、StringHasher 和 LinkSub 稳定性。
- FCStd、BREP、STEP、IGES 及其他格式的读取、编辑、保存、重开和再次保存。
- GUI Task、对话框、选择、预选、焦点、模型树、属性面板、状态栏和长任务。
- Worker、WASM、OPFS、GPU、内存、取消、崩溃和资源释放。
以下行为一律禁止:
- 用手工 JSON、Mock、截图或静态源码推断替代真实 FreeCAD 执行。
- 用最终 Shape 相似掩盖中间 history、命名、事务或对象图差异。
- FreeCAD 原生拒绝时,为了增加 WEB 支持数而偷偷接受。
- 原生来源不唯一时按数组顺序、网格索引或最终拓扑位置伪造稳定名称。
- 未知 Property、Extension、资源或脚本被静默丢弃、重写或标记可编辑。
- UI 绕过 Facade 直接调用 OCCT、Three.js、OPFS、SQLite 或脚本执行器。
- 放宽断言、删除 fixture 或改写报告来让 exact promotion 通过。
## 3. 真实执行环境
### 3.1 锁定产物
| 运行面 | 固定入口 | 用途 | 必须锁定 |
| --- | --- | --- | --- |
| Headless FreeCAD | `.cache/freecad/install-native/bin/FreeCADCmd` | Part/几何、黄金场景、错误和文件回放 | 版本、提交、二进制 SHA-256、Python 驱动 SHA-256 |
| Desktop FreeCAD CLI | `.cache/freecad/install-desktop/bin/FreeCADCmd` | 34 模块对象、Property、PartDesign、命名、FCStd | sysroot、模块加载、隔离配置、二进制 SHA-256 |
| Desktop FreeCAD GUI | `.cache/freecad/install-desktop/bin/FreeCAD` | 命令、Task、QAction、焦点、选择、视图和工作台 | `xvfb-run`/显示环境、用户配置、locale、DPI |
| Bitbybit OCCT | `@bitbybit-dev/occt` 1.1.1 | Web 几何兼容路径 | npm 版本、WASM SHA-256、API surface |
| 原生 history provider | `native/occt-history/dist/*` | builder history、命名 ABI 和三方差分 | JS/WASM/data 哈希、OCCT 版本、导出 ABI |
| Web 浏览器 | Playwright 锁定浏览器 | Worker、WASM、OPFS、UI、GPU 和交互 | 浏览器版本、viewport、deviceScaleFactor、特性开关 |
### 3.2 环境隔离
每次原生执行必须:
1. 使用任务专属临时目录和独立 FreeCAD user/system config。
2. 固定 locale、时区、单位、线程和随机种子无法固定的字段进入显式归一化清单。
3. 禁止读取用户真实 FreeCAD 配置、最近文件、插件目录和自动恢复文件。
4. GUI 探针在虚拟显示中运行记录分辨率、DPI、主题、字体和窗口状态。
5. 运行前记录二进制、harness、fixture 和输入资源 SHA-256。
6. 运行后关闭文档、进程和 Worker检查临时文件、Shape handle、WASM 引用和 OPFS lease。
### 3.3 基线验证命令
```bash
.cache/freecad/install-native/bin/FreeCADCmd --version
.cache/freecad/install-desktop/bin/FreeCADCmd --version
./npmw run check:baseline
./npmw run check:freecad-desktop-oracle
FREECAD_ORACLE_PROFILE=desktop xvfb-run -a ./npmw run probe:freecad-reference
./npmw run check:freecad-oracle-coverage
```
任一版本、提交或 artifact hash 不一致时,当前功能任务停止;先恢复基线,不允许生成新的对标结论。
## 4. 三层真实差分链
### 4.1 原生事实层
原生 FreeCAD 每个案例至少输出:
- `baselineId/freecadVersion/gitCommit`
- harness、fixture、输入资源路径、字节数和 SHA-256。
- 文档对象集、对象顺序、TypeId、Label、Visibility 和状态。
- Property 名称、TypeId、值、status、editor mode、表达式和链接。
- recompute 返回值、错误、状态字符串、事务和 observer 事件。
- Shape null/valid、类型、Solid/Face/Edge/Vertex、体积、面积、边界和 BREP hash。
- builder 输入、阶段、Generated/Modified/Deleted、命名和歧义。
- save/reopen/resave 的三相快照。
### 4.2 WEB 实现层
相同案例必须通过生产 `BitBybitWebCadFacade` 进入,不直接调用 UI 内部对象。输出至少包含:
- Facade command/request schema 与版本。
- Document revision、transaction id、generation 和依赖重算结果。
- Worker provider、WASM artifact、Shape handle 所有权和释放计数。
- 与原生同结构的对象、Property、Shape、history、命名和诊断快照。
- OPFS checkpoint、项目资源引用、FCStd/交换格式产物。
### 4.3 真实浏览器层
浏览器案例必须验证:
- UI 命令状态与原生 QAction/command manager 状态一致。
- Task 打开、预览、校验、Apply/OK/Cancel、焦点和选择轨迹一致。
- Worker 真正加载 WASM不能退回 mock provider。
- save/reopen/resave 经过 OPFS 或声明的 fallback不能只在内存中模拟。
- 取消、崩溃、超时、stale response 不提交旧结果。
- 完成后 Shape、Worker 请求、OPFS lease、GPU/Three 资源回到预期基线。
## 5. 比较合同
### 5.1 比较优先级
| 级别 | 比较域 | 必须一致的字段 | 允许差异的前提 |
| --- | --- | --- | --- |
| D0 | 基线 | 版本、提交、artifact、harness、fixture | 不允许 |
| D1 | 接受/拒绝 | 命令 enabled、builder success、失败阶段、诊断分类 | 仅文案本地化可归一化 |
| D2 | 文档 | 对象集、TypeId、依赖、Tip、Support、状态、事务 | 仅已登记浏览器代理对象 |
| D3 | Property | 类型、值、单位、约束、status、editor、表达式、link | 仅显式 opaque/read-only |
| D4 | 几何 | null/valid、Shape 类型、拓扑计数、质量属性、边界、公差 | 数值必须在场景声明公差内 |
| D5 | 历史命名 | stage、Generated/Modified/Deleted、provenance、LinkSub | 原生歧义必须保持歧义 |
| D6 | 持久化 | 对象/属性/资源、Shape、命名、GUI state | 未知资源只能字节保持或拒绝编辑 |
| D7 | GUI | visible/enabled、Task、焦点、选择、树、对话框、状态 | 浏览器保留键需显式映射 |
| D8 | 资源质量 | 时间预算、内存、取消、崩溃、释放、离线 | 只允许已登记平台差异 |
### 5.2 数值和结构规则
1. 离散值、对象数、拓扑数、状态、枚举和错误分类必须精确一致。
2. 长度、面积、体积、角度和矩阵按 fixture 声明公差比较;禁止使用全局无限放宽公差。
3. BREP hash 只在序列化确定的同一阶段要求相等;若 FreeCAD 合法重序列化,必须同时比较结构摘要并登记原因。
4. 属性和对象顺序只有原生语义明确要求时才比较顺序,否则按稳定 identity 比较。
5. 错误文本保存原文,同时生成稳定 reason code测试以 reason code 和关键原文片段双重锁定。
6. 指针、UUID、临时路径、进程号等非确定字段只能由集中归一化器处理禁止单个测试随意删除字段。
## 6. 差异分类与纠正协议
### 6.1 唯一分类
每个差异必须落入且只落入一种分类:
| 分类 | 含义 | 动作 |
| --- | --- | --- |
| `web-implementation-defect` | FreeCAD 稳定WEB 输出错误 | 同一任务内修复实现并补回归 |
| `web-missing-capability` | FreeCAD 接受WEB 无实现 | 保持 pending/in_progress按 A-I 补齐 |
| `web-over-acceptance` | FreeCAD 拒绝WEB 接受 | 删除/封闭 fallback匹配拒绝和回滚 |
| `web-over-rejection` | FreeCAD 接受WEB 拒绝 | 修正输入映射、builder 或能力探测 |
| `native-allowed-evolution` | FreeCAD 自身编辑恢复后命名合法演进 | 保存原生复跑证据WEB 不强制旧名称 |
| `native-ambiguous` | 原生来源不唯一 | WEB 保持 ambiguous/fail-closed |
| `platform-difference` | 浏览器安全/平台限制无法逐字相同 | 明确 compatible/proxy/excluded 和用户诊断 |
| `oracle-defect` | harness、fixture、归一化或基线错误 | 修复 oracle旧结论失效并全部复跑 |
| `unknown` | 尚无充分证据 | 阻断任务和能力提升,不得关闭 |
### 6.2 纠正步骤
1. 用同一锁定环境独立复跑至少两次,排除随机性和陈旧 artifact。
2. 缩减为单一 TypeId、命令、Property 或 builder 阶段的最小 fixture。
3. 保留完整原生输入、输出、诊断、对象集和资源,不只截取失败字段。
4. 判断差异首次出现层UI、Facade、Document、Worker、builder、命名、codec 或 persistence。
5. 先添加会失败的 focused checker再修改生产实现。
6. 修复不得改变无关场景、放宽公差、删除原生拒绝或引入通用 Shape fallback。
7. 重跑名义、失败、边界、变异恢复、事务、往返和浏览器案例。
8. 将差异分类、根因、修复文件、回归命令和 residual risk 写入证据账本。
9. 所有退出条件通过后才生成队列;生成器必须只推进一个任务。
## 7. 单能力 20 步微任务模板
每个命令、对象类型、Property codec、格式分支、GUI 状态或有序操作对依次拆为:
| 步骤 | 微任务 | 单一交付物 | 退出条件 |
| --- | --- | --- | --- |
| T01 | 定位源码 | 模块、TypeId/command、C++/Python 路径 | 来源和版本可追溯 |
| T02 | 锁定输入 | 参数、单位、对象图、选择和资源 | fixture 可重复解析 |
| T03 | 锁定适用性 | enabled/disabled 和前置条件 | 三种基本上下文均有事实 |
| T04 | 原生名义执行 | 成功快照 | 二次执行一致 |
| T05 | 原生边界执行 | 最小/最大/空/多项/单位边界 | 每项有接受或拒绝 |
| T06 | 原生失败执行 | 无效输入和精确诊断 | Shape/对象污染已记录 |
| T07 | 原生取消执行 | preview/cancel/abort | 文档和事务恢复 |
| T08 | 原生参数编辑 | before/edit/restore | 变化和恢复可分类 |
| T09 | 原生历史命名 | stages/history/naming | 无缺失 builder 证据 |
| T10 | 原生持久化 | save/reopen/resave | 三相无未知漂移 |
| T11 | WEB 合同 | Facade request/result/error schema | UI 无内核旁路 |
| T12 | WEB 实现 | production provider | 无 mock/隐藏 fallback |
| T13 | WEB 失败与取消 | structured error/cancel | stale result 不提交 |
| T14 | WEB 事务 | commit/abort/undo/redo | revision 和对象图正确 |
| T15 | WEB 命名 | TopoRef/ElementMap2/LinkSub | 唯一来源稳定,歧义封闭 |
| T16 | WEB 持久化 | Web save/reopen/resave | codec/资源无静默丢失 |
| T17 | 三方差分 | FreeCAD/Bitbybit/native provider 报告 | unknown difference 为零 |
| T18 | 浏览器回放 | Worker/OPFS/UI 证据 | 真实浏览器且资源归零 |
| T19 | 缺陷纠正 | 根因、修复、focused regression | 所有已知差异关闭或分类 |
| T20 | 能力提升 | gate、blocker、matrix、队列同步 | 只推进直接后继 |
如果某项不适用,必须保存机器可验证的 `not-applicable` 原因;不能跳过后只在文档中声称完成。
## 8. 阶段和细粒度里程碑
### M00 基线与治理
- M00.01 验证 FreeCAD headless 版本/提交/hash。
- M00.02 验证 FreeCAD desktop 版本/提交/hash。
- M00.03 验证 sysroot、Python 模块和动态库闭包。
- M00.04 验证 Bitbybit 和原生 history WASM/hash/ABI。
- M00.05 验证浏览器版本、Playwright、GPU 和 OPFS 能力。
- M00.06 验证隔离配置、locale、单位、字体和虚拟显示。
- M00.07 验证队列恰好一个 `in_progress`
- M00.08 验证 exact claim 保持 fail-closed。
退出条件:任一执行机器都能复现同一基线;所有报告携带来源和 hash。
### M01 原生清册与 GUI oracle
- M01.01 34 模块构建/导入状态。
- M01.02 运行时 TypeId 全集和不可实例化原因。
- M01.03 每 TypeId 的 Property、默认值、status、editor。
- M01.04 命令注册全集、source-only 和 context-only 分类。
- M01.05 空文档、活动文档、单选、多选三态命令矩阵。
- M01.06 每命令族 success/disabled/failure/cancel/recovery。
- M01.07 Task、QAction、焦点、选择和对象集快照。
- M01.08 分片合并、重复/遗漏检测和 artifact hash。
退出条件:清册候选全部有运行时事实或显式排除;未知命令状态为零。
### M02 稳定拓扑、history 与有序操作对
- M02.01 每个生产 builder 的输入、阶段 Shape 和 history。
- M02.02 final-shape-only 和缺失 builder 证据 fail-closed。
- M02.03 MappedNameRef/StringHasher 来源和 ABI。
- M02.04 同构拓扑唯一/多来源分类。
- M02.05 参数编辑恢复的 geometry/relation/name 三相摘要。
- M02.06 生产链恢复拓扑和命名演进分类。
- M02.07 19×19 有序操作对逐对原生执行。
- M02.08 接受对的真实 builder、变异、命名和 FCStd。
- M02.09 拒绝/no-op 对的诊断、事务回滚和干净 FCStd。
- M02.10 长链 LinkSub 保存、重开、再次保存。
退出条件所有注册转换均已分类wrong binding、unexplained relation 和 round-trip name drift 为零。
### M03 Property codec 与状态语义
- M03.01 通用标量和枚举。
- M03.02 长度、角度、面积、体积和单位。
- M03.03 Vector、Matrix、Placement、Color 和材料。
- M03.04 String/List/Map/ExpressionEngine。
- M03.05 Link、LinkSub、LinkList、LinkSubList 和 XLink。
- M03.06 Shape、Mesh、Geometry、Constraint 和复杂专用类型。
- M03.07 Extension/FeaturePython/动态 Property。
- M03.08 opaque 类型逐个 native codec 或只读保留。
- M03.09 status/editor/readonly/hidden/transient 行为。
- M03.10 每 codec 的 mutation 和 FCStd 往返。
退出条件:运行时 Property 清册无未分类 opaque未知值不会被 WEB 改写。
### M04 Document、DAG、事务与 observer
- M04.01 create/delete/rename/copy/clone。
- M04.02 add/remove/change Property。
- M04.03 dependency DAG、拓扑排序和 cycle。
- M04.04 dirty/touched/recompute scope。
- M04.05 partial recompute 和失败传播。
- M04.06 transaction commit/abort/nested/merge。
- M04.07 undo/redo 和失败后的最后有效状态。
- M04.08 observer 事件顺序和 payload。
- M04.09 multi-document、cross-document link、MDI。
- M04.10 Extension、FeaturePython、proxy 和 unknown object。
退出条件:事件、对象图和 revision 与原生一致;失败和取消无污染。
### M05 Kernel、Sketcher、Part 和 PartDesign
- M05.01 OCCT 原语、曲线、曲面和 topology inspection。
- M05.02 Boolean、section、split、refine、heal 和 tolerance。
- M05.03 Sketcher 几何、约束、DOF、冗余和冲突。
- M05.04 Sketcher 编辑、drag、external geometry 和 solver recovery。
- M05.05 Part primitive/builder/boolean/modification。
- M05.06 Body、Tip、Group、Support 和 attachment。
- M05.07 Pad/Pocket/Revolution/Groove。
- M05.08 Loft/Pipe/additive/subtractive 组合。
- M05.09 Fillet/Chamfer/Hole/Draft/Thickness。
- M05.10 Pattern/Mirrored/MultiTransform 和跨 Body/XLink。
退出条件:每个 feature 的 T01-T20 完成失败诊断、事务、history、naming 和 FCStd 全部对齐。
### M06 FCStd 与交换格式
- M06.01 Document.xml/GuiDocument.xml/schema/version。
- M06.02 Property codec 和 unknown XML 保留。
- M06.03 BRep、ElementMap、StringHasher 和资源 identity。
- M06.04 Embedded files、scripts、thumbnails 和 extensions。
- M06.05 FreeCAD→Web→FreeCAD 变异链。
- M06.06 Web→FreeCAD→Web 变异链。
- M06.07 BREP/STEP/IGES 单位、颜色、名称、层和装配。
- M06.08 STL/OBJ/PLY/DXF/SVG/PDF。
- M06.09 IFC/CSV/G-code/JT/IDF/OpenSCAD 边界。
- M06.10 损坏、超限、取消、路径穿越和压缩炸弹。
退出条件:支持项双向无未知语义漂移;不支持项无损代理或明确拒绝。
### M07 GUI 与工作台闭合
- M07.01 Shell、菜单、工具栏和 Workbench 切换。
- M07.02 MDI、模型树、Combo View、Dock 和布局保存。
- M07.03 Task panel 和属性 editor 生命周期。
- M07.04 对话框 validation/apply/accept/reject。
- M07.05 3D selection/preselection/context menu。
- M07.06 keyboard、focus、shortcut conflict 和 clipboard。
- M07.07 status/report/jobs/progress/cancel。
- M07.08 desktop/tablet/mobile 响应式和触控。
- M07.09 screenshot、accessibility tree 和 locale。
- M07.10 每工作台端到端 success/failure/cancel/recovery。
退出条件:命令状态、对象结果、事务和交互轨迹对齐;无重叠、溢出或无名控件。
### M08 文档与工程工作台
按 Draft、Spreadsheet、TechDraw、Plot、Assembly、BIM、Surface、Mesh/MeshPart、Material 顺序每个工作台分别完成清册、创建、编辑、失败、引用、事务、格式、GUI、浏览器和跨工作台十个微里程碑。
退出条件:每个对象和命令有 T01-T20跨工作台引用和导出无未知差异。
### M09 分析、制造、数据和扩展
按 FEM、CAM、Robot、Inspection/Measure、Points/ReverseEngineering、Python/Macro、Addon、Cloud/Help/IDF/JT/OpenSCAD 顺序执行。每个外部求解器或 sidecar 还必须锁定版本、许可证、输入输出、超时、取消、资源限制和生产授权边界。
退出条件:可执行能力有真实差分;不可浏览器实现的能力被正式标为 proxy/excluded不冒充 exact。
### M10 平台、可靠性和发布
- M10.01 Chrome/Firefox/WebKit。
- M10.02 Linux/Windows/macOS。
- M10.03 GPU/软件渲染和驱动矩阵。
- M10.04 locale/单位/时区/输入法。
- M10.05 keyboard/screen reader/zoom/high contrast。
- M10.06 fuzz/stress/百万级拓扑或求解重放。
- M10.07 长会话、内存、GPU、Worker 和 OPFS 泄漏。
- M10.08 crash、checkpoint、migration、rollback 和 offline。
- M10.09 SBOM、依赖、许可证、安全和签名。
- M10.10 52/52 exact、34/34 exact 和零差异 promotion。
退出条件:所有支持平台无未知语义差异;签名产物可重建、验签和回滚。
## 9. 每轮执行步骤
```text
1. 读取 config/freecad-active-work-queue.json.nextTask。
2. 核对该任务 dependencies、输入报告和 artifact hash。
3. 创建最小 fixture不得顺手扩大到第二个队列项。
4. 运行锁定 FreeCAD 原生成功/失败/变异/持久化探针。
5. 运行 Bitbybit/原生 provider/Facade 的同输入回放。
6. 运行真实浏览器 Worker/OPFS/UI 回放(任务要求时)。
7. 逐字段比较 D0-D8产生差异列表。
8. 对每项差异执行唯一分类unknown 阻断任务。
9. 对 WEB 缺陷先补失败检查器,再修生产代码。
10. 重跑 focused probe、focused check 和相关回归。
11. 确认事务、文档、Shape、Worker、OPFS 和 GPU 资源恢复。
12. 更新 oracle/verification/分类账本和后续工作完成证据。
13. 重新生成 active queue 和状态页,只允许推进一项。
14. 运行 execution-plan、JSON、git diff 和风险相称的回归。
15. 发布点运行完整 verify、构建、SBOM、签名和验签。
16. 提交、推送,随后再从机器队列读取新的 nextTask。
```
## 10. 常用真实执行命令
```bash
# 原生清册和桌面 GUI
FREECAD_ORACLE_PROFILE=desktop xvfb-run -a ./npmw run probe:freecad-reference
./npmw run probe:freecad-gui-command-shards
./npmw run check:freecad-desktop-oracle
./npmw run check:freecad-oracle-coverage
# 三方几何、历史和命名
./npmw run test:freecad:threeway
./npmw run check:freecad:threeway
./npmw run probe:freecad-ordered-operation-pairs
./npmw run check:freecad-ordered-operation-pairs
./npmw run check:freecad-tsn-stage-correlation
# FCStd 和真实浏览器
./npmw run test:freecad-fcstd-native
./npmw run check:freecad-fcstd-roundtrip
./npmw run ci:real:chrome
./npmw run ci:check:chrome
# 队列和发布门禁
./npmw run generate:freecad-active-work-queue
./npmw run check:freecad-active-work-queue
./npmw run check:execution-plan
./npmw run verify
git diff --check
```
具体任务优先使用队列条目指定的 focused 命令,不应每次先运行整个 suite。完整 `verify` 用于发布点或高风险共享合同变更。
## 11. 证据文件最低结构
```json
{
"schemaVersion": 1,
"baseline": {
"freecadVersion": "1.1.1",
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
"runtime": "desktop|headless|browser",
"artifacts": []
},
"case": {
"id": "machine-generated-id",
"inputs": {},
"preconditions": [],
"phases": {}
},
"comparison": {
"dimensions": [],
"knownDifferences": [],
"unknownDifferences": []
},
"resources": {},
"decision": "accepted|rejected|no-op|compatible|proxy|blocked",
"status": "pass|fail"
}
```
报告生成器必须写入 harness hashchecker 必须重算 hash、验证连续前缀并在 unknown difference 非空时失败。
## 12. 里程碑验收与汇报
每个微里程碑关闭时记录:范围、真实 FreeCAD 命令、输入、原生结论、WEB 结论、差异分类、修复、focused check、浏览器证据、持久化证据、资源释放和剩余风险。
阶段里程碑只能在所有子项自然变为 completed 后关闭。系统级“完全对标 FreeCAD”只能在以下条件同时满足时声明
- exact 计划全部完成。
- 34 个模块全部达到 exact 或从最终声明中正式排除。
- 所有命令、对象、Property、格式和入口无未知项。
- wrong binding、unexplained relation、round-trip name drift、unknown semantic difference 和 release blocker 均为零。
- 跨浏览器/OS/GPU、无障碍、locale、长稳、安全和迁移门禁通过。
- 发布物、SBOM 和能力矩阵签名可验证。
在此之前,项目只能按机器能力矩阵声明 exact、compatible、proxy、development 或 excluded 的实际范围。
## 13. 首次按本文执行发现并纠正的 oracle 差异
本计划落地时立即执行真实基线审计,发现旧 `.cache/freecad/reference-desktop.json` 缺少 `determinism.normalizedProcessFields``check:freecad-desktop-oracle` 因此正确失败。重新运行完整 desktop probe 后又在 `BIMWorkbench` 激活阶段触发默认 300 秒超时;同一 BIM workbench 的 registration-only 原生探针可正常完成,证明不是二进制或模块缺失。
根因位于 `scripts/freecad-reference-probe.py`:隔离配置只在 `gui-commands` scope 设置 `BIM.FirstTime=false`,但 `full` scope 同样会激活 BIM报告又仅根据“使用隔离配置”声称首启已抑制没有读取真实参数。纠正后
1. 所有隔离 GUI probe 在激活任一 workbench 前设置 BIM `FirstTime=false`
2. 立即读回参数,只有真实值为 false 才报告 `suppressed-before-workbench-activation`
3. 完整 desktop probe 重新执行并通过,未再发生 BIM 首启超时。
4. 锁定 FreeCAD 1.1.1、34 模块、352 个运行时 TypeId 候选、348 个可实例化对象、4 个明确不可实例化对象和 5510 条 Property 记录。
5. `check:freecad-desktop-oracle``check:freecad-oracle-coverage``check:freecad-gui-commands` 和 26 场景 `check:freecad:threeway` 全部通过。
6. 由 desktop report 派生的 Property 语义报告因来源 hash 变化而 fail-closed已重新真实生成85 种 Property/5510 条记录中 4987 条由原生 codec 表示523 条继续保持 opaque proxy未被误报 exact。
该修复只纠正 oracle 的真实执行隔离和证据可信度,不提升任何 WEB 模块的 exact 等级。

View File

@@ -46,7 +46,7 @@
### 2.3 已量化但尚未关闭的 P0 阻断
- Oracle352 个注册对象、348 个可实例化对象、4 个不可实例化对象、1111 个启动 GUI command、19 个 source-only command 和 2 个 context-only command 已分类;命令族的成功、禁用、失败、取消、恢复流程仍未穷尽。
- Property85 种运行时类型、5510 条记录中,22 种/4304 条为通用原生 codec5 种/683 条为专用 codec58 种/523 条仍为 opaque proxy。
- Property85 种运行时类型、5510 条记录中,30 种/4361 条为通用原生 codec5 种/683 条为专用 codec50 种/466 条仍为 opaque proxy。
- Property status15 类已观察状态均已进入类型化 Facade 行为;`LockDynamic``PartialTrigger` 已有原生事务证据,但完整 observer 与局部重算序列未关闭。
- TSN30/30 原生 mutation、219/219 几何阶段恢复通过11 个 PartDesign case/28 个恢复命名阶段均已通过第二次独立原生复跑分类为允许演进。
- 生产命名链:五阶段 5/5 几何恢复2 个恢复拓扑 case/5 个下游阶段已分类为允许演进;仍有 3/5 通用 Shape 代理并缺注册 rotate mutation family。

View File

@@ -23,8 +23,136 @@
"check:freecad-inventory": "node scripts/check-freecad-source-inventory.mjs",
"generate:freecad-type-properties": "node scripts/generate-freecad-type-property-inventory.mjs",
"check:freecad-type-properties": "node scripts/check-freecad-type-property-inventory.mjs",
"probe:freecad-native-property-semantics": "node scripts/run-freecad-native-property-semantics.mjs",
"check:freecad-native-property-semantics": "node scripts/check-freecad-native-property-semantics.mjs && node scripts/check-freecad-property-status-oracle.mjs",
"probe:freecad-native-property-semantics": "node scripts/run-freecad-native-property-semantics.mjs",
"generate:freecad-property-acceleration-inventory": "node scripts/generate-freecad-property-acceleration-inventory.mjs",
"check:freecad-property-acceleration-inventory": "node scripts/check-freecad-property-acceleration-inventory.mjs",
"probe:freecad-property-acceleration-success": "node scripts/run-freecad-property-acceleration-success.mjs",
"check:freecad-property-acceleration-success": "node scripts/check-freecad-property-acceleration-success.mjs",
"probe:freecad-property-acceleration-failure": "node scripts/run-freecad-property-acceleration-failure.mjs",
"check:freecad-property-acceleration-failure": "node scripts/check-freecad-property-acceleration-failure.mjs",
"probe:freecad-property-acceleration-mutation": "node scripts/run-freecad-property-acceleration-mutation.mjs",
"check:freecad-property-acceleration-mutation": "node scripts/check-freecad-property-acceleration-mutation.mjs",
"test:freecad-property-acceleration-facade": "tsx --test tests/propertyAccelerationFacade.test.ts",
"test:freecad-property-acceleration-transaction": "tsx --test tests/propertyAccelerationTransaction.test.ts",
"probe:freecad-property-acceleration-roundtrip": "tsx scripts/run-freecad-property-acceleration-roundtrip.ts",
"check:freecad-property-acceleration-roundtrip": "node scripts/check-freecad-property-acceleration-roundtrip.mjs",
"test:chrome-property-acceleration": "node scripts/run-chrome-property-acceleration.mjs",
"check:chrome-property-acceleration": "node scripts/check-chrome-property-acceleration.mjs",
"test:chrome-property-area": "node scripts/run-chrome-property-area.mjs",
"check:chrome-property-area": "node scripts/check-chrome-property-area.mjs",
"generate:freecad-property-area-promotion": "node scripts/generate-freecad-property-area-promotion.mjs",
"check:freecad-property-area-promotion": "node scripts/check-freecad-property-area-promotion.mjs",
"generate:freecad-property-boollist-inventory": "node scripts/generate-freecad-property-boollist-inventory.mjs",
"check:freecad-property-boollist-inventory": "node scripts/check-freecad-property-boollist-inventory.mjs",
"probe:freecad-property-boollist-success": "node scripts/run-freecad-property-boollist-success.mjs",
"check:freecad-property-boollist-success": "node scripts/check-freecad-property-boollist-success.mjs",
"probe:freecad-property-boollist-failure": "node scripts/run-freecad-property-boollist-failure.mjs",
"check:freecad-property-boollist-failure": "node scripts/check-freecad-property-boollist-failure.mjs",
"probe:freecad-property-boollist-mutation": "node scripts/run-freecad-property-boollist-mutation.mjs",
"check:freecad-property-boollist-mutation": "node scripts/check-freecad-property-boollist-mutation.mjs",
"test:freecad-property-boollist-facade": "tsx --test tests/propertyBoolListFacade.test.ts",
"test:freecad-property-boollist-transaction": "tsx --test tests/propertyBoolListTransaction.test.ts",
"probe:freecad-property-boollist-roundtrip": "tsx scripts/run-freecad-property-boollist-roundtrip.ts",
"check:freecad-property-boollist-roundtrip": "node scripts/check-freecad-property-boollist-roundtrip.mjs",
"test:chrome-property-boollist": "node scripts/run-chrome-property-boollist.mjs",
"check:chrome-property-boollist": "node scripts/check-chrome-property-boollist.mjs",
"generate:freecad-property-boollist-promotion": "node scripts/generate-freecad-property-boollist-promotion.mjs",
"check:freecad-property-boollist-promotion": "node scripts/check-freecad-property-boollist-promotion.mjs",
"generate:freecad-property-color-inventory": "node scripts/generate-freecad-property-color-inventory.mjs",
"check:freecad-property-color-inventory": "node scripts/check-freecad-property-color-inventory.mjs",
"probe:freecad-property-color-success": "node scripts/run-freecad-property-color-success.mjs",
"check:freecad-property-color-success": "node scripts/check-freecad-property-color-success.mjs",
"probe:freecad-property-color-failure": "node scripts/run-freecad-property-color-failure.mjs",
"check:freecad-property-color-failure": "node scripts/check-freecad-property-color-failure.mjs",
"probe:freecad-property-color-mutation": "node scripts/run-freecad-property-color-mutation.mjs",
"check:freecad-property-color-mutation": "node scripts/check-freecad-property-color-mutation.mjs",
"test:freecad-property-color-facade": "tsx --test tests/propertyColorFacade.test.ts",
"test:freecad-property-color-transaction": "tsx --test tests/propertyColorTransaction.test.ts",
"probe:freecad-property-color-roundtrip": "tsx scripts/run-freecad-property-color-roundtrip.ts",
"check:freecad-property-color-roundtrip": "node scripts/check-freecad-property-color-roundtrip.mjs",
"test:chrome-property-color": "node scripts/run-chrome-property-color.mjs",
"check:chrome-property-color": "node scripts/check-chrome-property-color.mjs",
"generate:freecad-property-color-promotion": "node scripts/generate-freecad-property-color-promotion.mjs",
"check:freecad-property-color-promotion": "node scripts/check-freecad-property-color-promotion.mjs",
"generate:freecad-property-colorlist-inventory": "node scripts/generate-freecad-property-colorlist-inventory.mjs",
"check:freecad-property-colorlist-inventory": "node scripts/check-freecad-property-colorlist-inventory.mjs",
"probe:freecad-property-colorlist-success": "node scripts/run-freecad-property-colorlist-success.mjs",
"check:freecad-property-colorlist-success": "node scripts/check-freecad-property-colorlist-success.mjs",
"probe:freecad-property-colorlist-failure": "node scripts/run-freecad-property-colorlist-failure.mjs",
"check:freecad-property-colorlist-failure": "node scripts/check-freecad-property-colorlist-failure.mjs",
"probe:freecad-property-colorlist-mutation": "node scripts/run-freecad-property-colorlist-mutation.mjs",
"check:freecad-property-colorlist-mutation": "node scripts/check-freecad-property-colorlist-mutation.mjs",
"test:freecad-property-colorlist-facade": "tsx --test tests/propertyColorListFacade.test.ts",
"test:freecad-property-colorlist-transaction": "tsx --test tests/propertyColorListTransaction.test.ts",
"probe:freecad-property-colorlist-roundtrip": "tsx scripts/run-freecad-property-colorlist-roundtrip.ts",
"check:freecad-property-colorlist-roundtrip": "node scripts/check-freecad-property-colorlist-roundtrip.mjs",
"test:chrome-property-colorlist": "node scripts/run-chrome-property-colorlist.mjs",
"check:chrome-property-colorlist": "node scripts/check-chrome-property-colorlist.mjs",
"generate:freecad-property-colorlist-promotion": "node scripts/generate-freecad-property-colorlist-promotion.mjs",
"check:freecad-property-colorlist-promotion": "node scripts/check-freecad-property-colorlist-promotion.mjs",
"generate:freecad-property-direction-inventory": "node scripts/generate-freecad-property-direction-inventory.mjs",
"check:freecad-property-direction-inventory": "node scripts/check-freecad-property-direction-inventory.mjs",
"probe:freecad-property-direction-success": "node scripts/run-freecad-property-direction-success.mjs",
"check:freecad-property-direction-success": "node scripts/check-freecad-property-direction-success.mjs",
"probe:freecad-property-direction-failure": "node scripts/run-freecad-property-direction-failure.mjs",
"check:freecad-property-direction-failure": "node scripts/check-freecad-property-direction-failure.mjs",
"probe:freecad-property-direction-mutation": "node scripts/run-freecad-property-direction-mutation.mjs",
"check:freecad-property-direction-mutation": "node scripts/check-freecad-property-direction-mutation.mjs",
"test:freecad-property-direction-facade": "tsx --test tests/propertyDirectionFacade.test.ts",
"test:freecad-property-direction-transaction": "tsx --test tests/propertyDirectionTransaction.test.ts",
"probe:freecad-property-direction-roundtrip": "tsx scripts/run-freecad-property-direction-roundtrip.ts",
"check:freecad-property-direction-roundtrip": "node scripts/check-freecad-property-direction-roundtrip.mjs",
"test:chrome-property-direction": "node scripts/run-chrome-property-direction.mjs",
"check:chrome-property-direction": "node scripts/check-chrome-property-direction.mjs",
"generate:freecad-property-direction-promotion": "node scripts/generate-freecad-property-direction-promotion.mjs",
"check:freecad-property-direction-promotion": "node scripts/check-freecad-property-direction-promotion.mjs",
"generate:freecad-property-file-inventory": "node scripts/generate-freecad-property-file-inventory.mjs",
"check:freecad-property-file-inventory": "node scripts/check-freecad-property-file-inventory.mjs",
"generate:freecad-property-fileincluded-inventory": "node scripts/generate-freecad-property-fileincluded-inventory.mjs",
"check:freecad-property-fileincluded-inventory": "node scripts/check-freecad-property-fileincluded-inventory.mjs",
"probe:freecad-property-fileincluded-success": "node scripts/run-freecad-property-fileincluded-success.mjs",
"check:freecad-property-fileincluded-success": "node scripts/check-freecad-property-fileincluded-success.mjs",
"probe:freecad-property-fileincluded-failure": "node scripts/run-freecad-property-fileincluded-failure.mjs",
"check:freecad-property-fileincluded-failure": "node scripts/check-freecad-property-fileincluded-failure.mjs",
"probe:freecad-property-fileincluded-mutation": "node scripts/run-freecad-property-fileincluded-mutation.mjs",
"check:freecad-property-fileincluded-mutation": "node scripts/check-freecad-property-fileincluded-mutation.mjs",
"test:freecad-property-fileincluded-facade": "tsx --test tests/propertyFileIncludedFacade.test.ts",
"test:freecad-property-fileincluded-transaction": "tsx --test tests/propertyFileIncludedTransaction.test.ts",
"probe:freecad-property-fileincluded-roundtrip": "tsx scripts/run-freecad-property-fileincluded-roundtrip.ts",
"check:freecad-property-fileincluded-roundtrip": "node scripts/check-freecad-property-fileincluded-roundtrip.mjs",
"test:chrome-property-fileincluded": "node scripts/run-chrome-property-fileincluded.mjs",
"check:chrome-property-fileincluded": "node scripts/check-chrome-property-fileincluded.mjs",
"generate:freecad-property-fileincluded-promotion": "node scripts/generate-freecad-property-fileincluded-promotion.mjs",
"check:freecad-property-fileincluded-promotion": "node scripts/check-freecad-property-fileincluded-promotion.mjs",
"probe:freecad-property-file-success": "node scripts/run-freecad-property-file-success.mjs",
"check:freecad-property-file-success": "node scripts/check-freecad-property-file-success.mjs",
"probe:freecad-property-file-failure": "node scripts/run-freecad-property-file-failure.mjs",
"check:freecad-property-file-failure": "node scripts/check-freecad-property-file-failure.mjs",
"probe:freecad-property-file-mutation": "node scripts/run-freecad-property-file-mutation.mjs",
"check:freecad-property-file-mutation": "node scripts/check-freecad-property-file-mutation.mjs",
"test:freecad-property-file-facade": "tsx --test tests/propertyFileFacade.test.ts",
"test:freecad-property-file-transaction": "tsx --test tests/propertyFileTransaction.test.ts",
"probe:freecad-property-file-roundtrip": "tsx scripts/run-freecad-property-file-roundtrip.ts",
"check:freecad-property-file-roundtrip": "node scripts/check-freecad-property-file-roundtrip.mjs",
"test:chrome-property-file": "node scripts/run-chrome-property-file.mjs",
"check:chrome-property-file": "node scripts/check-chrome-property-file.mjs",
"generate:freecad-property-file-promotion": "node scripts/generate-freecad-property-file-promotion.mjs",
"check:freecad-property-file-promotion": "node scripts/check-freecad-property-file-promotion.mjs",
"generate:freecad-property-acceleration-promotion": "node scripts/generate-freecad-property-acceleration-promotion.mjs",
"check:freecad-property-acceleration-promotion": "node scripts/check-freecad-property-acceleration-promotion.mjs",
"generate:freecad-property-area-inventory": "node scripts/generate-freecad-property-area-inventory.mjs",
"check:freecad-property-area-inventory": "node scripts/check-freecad-property-area-inventory.mjs",
"probe:freecad-property-area-success": "node scripts/run-freecad-property-area-success.mjs",
"check:freecad-property-area-success": "node scripts/check-freecad-property-area-success.mjs",
"probe:freecad-property-area-failure": "node scripts/run-freecad-property-area-failure.mjs",
"check:freecad-property-area-failure": "node scripts/check-freecad-property-area-failure.mjs",
"probe:freecad-property-area-mutation": "node scripts/run-freecad-property-area-mutation.mjs",
"check:freecad-property-area-mutation": "node scripts/check-freecad-property-area-mutation.mjs",
"test:freecad-property-area-facade": "tsx --test tests/propertyAreaFacade.test.ts",
"test:freecad-property-area-transaction": "tsx --test tests/propertyAreaTransaction.test.ts",
"probe:freecad-property-area-roundtrip": "tsx scripts/run-freecad-property-area-roundtrip.ts",
"check:freecad-property-area-roundtrip": "node scripts/check-freecad-property-area-roundtrip.mjs",
"check:freecad-native-property-semantics": "node scripts/check-freecad-native-property-semantics.mjs && node scripts/check-freecad-property-status-oracle.mjs",
"probe:freecad-property-status": "node scripts/run-freecad-property-status-oracle.mjs",
"check:freecad-property-status": "node scripts/check-freecad-property-status-oracle.mjs",
"generate:freecad-gui-commands": "node scripts/generate-freecad-gui-command-inventory.mjs",

View File

@@ -0,0 +1,13 @@
import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
const root = resolve(new URL('..', import.meta.url).pathname)
const report = JSON.parse(await readFile(resolve(root, 'config/chrome-property-acceleration-verification.json'), 'utf8'))
const fail = (message) => { throw new Error(`Chrome PropertyAcceleration check failed: ${message}`) }
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.browserId !== 'chrome' || !/Chrome\//.test(report.userAgent || '') || report.crossOriginIsolated !== true) fail('browser boundary is invalid')
const requiredWorkerRequests = ['initialize', 'save-document', 'load-document', 'load-checkpoint', 'recovery-report', 'put-resource', 'get-resource', 'release-resource', 'dispose']
if (!report.worker?.constructed?.some(({ name }) => name === 'bitbybit-persistence') || !requiredWorkerRequests.every((type) => report.worker.requestTypes?.includes(type)) || report.worker.terminated?.includes('bitbybit-persistence') !== true) fail('persistence Worker lifecycle is incomplete')
if (report.ui?.inputType !== 'number' || report.ui.label !== 'Acceleration' || report.ui.unit !== 'mm/s^2' || report.ui.beforeValue !== 1000 || report.ui.afterValue !== 500 || report.ui.documentVersion !== 2 || report.ui.dirty !== true || report.ui.objectState !== 'touched' || report.ui.errors?.length !== 0) fail('production UI edit evidence is incomplete')
if (report.persistence?.mode !== 'sqlite-opfs' || report.persistence.sqliteWasm !== true || report.persistence.opfs !== true || report.persistence.savedMode !== 'sqlite-opfs' || report.persistence.loadedValue !== 500 || report.persistence.loadedType !== 'App::PropertyAcceleration' || report.persistence.checkpointVersion !== 2 || report.persistence.recoveryIntegrity !== 'ok' || report.persistence.fcstdElement !== 'Float' || report.persistence.fcstdValue !== '500') fail('OPFS/FCStd persistence evidence is incomplete')
if (!(report.resource?.byteLength > 0) || report.resource.roundTrip !== true || report.resource.released !== true || report.resource.markerRemoved !== true || report.release?.shapeCount !== 0 || report.release.kernelReferenceCount !== 0 || report.release.workerTerminated !== true) fail('resource release evidence is incomplete')
console.log(JSON.stringify({ status: 'chrome-property-acceleration-pass', ui: report.ui, persistence: report.persistence, workerRequests: report.worker.requestTypes, resource: report.resource, release: report.release }, null, 2))

View File

@@ -0,0 +1,13 @@
import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
const root = resolve(new URL('..', import.meta.url).pathname)
const report = JSON.parse(await readFile(resolve(root, 'config/chrome-property-area-verification.json'), 'utf8'))
const fail = (message) => { throw new Error(`Chrome PropertyArea check failed: ${message}`) }
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.browserId !== 'chrome' || !/Chrome\//.test(report.userAgent || '') || report.crossOriginIsolated !== true) fail('browser boundary is invalid')
const requiredWorkerRequests = ['initialize', 'save-document', 'load-document', 'load-checkpoint', 'recovery-report', 'put-resource', 'get-resource', 'release-resource', 'dispose']
if (!report.worker?.constructed?.some(({ name }) => name === 'bitbybit-persistence') || !requiredWorkerRequests.every((type) => report.worker.requestTypes?.includes(type)) || report.worker.terminated?.includes('bitbybit-persistence') !== true) fail('persistence Worker lifecycle is incomplete')
if (report.ui?.areaReadOnly !== true || report.ui.beforeText !== '20 mm^2' || report.ui.afterText !== '0 mm^2' || report.ui.beforeArea !== 20 || report.ui.afterArea !== 0 || report.ui.beforeElementCount !== 2 || report.ui.afterElementCount !== 0 || report.ui.triggerLabel !== 'Clear subshape links' || report.ui.documentVersion !== 2 || report.ui.dirty !== true || report.ui.objectState !== 'touched' || report.ui.errors?.length !== 0) fail('production UI derived-area evidence is incomplete')
if (report.persistence?.mode !== 'sqlite-opfs' || report.persistence.sqliteWasm !== true || report.persistence.opfs !== true || report.persistence.savedMode !== 'sqlite-opfs' || report.persistence.loadedArea !== 0 || report.persistence.loadedAreaType !== 'App::PropertyArea' || report.persistence.loadedElementCount !== 0 || report.persistence.loadedElementsType !== 'App::PropertyLinkSubList' || report.persistence.checkpointVersion !== 2 || report.persistence.recoveryIntegrity !== 'ok' || report.persistence.fcstdAreaElement !== 'Float' || Number(report.persistence.fcstdAreaValue) !== 0 || report.persistence.fcstdElementsElement !== 'LinkSubList' || report.persistence.fcstdElementCount !== 0) fail('OPFS/FCStd persistence evidence is incomplete')
if (!(report.resource?.byteLength > 0) || report.resource.roundTrip !== true || report.resource.released !== true || report.resource.markerRemoved !== true || report.release?.shapeCount !== 0 || report.release.kernelReferenceCount !== 0 || report.release.workerTerminated !== true) fail('resource release evidence is incomplete')
console.log(JSON.stringify({ status: 'chrome-property-area-pass', ui: report.ui, persistence: report.persistence, workerRequests: report.worker.requestTypes, resource: report.resource, release: report.release }, null, 2))

View File

@@ -0,0 +1,15 @@
import { isDeepStrictEqual } from 'node:util'
import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
const root = resolve(new URL('..', import.meta.url).pathname)
const report = JSON.parse(await readFile(resolve(root, 'config/chrome-property-boollist-verification.json'), 'utf8'))
const fail = (message) => { throw new Error(`Chrome PropertyBoolList check failed: ${message}`) }
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.browserId !== 'chrome' || !/Chrome\//.test(report.userAgent || '') || report.crossOriginIsolated !== true) fail('browser boundary is invalid')
const requiredWorkerRequests = ['initialize', 'save-document', 'load-document', 'load-checkpoint', 'recovery-report', 'put-resource', 'get-resource', 'release-resource', 'dispose']
if (!report.worker?.constructed?.some(({ name }) => name === 'bitbybit-persistence') || !requiredWorkerRequests.every((type) => report.worker.requestTypes?.includes(type)) || report.worker.terminated?.includes('bitbybit-persistence') !== true) fail('persistence Worker lifecycle is incomplete')
const target = [true, false, true, false]
if (report.ui?.inputType !== 'text' || report.ui.label !== 'Bool list' || report.ui.beforeText !== 'false' || report.ui.afterText !== 'true, false, true, false' || !isDeepStrictEqual(report.ui.beforeValue, [false]) || !isDeepStrictEqual(report.ui.afterValue, target) || report.ui.documentVersion !== 2 || report.ui.dirty !== true || report.ui.objectState !== 'touched' || report.ui.errors?.length !== 0) fail('production UI edit evidence is incomplete')
if (report.persistence?.mode !== 'sqlite-opfs' || report.persistence.sqliteWasm !== true || report.persistence.opfs !== true || report.persistence.savedMode !== 'sqlite-opfs' || !isDeepStrictEqual(report.persistence.loadedValue, target) || report.persistence.loadedType !== 'App::PropertyBoolList' || report.persistence.checkpointVersion !== 2 || report.persistence.recoveryIntegrity !== 'ok' || report.persistence.fcstdElement !== 'BoolList' || report.persistence.fcstdValue !== '[true,false,true,false]') fail('OPFS/FCStd persistence evidence is incomplete')
if (!(report.resource?.byteLength > 0) || report.resource.roundTrip !== true || report.resource.released !== true || report.resource.markerRemoved !== true || report.release?.shapeCount !== 0 || report.release.kernelReferenceCount !== 0 || report.release.workerTerminated !== true) fail('resource release evidence is incomplete')
console.log(JSON.stringify({ status: 'chrome-property-boollist-pass', ui: report.ui, persistence: report.persistence, workerRequests: report.worker.requestTypes, resource: report.resource, release: report.release }, null, 2))

View File

@@ -0,0 +1,15 @@
import { isDeepStrictEqual } from 'node:util'
import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
const root = resolve(new URL('..', import.meta.url).pathname)
const report = JSON.parse(await readFile(resolve(root, 'config/chrome-property-color-verification.json'), 'utf8'))
const fail = (message) => { throw new Error(`Chrome PropertyColor check failed: ${message}`) }
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.browserId !== 'chrome' || !/Chrome\//.test(report.userAgent || '') || report.crossOriginIsolated !== true) fail('browser boundary is invalid')
const requiredWorkerRequests = ['initialize', 'save-document', 'load-document', 'load-checkpoint', 'recovery-report', 'put-resource', 'get-resource', 'release-resource', 'dispose']
if (!report.worker?.constructed?.some(({ name }) => name === 'bitbybit-persistence') || !requiredWorkerRequests.every((type) => report.worker.requestTypes?.includes(type)) || report.worker.terminated?.includes('bitbybit-persistence') !== true) fail('persistence Worker lifecycle is incomplete')
const target = [0.2, 0.4, 0.6, 0.8]
if (report.ui?.rgbInputType !== 'color' || report.ui.alphaInputType !== 'number' || report.ui.rgbLabel !== 'Colour RGB' || report.ui.alphaLabel !== 'Colour alpha' || report.ui.beforeHex !== '#000000' || report.ui.afterHex !== '#336699' || report.ui.beforeAlpha !== '1' || report.ui.afterAlpha !== 0.8 || !isDeepStrictEqual(report.ui.beforeValue, [0, 0, 0, 1]) || !isDeepStrictEqual(report.ui.afterValue, target) || report.ui.documentVersion !== 3 || report.ui.dirty !== true || report.ui.objectState !== 'touched' || report.ui.errors?.length !== 0) fail('production UI edit evidence is incomplete')
if (report.persistence?.mode !== 'sqlite-opfs' || report.persistence.sqliteWasm !== true || report.persistence.opfs !== true || report.persistence.savedMode !== 'sqlite-opfs' || !isDeepStrictEqual(report.persistence.loadedValue, target) || report.persistence.loadedType !== 'App::PropertyColor' || report.persistence.checkpointVersion !== 3 || report.persistence.recoveryIntegrity !== 'ok' || report.persistence.fcstdElement !== 'PropertyColor' || report.persistence.fcstdValue !== '862362060') fail('OPFS/FCStd persistence evidence is incomplete')
if (!(report.resource?.byteLength > 0) || report.resource.roundTrip !== true || report.resource.released !== true || report.resource.markerRemoved !== true || report.release?.shapeCount !== 0 || report.release.kernelReferenceCount !== 0 || report.release.workerTerminated !== true) fail('resource release evidence is incomplete')
console.log(JSON.stringify({ status: 'chrome-property-color-pass', ui: report.ui, persistence: report.persistence, workerRequests: report.worker.requestTypes, resource: report.resource, release: report.release }, null, 2))

View File

@@ -0,0 +1,15 @@
import { isDeepStrictEqual } from 'node:util'
import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
const root = resolve(new URL('..', import.meta.url).pathname)
const report = JSON.parse(await readFile(resolve(root, 'config/chrome-property-colorlist-verification.json'), 'utf8'))
const fail = (message) => { throw new Error(`Chrome PropertyColorList check failed: ${message}`) }
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.browserId !== 'chrome' || !/Chrome\//.test(report.userAgent || '') || report.crossOriginIsolated !== true) fail('browser boundary is invalid')
const requiredWorkerRequests = ['initialize', 'save-document', 'load-document', 'load-checkpoint', 'recovery-report', 'put-resource', 'get-resource', 'release-resource', 'dispose']
if (!report.worker?.constructed?.some(({ name }) => name === 'bitbybit-persistence') || !requiredWorkerRequests.every((type) => report.worker.requestTypes?.includes(type)) || report.worker.terminated?.includes('bitbybit-persistence') !== true) fail('persistence Worker lifecycle is incomplete')
const target = [[0.2, 0.4, 0.6, 0.8], [17 / 255, 34 / 255, 51 / 255, 0.4]]
if (!isDeepStrictEqual(report.ui?.rgbInputTypes, ['color', 'color']) || !isDeepStrictEqual(report.ui?.alphaInputTypes, ['number', 'number']) || !isDeepStrictEqual(report.ui?.rgbLabels, ['Colour list 1 RGB', 'Colour list 2 RGB']) || !isDeepStrictEqual(report.ui?.alphaLabels, ['Colour list 1 alpha', 'Colour list 2 alpha']) || report.ui?.addLabel !== 'Add Colour list color' || report.ui?.removeLabel !== 'Remove Colour list 3' || !isDeepStrictEqual(report.ui?.beforeHex, ['#000000']) || !isDeepStrictEqual(report.ui?.afterHex, ['#336699', '#112233']) || !isDeepStrictEqual(report.ui?.beforeAlpha, ['1']) || !isDeepStrictEqual(report.ui?.afterAlpha, [0.8, 0.4]) || !isDeepStrictEqual(report.ui?.beforeValue, [[0, 0, 0, 1]]) || !isDeepStrictEqual(report.ui?.afterValue, target) || report.ui?.beforeItemCount !== 1 || report.ui?.peakItemCount !== 3 || report.ui?.afterItemCount !== 2 || report.ui?.documentVersion !== 8 || report.ui?.dirty !== true || report.ui?.objectState !== 'touched' || report.ui?.errors?.length !== 0) fail('production UI edit evidence is incomplete')
if (report.persistence?.mode !== 'sqlite-opfs' || report.persistence.sqliteWasm !== true || report.persistence.opfs !== true || report.persistence.savedMode !== 'sqlite-opfs' || !isDeepStrictEqual(report.persistence.loadedValue, target) || report.persistence.loadedType !== 'App::PropertyColorList' || report.persistence.checkpointVersion !== 8 || report.persistence.recoveryIntegrity !== 'ok' || report.persistence.fcstdElement !== 'ColorList' || report.persistence.fcstdValue !== JSON.stringify(target) || report.persistence.fcstdResourcePath !== 'ColourList' || report.persistence.fcstdResourceBytes !== 12) fail('OPFS/FCStd persistence evidence is incomplete')
if (!(report.resource?.byteLength > 0) || report.resource.roundTrip !== true || report.resource.released !== true || report.resource.markerRemoved !== true || report.release?.shapeCount !== 0 || report.release.kernelReferenceCount !== 0 || report.release.workerTerminated !== true) fail('resource release evidence is incomplete')
console.log(JSON.stringify({ status: 'chrome-property-colorlist-pass', ui: report.ui, persistence: report.persistence, workerRequests: report.worker.requestTypes, resource: report.resource, release: report.release }, null, 2))

View File

@@ -0,0 +1,16 @@
import { isDeepStrictEqual } from 'node:util'
import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
const root = resolve(new URL('..', import.meta.url).pathname)
const report = JSON.parse(await readFile(resolve(root, 'config/chrome-property-direction-verification.json'), 'utf8'))
const fail = (message) => { throw new Error(`Chrome PropertyDirection check failed: ${message}`) }
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.browserId !== 'chrome' || !/Chrome\//.test(report.userAgent || '') || report.crossOriginIsolated !== true) fail('browser boundary is invalid')
const requiredWorkerRequests = ['initialize', 'save-document', 'load-document', 'load-checkpoint', 'recovery-report', 'put-resource', 'get-resource', 'release-resource', 'dispose']
if (!report.worker?.constructed?.some(({ name }) => name === 'bitbybit-persistence') || !requiredWorkerRequests.every((type) => report.worker.requestTypes?.includes(type)) || report.worker.terminated?.includes('bitbybit-persistence') !== true) fail('persistence Worker lifecycle is incomplete')
const initial = { x: 0, y: 0, z: 1 }
const target = { x: 0.25, y: -0.5, z: 1.5 }
if (report.ui?.inputTypes?.some((type) => type !== 'number') || !isDeepStrictEqual(report.ui?.labels, ['Normal x', 'Normal y', 'Normal z']) || !isDeepStrictEqual(report.ui?.beforeValue, initial) || !isDeepStrictEqual(report.ui?.afterValue, target) || report.ui?.documentVersion !== 4 || report.ui?.dirty !== true || report.ui?.objectState !== 'touched' || report.ui?.errors?.length !== 0) fail('production UI direction edit evidence is incomplete')
if (report.persistence?.mode !== 'sqlite-opfs' || report.persistence.sqliteWasm !== true || report.persistence.opfs !== true || report.persistence.savedMode !== 'sqlite-opfs' || !isDeepStrictEqual(report.persistence.loadedValue, target) || report.persistence.loadedType !== 'App::PropertyDirection' || report.persistence.checkpointVersion !== 4 || report.persistence.recoveryIntegrity !== 'ok' || report.persistence.fcstdElement !== 'PropertyVector' || report.persistence.fcstdValue !== JSON.stringify(target)) fail('OPFS/FCStd persistence evidence is incomplete')
if (!(report.resource?.byteLength > 0) || report.resource.roundTrip !== true || report.resource.released !== true || report.resource.markerRemoved !== true || report.release?.shapeCount !== 0 || report.release?.kernelReferenceCount !== 0 || report.release?.workerTerminated !== true) fail('resource release evidence is incomplete')
console.log(JSON.stringify({ status: 'chrome-property-direction-pass', ui: report.ui, persistence: report.persistence, workerRequests: report.worker.requestTypes, resource: report.resource, release: report.release }, null, 2))

View File

@@ -0,0 +1,15 @@
import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
const root = resolve(new URL('..', import.meta.url).pathname)
const report = JSON.parse(await readFile(resolve(root, 'config/chrome-property-file-verification.json'), 'utf8'))
const fail = (message) => { throw new Error(`Chrome PropertyFile check failed: ${message}`) }
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.browserId !== 'chrome' || !/Chrome\//.test(report.userAgent || '') || report.crossOriginIsolated !== true) fail('browser boundary is invalid')
const requiredWorkerRequests = ['initialize', 'save-document', 'load-document', 'load-checkpoint', 'recovery-report', 'put-resource', 'get-resource', 'release-resource', 'dispose']
if (!report.worker?.constructed?.some(({ name }) => name === 'bitbybit-persistence') || !requiredWorkerRequests.every((type) => report.worker.requestTypes?.includes(type)) || report.worker.terminated?.includes('bitbybit-persistence') !== true) fail('persistence Worker lifecycle is incomplete')
const initial = 'project-files/initial.obj'
const target = 'project-files/chrome-updated.obj'
if (report.ui?.inputType !== 'text' || report.ui.label !== 'File name' || report.ui.beforeValue !== initial || report.ui.afterValue !== target || report.ui.documentVersion !== 2 || report.ui.dirty !== true || report.ui.objectState !== 'touched' || report.ui.errors?.length !== 0) fail('production UI file edit evidence is incomplete')
if (report.persistence?.mode !== 'sqlite-opfs' || report.persistence.sqliteWasm !== true || report.persistence.opfs !== true || report.persistence.savedMode !== 'sqlite-opfs' || report.persistence.loadedValue !== target || report.persistence.loadedType !== 'App::PropertyFile' || report.persistence.checkpointVersion !== 2 || report.persistence.recoveryIntegrity !== 'ok' || report.persistence.fcstdElement !== 'String' || report.persistence.fcstdValue !== target) fail('OPFS/FCStd persistence evidence is incomplete')
if (!(report.resource?.byteLength > 0) || report.resource.roundTrip !== true || report.resource.released !== true || report.resource.markerRemoved !== true || report.release?.shapeCount !== 0 || report.release.kernelReferenceCount !== 0 || report.release.workerTerminated !== true) fail('resource release evidence is incomplete')
console.log(JSON.stringify({ status: 'chrome-property-file-pass', ui: report.ui, persistence: report.persistence, workerRequests: report.worker.requestTypes, resource: report.resource, release: report.release }, null, 2))

View File

@@ -0,0 +1,15 @@
import { isDeepStrictEqual } from 'node:util'
import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
const root = resolve(new URL('..', import.meta.url).pathname)
const report = JSON.parse(await readFile(resolve(root, 'config/chrome-property-fileincluded-verification.json'), 'utf8'))
const fail = (message) => { throw new Error(`Chrome PropertyFileIncluded check failed: ${message}`) }
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.browserId !== 'chrome' || !/Chrome\//.test(report.userAgent || '') || report.crossOriginIsolated !== true) fail('browser boundary is invalid')
const requiredWorkerRequests = ['initialize', 'save-document', 'load-document', 'load-checkpoint', 'recovery-report', 'put-resource', 'get-resource', 'release-resource', 'dispose']
if (!report.worker?.constructed?.some(({ name }) => name === 'bitbybit-persistence') || !requiredWorkerRequests.every((type) => report.worker.requestTypes?.includes(type)) || report.worker.terminated?.includes('bitbybit-persistence') !== true) fail('persistence Worker lifecycle is incomplete')
const value = report.ui?.afterValue
if (report.ui?.inputType !== 'file' || report.ui.label !== 'Embedded file' || report.ui.beforeName !== 'Empty' || report.ui.afterName !== 'chrome-resource.bin' || value?.schemaVersion !== 1 || value.archiveName !== 'chrome-resource.bin' || !/^[a-f0-9]{64}$/.test(value.resourceHash || '') || value.byteLength !== 16 || value.mediaType !== 'application/octet-stream' || report.ui.documentVersion !== 2 || report.ui.dirty !== true || report.ui.objectState !== 'touched' || !isDeepStrictEqual(report.ui.notices, ['chrome-resource.bin embedded'])) fail('production UI included-file edit evidence is incomplete')
if (report.persistence?.mode !== 'sqlite-opfs' || report.persistence.sqliteWasm !== true || report.persistence.opfs !== true || report.persistence.savedMode !== 'sqlite-opfs' || !isDeepStrictEqual(report.persistence.loadedValue, value) || report.persistence.loadedType !== 'App::PropertyFileIncluded' || report.persistence.checkpointVersion !== 2 || report.persistence.recoveryIntegrity !== 'ok' || report.persistence.fcstdElement !== 'FileIncluded' || report.persistence.fcstdResourcePath !== 'chrome-resource.bin' || report.persistence.fcstdResourceBytes !== 16 || report.persistence.fcstdResourceMatches !== true) fail('OPFS/FCStd persistence evidence is incomplete')
if (report.resource?.documentByteLength !== 16 || report.resource.documentRoundTrip !== true || !(report.resource.independentByteLength > 0) || report.resource.independentRoundTrip !== true || report.resource.independentReleased !== true || report.resource.markerRemoved !== true || report.release?.shapeCount !== 0 || report.release.kernelReferenceCount !== 0 || report.release.workerTerminated !== true) fail('resource release evidence is incomplete')
console.log(JSON.stringify({ status: 'chrome-property-fileincluded-pass', ui: report.ui, persistence: report.persistence, workerRequests: report.worker.requestTypes, resource: report.resource, release: report.release }, null, 2))

View File

@@ -6,7 +6,21 @@ const forbidden = [
/from\s+["']three(?:\/|["'])/, /from\s+["']@types\/three/, /from\s+["']sqlite3?/, /from\s+["']@sqlite/, /from\s+["']opfs/, /SharedArrayBuffer/, /\bpostMessage\s*\(/,
]
const allowDirectRuntime = new Set(['facade/threeViewport.ts', 'facade/threeViewport.tsx', 'facade/persistenceWorker.ts', 'facade/projectStore.ts', 'facade/projectMigrationSeedWorker.ts', 'facade/geometryWorker.ts', 'facade/nativeHistoryWorkerClient.ts', 'facade/nativeHistoryWorkerEntry.ts', 'facade/planegcsWorkerClient.ts', 'facade/planegcsWorkerEntry.ts'])
const allowWorkerMessaging = new Set(['assemblySolverWorker.ts', 'meshLodWorker.ts', 'chromeAssemblyHarness.ts', 'chromeMeshHarness.ts', 'facade/camPipeline.ts'])
const allowWorkerMessaging = new Set([
'assemblySolverWorker.ts',
'meshLodWorker.ts',
'chromeAssemblyHarness.ts',
'chromeMeshHarness.ts',
'chromePropertyAccelerationHarness.tsx',
'chromePropertyAreaHarness.tsx',
'chromePropertyBoolListHarness.tsx',
'chromePropertyColorHarness.tsx',
'chromePropertyColorListHarness.tsx',
'chromePropertyDirectionHarness.tsx',
'chromePropertyFileHarness.tsx',
'chromePropertyFileIncludedHarness.tsx',
'facade/camPipeline.ts',
])
async function walk(relative = '') {
const directory = new URL(relative, sourceRoot)

View File

@@ -5,11 +5,27 @@ import { resolve } from 'node:path'
const root = resolve(new URL('..', import.meta.url).pathname)
const report = JSON.parse(await readFile(resolve(root, 'config/freecad-native-property-semantics.json'), 'utf8'))
const fail = (message) => { throw new Error(`FreeCAD native property semantics check failed: ${message}`) }
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baseline?.freecadVersion !== '1.1.1' || report.baseline?.commit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.exactPromotionReady !== false || report.exactBlocker !== '58 runtime property types and 523 records remain opaque-only; complete native document and property semantics') fail('report boundary is invalid')
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baseline?.freecadVersion !== '1.1.1' || report.baseline?.commit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.exactPromotionReady !== false || report.exactBlocker !== '50 runtime property types and 466 records remain opaque-only; complete native document and property semantics') fail('report boundary is invalid')
if (report.runtime?.registeredObjectTypes !== 352 || report.runtime.instantiableObjectTypes !== 348 || report.runtime.unavailableObjectTypes !== 4 || report.runtime.propertyRecords !== 5510 || report.runtime.propertyTypes !== 85 || report.runtime.unavailableObjects?.length !== 4) fail('runtime inventory counts changed')
const support = report.supportSummary
if (support?.['native-editable-codec']?.typeCount !== 22 || support['native-editable-codec'].recordCount !== 4304 || support?.['native-specialized-codec']?.typeCount !== 5 || support['native-specialized-codec'].recordCount !== 683 || support?.['opaque-fcstd-proxy']?.typeCount !== 58 || support['opaque-fcstd-proxy'].recordCount !== 523) fail('property support partition is stale')
if (support?.['native-editable-codec']?.typeCount !== 30 || support['native-editable-codec'].recordCount !== 4361 || support?.['native-specialized-codec']?.typeCount !== 5 || support['native-specialized-codec'].recordCount !== 683 || support?.['opaque-fcstd-proxy']?.typeCount !== 50 || support['opaque-fcstd-proxy'].recordCount !== 466) fail('property support partition is stale')
if (report.types?.length !== 85 || new Set(report.types.map(({ typeId }) => typeId)).size !== 85 || report.types.reduce((total, entry) => total + entry.recordCount, 0) !== 5510) fail('per-TypeId inventory is invalid')
const acceleration = report.types.find(({ typeId }) => typeId === 'App::PropertyAcceleration')
if (acceleration?.support !== 'native-editable-codec' || acceleration.recordCount !== 1 || acceleration.objectTypeCount !== 1) fail('App::PropertyAcceleration promotion is missing')
const area = report.types.find(({ typeId }) => typeId === 'App::PropertyArea')
if (area?.support !== 'native-editable-codec' || area.recordCount !== 1 || area.objectTypeCount !== 1 || area.statusNames?.join(',') !== 'PropOutput,PropReadOnly') fail('App::PropertyArea promotion is missing')
const boolList = report.types.find(({ typeId }) => typeId === 'App::PropertyBoolList')
if (boolList?.support !== 'native-editable-codec' || boolList.recordCount !== 7 || boolList.objectTypeCount !== 7 || boolList.statusNames?.join(',') !== 'Hidden,Immutable,LockDynamic') fail('App::PropertyBoolList promotion is missing')
const color = report.types.find(({ typeId }) => typeId === 'App::PropertyColor')
if (color?.support !== 'native-editable-codec' || color.recordCount !== 8 || color.objectTypeCount !== 8 || color.statusNames?.length !== 0) fail('App::PropertyColor promotion is missing')
const colorList = report.types.find(({ typeId }) => typeId === 'App::PropertyColorList')
if (colorList?.support !== 'native-editable-codec' || colorList.recordCount !== 2 || colorList.objectTypeCount !== 2 || colorList.statusNames?.length !== 0) fail('App::PropertyColorList promotion is missing')
const direction = report.types.find(({ typeId }) => typeId === 'App::PropertyDirection')
if (direction?.support !== 'native-editable-codec' || direction.recordCount !== 2 || direction.objectTypeCount !== 2 || direction.statusNames?.length !== 0) fail('App::PropertyDirection promotion is missing')
const file = report.types.find(({ typeId }) => typeId === 'App::PropertyFile')
if (file?.support !== 'native-editable-codec' || file.recordCount !== 16 || file.objectTypeCount !== 12 || file.statusNames?.length !== 0) fail('App::PropertyFile promotion is missing')
const fileIncluded = report.types.find(({ typeId }) => typeId === 'App::PropertyFileIncluded')
if (fileIncluded?.support !== 'native-editable-codec' || fileIncluded.recordCount !== 20 || fileIncluded.objectTypeCount !== 15 || fileIncluded.statusNames?.join(',') !== 'PropOutput,ReadOnly') fail('App::PropertyFileIncluded promotion is missing')
if (report.propertyStatus?.unknownNumericBits?.length !== 0 || report.propertyStatus.proxyOnlyRecordCount !== 0 || report.propertyStatus.proxyOnly?.length !== 0 || report.propertyStatus.facadeNative?.join(',') !== report.propertyStatus.observed?.join(',')) fail('property status representation coverage is stale')
if (report.propertyStatus.behaviorNative?.join(',') !== 'Hidden,Immutable,LockDynamic,NoModify,Ordered,Output,PartialTrigger,PropHidden,PropNoPersist,PropNoRecompute,PropOutput,PropReadOnly,PropTransient,ReadOnly,Transient' || report.propertyStatus.preservedOnly?.length !== 0 || report.propertyStatus.preservedOnlyRecordCount !== 0) fail('property status behavior boundary is stale')
for (const locked of [report.source, report.harness]) {
@@ -17,4 +33,4 @@ for (const locked of [report.source, report.harness]) {
const [content, bytes] = await Promise.all([readFile(path), stat(path).then(({ size }) => size)])
if (bytes !== locked.bytes || createHash('sha256').update(content).digest('hex') !== locked.sha256) fail(`report is stale for ${locked.path}`)
}
console.log(JSON.stringify({ status: 'freecad-native-property-semantics-pass', propertyTypes: 85, propertyRecords: 5510, nativeCodecRecords: 4987, opaqueProxyRecords: 523, representedStatusRecords: 5510, preservedOnlyStatusRecords: 0, exactPromotionReady: false }, null, 2))
console.log(JSON.stringify({ status: 'freecad-native-property-semantics-pass', propertyTypes: 85, propertyRecords: 5510, nativeCodecRecords: 5044, opaqueProxyRecords: 466, promotedTypes: [acceleration.typeId, area.typeId, boolList.typeId, color.typeId, colorList.typeId, direction.typeId, file.typeId, fileIncluded.typeId], representedStatusRecords: 5510, preservedOnlyStatusRecords: 0, exactPromotionReady: false, exactBlocker: report.exactBlocker }, null, 2))

View File

@@ -6,6 +6,13 @@ const root = resolve(new URL('..', import.meta.url).pathname)
const report = JSON.parse(await readFile(resolve(root, 'config/freecad-ordered-operation-pair-classification.json'), 'utf8'))
const fail = (message) => { throw new Error(`FreeCAD ordered operation pair classification: ${message}`) }
const sha256 = (value) => createHash('sha256').update(value).digest('hex')
const summariesMatchWithinTolerance = (left, right, tolerance = 1e-6) => (
left?.isValid === right?.isValid
&& ['solids', 'faces', 'edges', 'vertices'].every((key) => left?.[key] === right?.[key])
&& ['volume', 'area'].every((key) => Math.abs(left?.[key] - right?.[key]) <= tolerance)
&& left?.bounds?.length === right?.bounds?.length
&& left.bounds.every((value, index) => Math.abs(value - right.bounds[index]) <= tolerance)
)
if (report.schemaVersion !== 1 || report.baseline?.freecadVersion !== '1.1.1' || report.baseline.commit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || !/^8\./.test(report.baseline.occtVersion)) fail('baseline is invalid.')
for (const harness of [report.nativeProbe?.executor, report.nativeProbe?.matrix, report.nativeProbe?.resave]) {
const path = resolve(root, harness?.path ?? '')
@@ -227,6 +234,154 @@ const expectedPairs = [
{ pair: 'chamfer->fuse', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepFilletAPI_MakeChamfer', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Fuse', secondInputCount: 2, mutationParameter: 'toolOffsetX', mutationTrajectory: [8, 7, 8] },
{ pair: 'chamfer->cut', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepFilletAPI_MakeChamfer', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'toolSize', mutationTrajectory: [4, 3, 4] },
{ pair: 'chamfer->common', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepFilletAPI_MakeChamfer', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Common', secondInputCount: 2, mutationParameter: 'toolOffsetX', mutationTrajectory: [7, 6, 7] },
{ pair: 'chamfer->rotate', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepFilletAPI_MakeChamfer', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [15, 22.5, 15] },
{ pair: 'chamfer->pad', decision: 'rejected', reasonCode: 'native-builder-and-freecad-profile-reject-with-clean-resave', firstBuilder: 'BRepFilletAPI_MakeChamfer', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepPrimAPI_MakePrism', secondInputCount: 1, mutationParameter: 'length', mutationTrajectory: [5, 7.5, 5], nativeTypeId: 'PartDesign::Pad', freeCadDiagnostic: 'FeatureExtrusion: Length: Could not extrude the sketch!' },
{ pair: 'chamfer->pocket', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepFilletAPI_MakeChamfer', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakePrism+BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'length', mutationTrajectory: [5, 4, 5] },
{ pair: 'chamfer->loft', decision: 'rejected', reasonCode: 'freecad-input-precondition-reject-with-kernel-diagnostic-and-clean-resave', firstBuilder: 'BRepFilletAPI_MakeChamfer', firstInputCount: 1, rejectionAuthority: 'freecad-document', kernelOutcome: 'accepted', secondBuilder: 'BRepOffsetAPI_ThruSections', secondInputCount: 2, mutationParameter: 'ruled', mutationTrajectory: [false, true, false], nativeTypeId: 'Part::Loft', freeCadDiagnostic: 'Profile shape is not a single vertex, edge, wire nor face.' },
{ pair: 'chamfer->pipe', decision: 'rejected', reasonCode: 'freecad-input-precondition-reject-with-kernel-diagnostic-and-clean-resave', firstBuilder: 'BRepFilletAPI_MakeChamfer', firstInputCount: 1, rejectionAuthority: 'freecad-document', kernelOutcome: 'invalid-result', secondBuilder: 'BRepOffsetAPI_MakePipe', secondInputCount: 2, mutationParameter: 'spineLength', mutationTrajectory: [15, 12, 15], nativeTypeId: 'Part::Sweep', freeCadDiagnostic: 'A fatal error occurred when making the sweep' },
{ pair: 'chamfer->revolution', decision: 'rejected', reasonCode: 'native-builder-and-freecad-profile-reject-with-clean-resave', firstBuilder: 'BRepFilletAPI_MakeChamfer', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepPrimAPI_MakeRevol', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [360, 270, 360], nativeTypeId: 'Part::Revolution', freeCadDiagnostic: 'Solids are not Processed' },
{ pair: 'chamfer->groove', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepFilletAPI_MakeChamfer', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakeRevol+BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'angle', mutationTrajectory: [360, 180, 360] },
{ pair: 'chamfer->fillet', decision: 'rejected', reasonCode: 'native-builder-wasm-abort-with-freecad-profile-acceptance-and-clean-resave', firstBuilder: 'BRepFilletAPI_MakeChamfer', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepFilletAPI_MakeFillet', secondInputCount: 1, mutationParameter: 'radius', mutationTrajectory: [0.4, 0.6, 0.4], nativeTypeId: 'Part::Fillet', freecadProfileAccepted: true, wasmCrashSignature: 'memory access out of bounds' },
{ pair: 'chamfer->chamfer', decision: 'rejected', reasonCode: 'native-builder-and-freecad-profile-reject-with-clean-resave', firstBuilder: 'BRepFilletAPI_MakeChamfer', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepFilletAPI_MakeChamfer', secondInputCount: 1, mutationParameter: 'distance', mutationTrajectory: [0.4, 0.6, 0.4], nativeTypeId: 'Part::Chamfer', freeCadDiagnostic: 'BRep_API: command not done', wasmCrashSignature: 'memory access out of bounds' },
{ pair: 'chamfer->hole', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepFilletAPI_MakeChamfer', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', secondInputCount: 1, mutationParameter: 'radius', mutationTrajectory: [1, 1.5, 1] },
{ pair: 'chamfer->draft', decision: 'rejected', reasonCode: 'native-builder-and-freecad-profile-reject-with-clean-resave', firstBuilder: 'BRepFilletAPI_MakeChamfer', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepOffsetAPI_DraftAngle', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [5, 8, 5], nativeTypeId: 'PartDesign::Draft', freeCadDiagnostic: '', inputShapeTransfer: 'partdesign-feature-summary-exact-with-explicit-brep-drift' },
{ pair: 'chamfer->thickness', decision: 'rejected', reasonCode: 'native-and-freecad-profile-no-op-with-clean-resave', firstBuilder: 'BRepFilletAPI_MakeChamfer', firstInputCount: 1, rejectionAuthority: 'occt-no-op', kernelOutcome: 'no-op', secondBuilder: 'BRepOffsetAPI_MakeThickSolid', secondInputCount: 1, mutationParameter: 'offset', mutationTrajectory: [-0.4, -0.6, -0.4], nativeTypeId: 'Part::Thickness', freeCadDiagnostic: 'Valid', freecadProfileNoOp: true, rollbackShape: 'geometry-and-summary-exact-with-explicit-brep-reserialization' },
{ pair: 'chamfer->linear-pattern', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepFilletAPI_MakeChamfer', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', secondInputCount: 1, mutationParameter: 'translationX', mutationTrajectory: [8, 9, 8] },
{ pair: 'chamfer->polar-pattern', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepFilletAPI_MakeChamfer', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [30, 45, 30] },
{ pair: 'chamfer->mirrored', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepFilletAPI_MakeChamfer', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', secondInputCount: 1, mutationParameter: 'planeOriginX', mutationTrajectory: [6, 7, 6] },
{ pair: 'chamfer->multi-transform', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepFilletAPI_MakeChamfer', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', secondInputCount: 1, mutationParameter: 'multiTranslationX', mutationTrajectory: [8, 9, 8] },
{ pair: 'hole->fuse', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Fuse', secondInputCount: 2, mutationParameter: 'toolOffsetX', mutationTrajectory: [8, 7, 8] },
{ pair: 'hole->cut', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'toolSize', mutationTrajectory: [4, 3, 4] },
{ pair: 'hole->common', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Common', secondInputCount: 2, mutationParameter: 'toolOffsetX', mutationTrajectory: [7, 6, 7] },
{ pair: 'hole->rotate', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [15, 22.5, 15] },
{ pair: 'hole->pad', decision: 'rejected', reasonCode: 'native-builder-and-freecad-profile-reject-with-clean-resave', firstBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepPrimAPI_MakePrism', secondInputCount: 1, mutationParameter: 'length', mutationTrajectory: [5, 7.5, 5], nativeTypeId: 'PartDesign::Pad', freeCadDiagnostic: 'FeatureExtrusion: Length: Could not extrude the sketch!' },
{ pair: 'hole->pocket', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakePrism+BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'length', mutationTrajectory: [5, 4, 5] },
{ pair: 'hole->loft', decision: 'rejected', reasonCode: 'freecad-input-precondition-reject-with-kernel-diagnostic-and-clean-resave', firstBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', firstInputCount: 1, rejectionAuthority: 'freecad-document', kernelOutcome: 'accepted', secondBuilder: 'BRepOffsetAPI_ThruSections', secondInputCount: 2, mutationParameter: 'ruled', mutationTrajectory: [false, true, false], nativeTypeId: 'Part::Loft', freeCadDiagnostic: 'Profile shape is not a single vertex, edge, wire nor face.' },
{ pair: 'hole->pipe', decision: 'rejected', reasonCode: 'freecad-input-precondition-reject-with-kernel-diagnostic-and-clean-resave', firstBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', firstInputCount: 1, rejectionAuthority: 'freecad-document', kernelOutcome: 'invalid-result', secondBuilder: 'BRepOffsetAPI_MakePipe', secondInputCount: 2, mutationParameter: 'spineLength', mutationTrajectory: [15, 12, 15], nativeTypeId: 'Part::Sweep', freeCadDiagnostic: 'A fatal error occurred when making the sweep' },
{ pair: 'hole->revolution', decision: 'rejected', reasonCode: 'native-builder-and-freecad-profile-reject-with-clean-resave', firstBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepPrimAPI_MakeRevol', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [360, 270, 360], nativeTypeId: 'Part::Revolution', freeCadDiagnostic: 'Solids are not Processed' },
{ pair: 'hole->groove', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakeRevol+BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'angle', mutationTrajectory: [360, 180, 360] },
{ pair: 'hole->fillet', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', firstInputCount: 1, secondBuilder: 'BRepFilletAPI_MakeFillet', secondInputCount: 1, mutationParameter: 'radius', mutationTrajectory: [0.4, 0.6, 0.4] },
{ pair: 'hole->chamfer', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', firstInputCount: 1, secondBuilder: 'BRepFilletAPI_MakeChamfer', secondInputCount: 1, mutationParameter: 'distance', mutationTrajectory: [0.4, 0.6, 0.4] },
{ pair: 'hole->hole', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', secondInputCount: 1, mutationParameter: 'radius', mutationTrajectory: [1, 1.5, 1] },
{ pair: 'hole->draft', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', firstInputCount: 1, secondBuilder: 'BRepOffsetAPI_DraftAngle', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [5, 8, 5] },
{ pair: 'hole->thickness', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', firstInputCount: 1, secondBuilder: 'BRepOffsetAPI_MakeThickSolid', secondInputCount: 1, mutationParameter: 'offset', mutationTrajectory: [-0.4, -0.6, -0.4] },
{ pair: 'hole->linear-pattern', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', secondInputCount: 1, mutationParameter: 'translationX', mutationTrajectory: [8, 9, 8] },
{ pair: 'hole->polar-pattern', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [30, 45, 30] },
{ pair: 'hole->mirrored', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', secondInputCount: 1, mutationParameter: 'planeOriginX', mutationTrajectory: [6, 7, 6] },
{ pair: 'hole->multi-transform', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', secondInputCount: 1, mutationParameter: 'multiTranslationX', mutationTrajectory: [8, 9, 8] },
{ pair: 'draft->fuse', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_DraftAngle', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Fuse', secondInputCount: 2, mutationParameter: 'toolOffsetX', mutationTrajectory: [8, 7, 8] },
{ pair: 'draft->cut', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_DraftAngle', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'toolSize', mutationTrajectory: [4, 3, 4] },
{ pair: 'draft->common', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_DraftAngle', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Common', secondInputCount: 2, mutationParameter: 'toolOffsetX', mutationTrajectory: [7, 6, 7] },
{ pair: 'draft->rotate', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_DraftAngle', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [15, 22.5, 15] },
{ pair: 'draft->pad', decision: 'rejected', reasonCode: 'native-builder-and-freecad-profile-reject-with-clean-resave', firstBuilder: 'BRepOffsetAPI_DraftAngle', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepPrimAPI_MakePrism', secondInputCount: 1, mutationParameter: 'length', mutationTrajectory: [5, 7.5, 5], nativeTypeId: 'PartDesign::Pad', freeCadDiagnostic: 'FeatureExtrusion: Length: Could not extrude the sketch!' },
{ pair: 'draft->pocket', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_DraftAngle', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakePrism+BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'length', mutationTrajectory: [5, 4, 5] },
{ pair: 'draft->loft', decision: 'rejected', reasonCode: 'freecad-input-precondition-reject-with-kernel-diagnostic-and-clean-resave', firstBuilder: 'BRepOffsetAPI_DraftAngle', firstInputCount: 1, rejectionAuthority: 'freecad-document', kernelOutcome: 'accepted', secondBuilder: 'BRepOffsetAPI_ThruSections', secondInputCount: 2, mutationParameter: 'ruled', mutationTrajectory: [false, true, false], nativeTypeId: 'Part::Loft', freeCadDiagnostic: 'Profile shape is not a single vertex, edge, wire nor face.' },
{ pair: 'draft->pipe', decision: 'rejected', reasonCode: 'freecad-input-precondition-reject-with-kernel-diagnostic-and-clean-resave', firstBuilder: 'BRepOffsetAPI_DraftAngle', firstInputCount: 1, rejectionAuthority: 'freecad-document', kernelOutcome: 'accepted', secondBuilder: 'BRepOffsetAPI_MakePipe', secondInputCount: 2, mutationParameter: 'spineLength', mutationTrajectory: [15, 12, 15], nativeTypeId: 'Part::Sweep', freeCadDiagnostic: 'A fatal error occurred when making the sweep' },
{ pair: 'draft->revolution', decision: 'rejected', reasonCode: 'native-builder-and-freecad-profile-reject-with-clean-resave', firstBuilder: 'BRepOffsetAPI_DraftAngle', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepPrimAPI_MakeRevol', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [360, 270, 360], nativeTypeId: 'Part::Revolution', freeCadDiagnostic: 'Solids are not Processed' },
{ pair: 'draft->groove', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_DraftAngle', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakeRevol+BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'angle', mutationTrajectory: [360, 180, 360] },
{ pair: 'draft->fillet', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_DraftAngle', firstInputCount: 1, secondBuilder: 'BRepFilletAPI_MakeFillet', secondInputCount: 1, mutationParameter: 'radius', mutationTrajectory: [0.4, 0.6, 0.4] },
{ pair: 'draft->chamfer', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_DraftAngle', firstInputCount: 1, secondBuilder: 'BRepFilletAPI_MakeChamfer', secondInputCount: 1, mutationParameter: 'distance', mutationTrajectory: [0.4, 0.6, 0.4] },
{ pair: 'draft->hole', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_DraftAngle', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', secondInputCount: 1, mutationParameter: 'radius', mutationTrajectory: [1, 1.5, 1] },
{ pair: 'draft->draft', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_DraftAngle', firstInputCount: 1, secondBuilder: 'BRepOffsetAPI_DraftAngle', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [5, 8, 5] },
{ pair: 'draft->thickness', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_DraftAngle', firstInputCount: 1, secondBuilder: 'BRepOffsetAPI_MakeThickSolid', secondInputCount: 1, mutationParameter: 'offset', mutationTrajectory: [-0.4, -0.6, -0.4] },
{ pair: 'draft->linear-pattern', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_DraftAngle', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', secondInputCount: 1, mutationParameter: 'translationX', mutationTrajectory: [8, 9, 8] },
{ pair: 'draft->polar-pattern', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_DraftAngle', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [30, 45, 30] },
{ pair: 'draft->mirrored', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_DraftAngle', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', secondInputCount: 1, mutationParameter: 'planeOriginX', mutationTrajectory: [5, 6, 5] },
{ pair: 'draft->multi-transform', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_DraftAngle', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', secondInputCount: 1, mutationParameter: 'multiTranslationX', mutationTrajectory: [8, 9, 8] },
{ pair: 'thickness->fuse', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_MakeThickSolid', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Fuse', secondInputCount: 2, mutationParameter: 'toolOffsetX', mutationTrajectory: [8, 7, 8] },
{ pair: 'thickness->cut', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_MakeThickSolid', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'toolSize', mutationTrajectory: [4, 3, 4] },
{ pair: 'thickness->common', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_MakeThickSolid', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Common', secondInputCount: 2, mutationParameter: 'toolOffsetX', mutationTrajectory: [7, 6, 7] },
{ pair: 'thickness->rotate', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_MakeThickSolid', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [15, 22.5, 15] },
{ pair: 'thickness->pad', decision: 'rejected', reasonCode: 'native-builder-and-freecad-profile-reject-with-clean-resave', firstBuilder: 'BRepOffsetAPI_MakeThickSolid', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepPrimAPI_MakePrism', secondInputCount: 1, mutationParameter: 'length', mutationTrajectory: [5, 7.5, 5], nativeTypeId: 'PartDesign::Pad', freeCadDiagnostic: 'FeatureExtrusion: Length: Could not extrude the sketch!' },
{ pair: 'thickness->pocket', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_MakeThickSolid', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakePrism+BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'length', mutationTrajectory: [5, 4, 5] },
{ pair: 'thickness->loft', decision: 'rejected', reasonCode: 'freecad-input-precondition-reject-with-kernel-diagnostic-and-clean-resave', firstBuilder: 'BRepOffsetAPI_MakeThickSolid', firstInputCount: 1, rejectionAuthority: 'freecad-document', kernelOutcome: 'accepted', secondBuilder: 'BRepOffsetAPI_ThruSections', secondInputCount: 2, mutationParameter: 'ruled', mutationTrajectory: [false, true, false], nativeTypeId: 'Part::Loft', freeCadDiagnostic: 'Profile shape is not a single vertex, edge, wire nor face.' },
{ pair: 'thickness->pipe', decision: 'rejected', reasonCode: 'freecad-input-precondition-reject-with-kernel-diagnostic-and-clean-resave', firstBuilder: 'BRepOffsetAPI_MakeThickSolid', firstInputCount: 1, rejectionAuthority: 'freecad-document', kernelOutcome: 'invalid-result', secondBuilder: 'BRepOffsetAPI_MakePipe', secondInputCount: 2, mutationParameter: 'spineLength', mutationTrajectory: [15, 12, 15], nativeTypeId: 'Part::Sweep', freeCadDiagnostic: 'A fatal error occurred when making the sweep' },
{ pair: 'thickness->revolution', decision: 'rejected', reasonCode: 'native-builder-and-freecad-profile-reject-with-clean-resave', firstBuilder: 'BRepOffsetAPI_MakeThickSolid', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepPrimAPI_MakeRevol', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [360, 270, 360], nativeTypeId: 'Part::Revolution', freeCadDiagnostic: 'Solids are not Processed' },
{ pair: 'thickness->groove', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_MakeThickSolid', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakeRevol+BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'angle', mutationTrajectory: [360, 180, 360] },
{ pair: 'thickness->fillet', decision: 'rejected', reasonCode: 'native-builder-wasm-abort-with-freecad-profile-acceptance-and-clean-resave', firstBuilder: 'BRepOffsetAPI_MakeThickSolid', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepFilletAPI_MakeFillet', secondInputCount: 1, mutationParameter: 'radius', mutationTrajectory: [0.4, 0.6, 0.4], nativeTypeId: 'Part::Fillet', freecadProfileAccepted: true, freecadSelectedEdges: [1], wasmCrashSignature: 'null function or function signature mismatch' },
{ pair: 'thickness->chamfer', decision: 'rejected', reasonCode: 'native-builder-cpp-exception-with-freecad-profile-acceptance-and-clean-resave', firstBuilder: 'BRepOffsetAPI_MakeThickSolid', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepFilletAPI_MakeChamfer', secondInputCount: 1, mutationParameter: 'distance', mutationTrajectory: [0.4, 0.6, 0.4], nativeTypeId: 'Part::Chamfer', freecadProfileAccepted: true, freecadSelectedEdges: [1] },
{ pair: 'thickness->hole', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_MakeThickSolid', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', secondInputCount: 1, mutationParameter: 'radius', mutationTrajectory: [1, 1.5, 1] },
{ pair: 'thickness->draft', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_MakeThickSolid', firstInputCount: 1, secondBuilder: 'BRepOffsetAPI_DraftAngle', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [5, 8, 5] },
{ pair: 'thickness->thickness', decision: 'rejected', reasonCode: 'native-and-freecad-profile-no-op-with-clean-resave', firstBuilder: 'BRepOffsetAPI_MakeThickSolid', firstInputCount: 1, rejectionAuthority: 'occt-no-op', kernelOutcome: 'no-op', secondBuilder: 'BRepOffsetAPI_MakeThickSolid', secondInputCount: 1, mutationParameter: 'offset', mutationTrajectory: [-0.4, -0.6, -0.4], nativeTypeId: 'Part::Thickness', freeCadDiagnostic: 'Valid', freecadProfileNoOp: true },
{ pair: 'thickness->linear-pattern', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_MakeThickSolid', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', secondInputCount: 1, mutationParameter: 'translationX', mutationTrajectory: [8, 9, 8] },
{ pair: 'thickness->polar-pattern', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_MakeThickSolid', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [30, 45, 30] },
{ pair: 'thickness->mirrored', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_MakeThickSolid', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', secondInputCount: 1, mutationParameter: 'planeOriginX', mutationTrajectory: [5, 6, 5] },
{ pair: 'thickness->multi-transform', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepOffsetAPI_MakeThickSolid', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', secondInputCount: 1, mutationParameter: 'multiTranslationX', mutationTrajectory: [8, 9, 8] },
{ pair: 'linear-pattern->fuse', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Fuse', secondInputCount: 2, mutationParameter: 'toolOffsetX', mutationTrajectory: [16, 15, 16] },
{ pair: 'linear-pattern->cut', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'toolSize', mutationTrajectory: [4, 3, 4] },
{ pair: 'linear-pattern->common', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Common', secondInputCount: 2, mutationParameter: 'toolOffsetX', mutationTrajectory: [10, 9, 10] },
{ pair: 'linear-pattern->rotate', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [15, 22.5, 15] },
{ pair: 'linear-pattern->pad', decision: 'rejected', reasonCode: 'native-builder-and-freecad-profile-reject-with-clean-resave', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepPrimAPI_MakePrism', secondInputCount: 1, mutationParameter: 'length', mutationTrajectory: [5, 7.5, 5], nativeTypeId: 'PartDesign::Pad', freeCadDiagnostic: 'FeatureExtrusion: Length: Could not extrude the sketch!' },
{ pair: 'linear-pattern->pocket', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakePrism+BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'length', mutationTrajectory: [5, 4, 5] },
{ pair: 'linear-pattern->loft', decision: 'rejected', reasonCode: 'freecad-input-precondition-reject-with-kernel-diagnostic-and-clean-resave', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, rejectionAuthority: 'freecad-document', kernelOutcome: 'accepted', secondBuilder: 'BRepOffsetAPI_ThruSections', secondInputCount: 2, mutationParameter: 'ruled', mutationTrajectory: [false, true, false], nativeTypeId: 'Part::Loft', freeCadDiagnostic: 'Profile shape is not a single vertex, edge, wire nor face.' },
{ pair: 'linear-pattern->pipe', decision: 'rejected', reasonCode: 'freecad-input-precondition-reject-with-kernel-diagnostic-and-clean-resave', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, rejectionAuthority: 'freecad-document', kernelOutcome: 'invalid-result', secondBuilder: 'BRepOffsetAPI_MakePipe', secondInputCount: 2, mutationParameter: 'spineLength', mutationTrajectory: [15, 12, 15], nativeTypeId: 'Part::Sweep', freeCadDiagnostic: 'A fatal error occurred when making the sweep' },
{ pair: 'linear-pattern->revolution', decision: 'rejected', reasonCode: 'native-builder-and-freecad-profile-reject-with-clean-resave', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepPrimAPI_MakeRevol', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [360, 270, 360], nativeTypeId: 'Part::Revolution', freeCadDiagnostic: 'Solids are not Processed' },
{ pair: 'linear-pattern->groove', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakeRevol+BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'angle', mutationTrajectory: [360, 180, 360] },
{ pair: 'linear-pattern->fillet', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepFilletAPI_MakeFillet', secondInputCount: 1, mutationParameter: 'radius', mutationTrajectory: [0.4, 0.6, 0.4] },
{ pair: 'linear-pattern->chamfer', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepFilletAPI_MakeChamfer', secondInputCount: 1, mutationParameter: 'distance', mutationTrajectory: [0.4, 0.6, 0.4] },
{ pair: 'linear-pattern->hole', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', secondInputCount: 1, mutationParameter: 'radius', mutationTrajectory: [1, 1.5, 1] },
{ pair: 'linear-pattern->draft', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepOffsetAPI_DraftAngle', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [5, 8, 5] },
{ pair: 'linear-pattern->thickness', decision: 'rejected', reasonCode: 'native-and-freecad-profile-no-op-with-clean-resave', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, rejectionAuthority: 'occt-no-op', kernelOutcome: 'no-op', secondBuilder: 'BRepOffsetAPI_MakeThickSolid', secondInputCount: 1, mutationParameter: 'offset', mutationTrajectory: [-0.4, -0.6, -0.4], nativeTypeId: 'Part::Thickness', freeCadDiagnostic: 'Valid', freecadProfileNoOp: true, rollbackShape: 'geometry-and-summary-exact-with-explicit-brep-reserialization' },
{ pair: 'linear-pattern->linear-pattern', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', secondInputCount: 1, mutationParameter: 'translationX', mutationTrajectory: [8, 9, 8] },
{ pair: 'linear-pattern->polar-pattern', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [30, 45, 30] },
{ pair: 'linear-pattern->mirrored', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', secondInputCount: 1, mutationParameter: 'planeOriginX', mutationTrajectory: [5, 6, 5] },
{ pair: 'linear-pattern->multi-transform', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', secondInputCount: 1, mutationParameter: 'multiTranslationX', mutationTrajectory: [8, 9, 8] },
{ pair: 'polar-pattern->fuse', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Fuse', secondInputCount: 2, mutationParameter: 'toolOffsetX', mutationTrajectory: [8, 7, 8] },
{ pair: 'polar-pattern->cut', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'toolSize', mutationTrajectory: [4, 3, 4] },
{ pair: 'polar-pattern->common', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Common', secondInputCount: 2, mutationParameter: 'toolOffsetX', mutationTrajectory: [7, 6, 7] },
{ pair: 'polar-pattern->rotate', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [15, 22.5, 15] },
{ pair: 'polar-pattern->pad', decision: 'rejected', reasonCode: 'native-builder-and-freecad-profile-reject-with-clean-resave', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepPrimAPI_MakePrism', secondInputCount: 1, mutationParameter: 'length', mutationTrajectory: [5, 7.5, 5], nativeTypeId: 'PartDesign::Pad', freeCadDiagnostic: 'FeatureExtrusion: Length: Could not extrude the sketch!' },
{ pair: 'polar-pattern->pocket', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakePrism+BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'length', mutationTrajectory: [5, 4, 5] },
{ pair: 'polar-pattern->loft', decision: 'rejected', reasonCode: 'freecad-input-precondition-reject-with-kernel-diagnostic-and-clean-resave', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, rejectionAuthority: 'freecad-document', kernelOutcome: 'accepted', secondBuilder: 'BRepOffsetAPI_ThruSections', secondInputCount: 2, mutationParameter: 'ruled', mutationTrajectory: [false, true, false], nativeTypeId: 'Part::Loft', freeCadDiagnostic: 'Profile shape is not a single vertex, edge, wire nor face.' },
{ pair: 'polar-pattern->pipe', decision: 'rejected', reasonCode: 'freecad-input-precondition-reject-with-kernel-diagnostic-and-clean-resave', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, rejectionAuthority: 'freecad-document', kernelOutcome: 'invalid-result', secondBuilder: 'BRepOffsetAPI_MakePipe', secondInputCount: 2, mutationParameter: 'spineLength', mutationTrajectory: [15, 12, 15], nativeTypeId: 'Part::Sweep', freeCadDiagnostic: 'A fatal error occurred when making the sweep' },
{ pair: 'polar-pattern->revolution', decision: 'rejected', reasonCode: 'native-builder-and-freecad-profile-reject-with-clean-resave', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepPrimAPI_MakeRevol', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [360, 270, 360], nativeTypeId: 'Part::Revolution', freeCadDiagnostic: 'BRep_API: command not done' },
{ pair: 'polar-pattern->groove', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakeRevol+BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'angle', mutationTrajectory: [360, 180, 360] },
{ pair: 'polar-pattern->fillet', decision: 'rejected', reasonCode: 'native-builder-and-freecad-profile-reject-with-clean-resave', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepFilletAPI_MakeFillet', secondInputCount: 1, mutationParameter: 'radius', mutationTrajectory: [0.4, 0.6, 0.4], nativeTypeId: 'Part::Fillet', freeCadDiagnostic: 'BRep_API: command not done', freecadSelectedEdges: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26], wasmCrashSignature: 'null function or function signature mismatch' },
{ pair: 'polar-pattern->chamfer', decision: 'rejected', reasonCode: 'native-builder-and-freecad-profile-reject-with-clean-resave', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepFilletAPI_MakeChamfer', secondInputCount: 1, mutationParameter: 'distance', mutationTrajectory: [0.4, 0.6, 0.4], nativeTypeId: 'Part::Chamfer', freeCadDiagnostic: 'BRep_API: command not done', freecadSelectedEdges: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26] },
{ pair: 'polar-pattern->hole', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', secondInputCount: 1, mutationParameter: 'radius', mutationTrajectory: [1, 1.5, 1] },
{ pair: 'polar-pattern->draft', decision: 'rejected', reasonCode: 'native-builder-and-freecad-profile-reject-with-clean-resave', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepOffsetAPI_DraftAngle', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [5, 8, 5], nativeTypeId: 'PartDesign::Draft', freeCadDiagnostic: '', inputShapeTransfer: 'partdesign-feature-summary-exact-with-explicit-brep-drift' },
{ pair: 'polar-pattern->thickness', decision: 'rejected', reasonCode: 'native-and-freecad-profile-no-op-with-clean-resave', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, rejectionAuthority: 'occt-no-op', kernelOutcome: 'no-op', secondBuilder: 'BRepOffsetAPI_MakeThickSolid', secondInputCount: 1, mutationParameter: 'offset', mutationTrajectory: [-0.4, -0.6, -0.4], nativeTypeId: 'Part::Thickness', freeCadDiagnostic: 'Valid', freecadProfileNoOp: true, rollbackShape: 'geometry-and-summary-exact-with-explicit-brep-reserialization', kernelNoOpComparison: 'topology-and-metrics-within-1e-6' },
{ pair: 'polar-pattern->linear-pattern', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', secondInputCount: 1, mutationParameter: 'translationX', mutationTrajectory: [8, 9, 8] },
{ pair: 'polar-pattern->polar-pattern', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [30, 45, 30] },
{ pair: 'polar-pattern->mirrored', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', secondInputCount: 1, mutationParameter: 'planeOriginX', mutationTrajectory: [5, 6, 5] },
{ pair: 'polar-pattern->multi-transform', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', secondInputCount: 1, mutationParameter: 'multiTranslationX', mutationTrajectory: [8, 9, 8] },
{ pair: 'mirrored->fuse', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Fuse', secondInputCount: 2, mutationParameter: 'toolOffsetX', mutationTrajectory: [8, 7, 8] },
{ pair: 'mirrored->cut', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'toolSize', mutationTrajectory: [4, 3, 4] },
{ pair: 'mirrored->common', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Common', secondInputCount: 2, mutationParameter: 'toolOffsetX', mutationTrajectory: [7, 6, 7] },
{ pair: 'mirrored->rotate', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [15, 22.5, 15] },
{ pair: 'mirrored->pad', decision: 'rejected', reasonCode: 'native-builder-and-freecad-profile-reject-with-clean-resave', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepPrimAPI_MakePrism', secondInputCount: 1, mutationParameter: 'length', mutationTrajectory: [5, 7.5, 5], nativeTypeId: 'PartDesign::Pad', freeCadDiagnostic: 'FeatureExtrusion: Length: Could not extrude the sketch!' },
{ pair: 'mirrored->pocket', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakePrism+BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'length', mutationTrajectory: [5, 4, 5] },
{ pair: 'mirrored->loft', decision: 'rejected', reasonCode: 'freecad-input-precondition-reject-with-kernel-diagnostic-and-clean-resave', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, rejectionAuthority: 'freecad-document', kernelOutcome: 'accepted', secondBuilder: 'BRepOffsetAPI_ThruSections', secondInputCount: 2, mutationParameter: 'ruled', mutationTrajectory: [false, true, false], nativeTypeId: 'Part::Loft', freeCadDiagnostic: 'Profile shape is not a single vertex, edge, wire nor face.' },
{ pair: 'mirrored->pipe', decision: 'rejected', reasonCode: 'freecad-input-precondition-reject-with-kernel-diagnostic-and-clean-resave', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, rejectionAuthority: 'freecad-document', kernelOutcome: 'invalid-result', secondBuilder: 'BRepOffsetAPI_MakePipe', secondInputCount: 2, mutationParameter: 'spineLength', mutationTrajectory: [15, 12, 15], nativeTypeId: 'Part::Sweep', freeCadDiagnostic: 'A fatal error occurred when making the sweep' },
{ pair: 'mirrored->revolution', decision: 'rejected', reasonCode: 'native-builder-and-freecad-profile-reject-with-clean-resave', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepPrimAPI_MakeRevol', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [360, 270, 360], nativeTypeId: 'Part::Revolution', freeCadDiagnostic: 'Solids are not Processed' },
{ pair: 'mirrored->groove', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakeRevol+BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'angle', mutationTrajectory: [360, 180, 360] },
{ pair: 'mirrored->fillet', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepFilletAPI_MakeFillet', secondInputCount: 1, mutationParameter: 'radius', mutationTrajectory: [0.4, 0.6, 0.4] },
{ pair: 'mirrored->chamfer', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepFilletAPI_MakeChamfer', secondInputCount: 1, mutationParameter: 'distance', mutationTrajectory: [0.4, 0.6, 0.4] },
{ pair: 'mirrored->hole', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', secondInputCount: 1, mutationParameter: 'radius', mutationTrajectory: [1, 1.5, 1] },
{ pair: 'mirrored->draft', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepOffsetAPI_DraftAngle', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [5, 8, 5] },
{ pair: 'mirrored->thickness', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepOffsetAPI_MakeThickSolid', secondInputCount: 1, mutationParameter: 'offset', mutationTrajectory: [-0.4, -0.6, -0.4] },
{ pair: 'mirrored->polar-pattern', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [30, 45, 30] },
{ pair: 'mirrored->mirrored', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', secondInputCount: 1, mutationParameter: 'planeOriginX', mutationTrajectory: [5, 6, 5] },
{ pair: 'mirrored->multi-transform', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', secondInputCount: 1, mutationParameter: 'multiTranslationX', mutationTrajectory: [8, 9, 8] },
{ pair: 'multi-transform->fuse', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Fuse', secondInputCount: 2, mutationParameter: 'toolOffsetX', mutationTrajectory: [16, 15, 16] },
{ pair: 'multi-transform->cut', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'toolSize', mutationTrajectory: [4, 3, 4] },
{ pair: 'multi-transform->common', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', firstInputCount: 1, secondBuilder: 'BRepAlgoAPI_Common', secondInputCount: 2, mutationParameter: 'toolOffsetX', mutationTrajectory: [10, 9, 10] },
{ pair: 'multi-transform->rotate', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [15, 22.5, 15] },
{ pair: 'multi-transform->pad', decision: 'rejected', reasonCode: 'native-builder-and-freecad-profile-reject-with-clean-resave', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepPrimAPI_MakePrism', secondInputCount: 1, mutationParameter: 'length', mutationTrajectory: [5, 7.5, 5], nativeTypeId: 'PartDesign::Pad', freeCadDiagnostic: 'FeatureExtrusion: Length: Could not extrude the sketch!' },
{ pair: 'multi-transform->pocket', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakePrism+BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'length', mutationTrajectory: [5, 4, 5] },
{ pair: 'multi-transform->loft', decision: 'rejected', reasonCode: 'freecad-input-precondition-reject-with-kernel-diagnostic-and-clean-resave', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', firstInputCount: 1, rejectionAuthority: 'freecad-document', kernelOutcome: 'accepted', secondBuilder: 'BRepOffsetAPI_ThruSections', secondInputCount: 2, mutationParameter: 'ruled', mutationTrajectory: [false, true, false], nativeTypeId: 'Part::Loft', freeCadDiagnostic: 'Profile shape is not a single vertex, edge, wire nor face.' },
{ pair: 'multi-transform->pipe', decision: 'rejected', reasonCode: 'freecad-input-precondition-reject-with-kernel-diagnostic-and-clean-resave', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', firstInputCount: 1, rejectionAuthority: 'freecad-document', kernelOutcome: 'invalid-result', secondBuilder: 'BRepOffsetAPI_MakePipe', secondInputCount: 2, mutationParameter: 'spineLength', mutationTrajectory: [15, 12, 15], nativeTypeId: 'Part::Sweep', freeCadDiagnostic: 'A fatal error occurred when making the sweep' },
{ pair: 'multi-transform->revolution', decision: 'rejected', reasonCode: 'native-builder-and-freecad-profile-reject-with-clean-resave', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', firstInputCount: 1, rejectionAuthority: 'occt-builder', secondBuilder: 'BRepPrimAPI_MakeRevol', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [360, 270, 360], nativeTypeId: 'Part::Revolution', freeCadDiagnostic: 'BRep_API: command not done' },
{ pair: 'multi-transform->groove', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakeRevol+BRepAlgoAPI_Cut', secondInputCount: 2, mutationParameter: 'angle', mutationTrajectory: [360, 180, 360] },
{ pair: 'multi-transform->fillet', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', firstInputCount: 1, secondBuilder: 'BRepFilletAPI_MakeFillet', secondInputCount: 1, mutationParameter: 'radius', mutationTrajectory: [0.4, 0.6, 0.4] },
{ pair: 'multi-transform->chamfer', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', firstInputCount: 1, secondBuilder: 'BRepFilletAPI_MakeChamfer', secondInputCount: 1, mutationParameter: 'distance', mutationTrajectory: [0.4, 0.6, 0.4] },
{ pair: 'multi-transform->hole', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', firstInputCount: 1, secondBuilder: 'BRepPrimAPI_MakeCylinder+BRepAlgoAPI_Cut', secondInputCount: 1, mutationParameter: 'radius', mutationTrajectory: [1, 1.5, 1] },
{ pair: 'multi-transform->draft', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', firstInputCount: 1, secondBuilder: 'BRepOffsetAPI_DraftAngle', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [5, 8, 5] },
{ pair: 'multi-transform->thickness', decision: 'rejected', reasonCode: 'native-and-freecad-profile-no-op-with-clean-resave', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', firstInputCount: 1, rejectionAuthority: 'occt-no-op', kernelOutcome: 'no-op', secondBuilder: 'BRepOffsetAPI_MakeThickSolid', secondInputCount: 1, mutationParameter: 'offset', mutationTrajectory: [-0.4, -0.6, -0.4], nativeTypeId: 'Part::Thickness', freeCadDiagnostic: 'Valid', freecadProfileNoOp: true, rollbackShape: 'geometry-and-summary-exact-with-explicit-brep-reserialization' },
{ pair: 'multi-transform->linear-pattern', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', secondInputCount: 1, mutationParameter: 'translationX', mutationTrajectory: [8, 9, 8] },
{ pair: 'multi-transform->polar-pattern', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', secondInputCount: 1, mutationParameter: 'angle', mutationTrajectory: [30, 45, 30] },
{ pair: 'multi-transform->mirrored', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse', secondInputCount: 1, mutationParameter: 'planeOriginX', mutationTrajectory: [5, 6, 5] },
{ pair: 'multi-transform->multi-transform', decision: 'accepted', reasonCode: 'native-builders-mutation-naming-and-fcstd-resave-pass', firstBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', firstInputCount: 1, secondBuilder: 'BRepBuilderAPI_Transform+BRepAlgoAPI_Fuse(ordered)', secondInputCount: 1, mutationParameter: 'multiTranslationX', mutationTrajectory: [8, 9, 8] },
]
if (report.nativeProbe?.artifacts?.length !== 3 || report.classifications?.length !== expectedPairs.length) fail('native artifacts or classification prefix is incomplete.')
for (const [index, entry] of report.classifications.entries()) {
@@ -251,16 +406,22 @@ for (const [index, entry] of report.classifications.entries()) {
for (const [attemptIndex, attempt] of rejection.kernelAttempts.entries()) {
const validKernelShape = expected.kernelOutcome !== 'invalid-result'
const expectedAuthority = expected.kernelOutcome === 'no-op' ? 'kernel-no-op' : expected.kernelOutcome === 'accepted' ? 'kernel-superset-only' : 'kernel-invalid-result'
if (attempt.operation !== secondOperation || attempt.builder !== expected.secondBuilder || attempt.inputCount !== expected.secondInputCount || attempt.parameter !== expected.mutationParameter || attempt.parameterValue !== expected.mutationTrajectory[attemptIndex] || attempt.runtime !== 'occt-native' || attempt.outcome !== expected.kernelOutcome || attempt.resultProduced !== true || attempt.shapeProduced !== true || attempt.validShapeProduced !== validKernelShape || attempt.historyProduced !== true || attempt.historyProvider !== 'occt-native' || attempt.summary?.isValid !== validKernelShape || attempt.historyRecords < 1 || !attempt.historySha256 || attempt.authority !== expectedAuthority || (expected.kernelOutcome === 'no-op' && JSON.stringify(attempt.summary) !== JSON.stringify(entry.first.summary))) fail(`${expected.pair} OCCT compatibility attempt ${attemptIndex} is invalid.`)
const tolerantNoOp = expected.kernelNoOpComparison === 'topology-and-metrics-within-1e-6'
const noOpMatchesInput = tolerantNoOp
? attempt.noOpComparison === expected.kernelNoOpComparison && summariesMatchWithinTolerance(attempt.summary, entry.first.summary)
: JSON.stringify(attempt.summary) === JSON.stringify(entry.first.summary)
if (attempt.operation !== secondOperation || attempt.builder !== expected.secondBuilder || attempt.inputCount !== expected.secondInputCount || attempt.parameter !== expected.mutationParameter || attempt.parameterValue !== expected.mutationTrajectory[attemptIndex] || attempt.runtime !== 'occt-native' || attempt.outcome !== expected.kernelOutcome || attempt.resultProduced !== true || attempt.shapeProduced !== true || attempt.validShapeProduced !== validKernelShape || attempt.historyProduced !== true || attempt.historyProvider !== 'occt-native' || attempt.summary?.isValid !== validKernelShape || attempt.historyRecords < 1 || !attempt.historySha256 || attempt.authority !== expectedAuthority || (expected.kernelOutcome === 'no-op' && !noOpMatchesInput)) fail(`${expected.pair} OCCT compatibility attempt ${attemptIndex} is invalid.`)
}
}
const persistence = rejection.persistence
const diagnostic = persistence?.diagnostic
const freecadProfileAccepted = expected.freecadProfileAccepted === true
const freecadProfileNoOp = expected.freecadProfileNoOp === true
const persistenceChecksPass = Object.values(persistence?.checks ?? {}).every(Boolean) || (freecadProfileAccepted && persistence?.checks?.nativeFeatureRejected === false && Object.entries(persistence?.checks ?? {}).filter(([key]) => key !== 'nativeFeatureRejected').every(([, value]) => value === true)) || (freecadProfileNoOp && persistence?.checks?.freecadProfileNoOp === true && persistence?.checks?.freecadProfileAccepted === false && persistence?.checks?.nativeFeatureRejected === false && Object.entries(persistence?.checks ?? {}).filter(([key]) => !['nativeFeatureRejected', 'freecadProfileAccepted'].includes(key)).every(([, value]) => value === true)) || (!freecadProfileAccepted && !freecadProfileNoOp && persistence?.checks?.nativeFeatureRejected === true && Object.entries(persistence?.checks ?? {}).filter(([key]) => key !== 'freecadProfileAccepted').every(([, value]) => value === true))
const noOpSourceBrepReserialized = expected.rollbackShape === 'geometry-and-summary-exact-with-explicit-brep-reserialization' && persistence?.checks?.sourceShapeRestored === false && persistence?.checks?.sourceShapeSummaryRestored === true && persistence?.checks?.sourceShapeGeometricallyRestored === true && persistence?.rollback?.sourceBrepReserialized === true
const persistenceChecksPass = Object.values(persistence?.checks ?? {}).every(Boolean) || (freecadProfileAccepted && persistence?.checks?.nativeFeatureRejected === false && Object.entries(persistence?.checks ?? {}).filter(([key]) => key !== 'nativeFeatureRejected').every(([, value]) => value === true)) || (freecadProfileNoOp && persistence?.checks?.freecadProfileNoOp === true && persistence?.checks?.freecadProfileAccepted === false && persistence?.checks?.nativeFeatureRejected === false && Object.entries(persistence?.checks ?? {}).filter(([key]) => !['nativeFeatureRejected', 'freecadProfileAccepted', ...(noOpSourceBrepReserialized ? ['sourceShapeRestored'] : [])].includes(key)).every(([, value]) => value === true)) || (!freecadProfileAccepted && !freecadProfileNoOp && persistence?.checks?.nativeFeatureRejected === true && Object.entries(persistence?.checks ?? {}).filter(([key]) => key !== 'freecadProfileAccepted').every(([, value]) => value === true))
if (persistence?.status !== 'pass' || persistence.decision !== 'rejected' || persistence.pair !== entry.pair || persistence.operation !== secondOperation || persistence.nativeTypeId !== expected.nativeTypeId || persistence.freecadVersion !== '1.1.1' || !persistenceChecksPass) fail(`${expected.pair} FCStd rejection evidence is incomplete.`)
if (diagnostic?.nativeTypeId !== expected.nativeTypeId || diagnostic.parameter?.name !== expected.mutationParameter || diagnostic.parameter.value !== expected.mutationTrajectory[0] || diagnostic.inputShape?.solids !== 1 || diagnostic.recomputeResult !== true || !diagnostic.objects?.some(({ name, typeId }) => name === 'PairResult' && typeId === expected.nativeTypeId)) fail(`${expected.pair} did not capture a real FreeCAD profile evaluation.`)
if (expected.freecadSelectedEdges && JSON.stringify(diagnostic.input?.selectedEdges) !== JSON.stringify(expected.freecadSelectedEdges)) fail(`${expected.pair} FreeCAD selected-edge fixture changed.`)
if (freecadProfileNoOp) {
if (diagnostic.shapeNull !== false || diagnostic.shapeValid !== true || diagnostic.statusString !== 'Valid' || !diagnostic.state?.includes('Up-to-date') || JSON.stringify(diagnostic.resultShape) !== JSON.stringify(diagnostic.inputShape)) fail(`${expected.pair} FreeCAD no-op evidence is incomplete.`)
} else if (freecadProfileAccepted) {
@@ -273,7 +434,14 @@ for (const [index, entry] of report.classifications.entries()) {
const input = diagnostic.input
if (input?.name !== 'DraftBase' || input.typeId !== 'PartDesign::Feature' || JSON.stringify(input.subelements) !== JSON.stringify(['Face1']) || input.sourceName !== persistence.source?.name || input.shapeSummaryTransferredExactly !== true || typeof input.sourceBrepSha256 !== 'string' || typeof input.draftBaseBrepSha256 !== 'string' || input.sourceBrepSha256 === input.draftBaseBrepSha256) fail(`${expected.pair} PartDesign input Shape transfer evidence is incomplete.`)
}
if (persistence.source?.shape?.solids !== 1 || !persistence.source.shape.brepSha256 || JSON.stringify(persistence.rollback?.before) !== JSON.stringify(persistence.rollback?.after)) fail(`${expected.pair} abort did not restore the source object set and Shape.`)
if (persistence.source?.shape?.solids !== 1 || !persistence.source.shape.brepSha256) fail(`${expected.pair} source Shape evidence is incomplete.`)
if (expected.rollbackShape === 'geometry-and-summary-exact-with-explicit-brep-reserialization') {
const before = persistence.rollback?.before
const after = persistence.rollback?.after
const symmetricDifference = persistence.rollback?.sourceShapeSymmetricDifference
const withoutBrep = (shape) => Object.fromEntries(Object.entries(shape ?? {}).filter(([key]) => key !== 'brepSha256'))
if (JSON.stringify(before?.objects) !== JSON.stringify(after?.objects) || JSON.stringify(withoutBrep(before?.sourceShape)) !== JSON.stringify(withoutBrep(after?.sourceShape)) || before?.sourceShape?.brepSha256 === after?.sourceShape?.brepSha256 || persistence.rollback?.sourceBrepReserialized !== true || persistence.rollback?.sourceShapeTopologicallyEqual !== false || symmetricDifference?.beforeMinusAfterVolume !== 0 || symmetricDifference?.afterMinusBeforeVolume !== 0 || persistence.checks.sourceShapeSummaryRestored !== true || persistence.checks.sourceShapeGeometricallyRestored !== true || persistence.checks.sourceShapeRestored !== false) fail(`${expected.pair} did not classify the source BREP reserialization precisely.`)
} else if (JSON.stringify(persistence.rollback?.before) !== JSON.stringify(persistence.rollback?.after)) fail(`${expected.pair} abort did not restore the source object set and Shape.`)
const phases = persistence.phases
if (JSON.stringify(phases?.initial) !== JSON.stringify(phases?.reopened) || JSON.stringify(phases?.initial) !== JSON.stringify(phases?.resaved) || phases.initial.objects?.length !== persistence.rollback.before.objects.length || phases.initial.objects?.some(({ typeId }) => typeId === 'PartDesign::Body' || typeId === 'PartDesign::Pad' || typeId === 'Part::Loft' || typeId === 'Part::Revolution')) fail(`${expected.pair} polluted the clean FCStd save/reopen/resave chain.`)
continue
@@ -288,6 +456,6 @@ for (const [index, entry] of report.classifications.entries()) {
const phases = entry.persistence.phases
if (JSON.stringify(phases?.initial) !== JSON.stringify(phases?.reopened) || JSON.stringify(phases?.initial) !== JSON.stringify(phases?.resaved) || phases.initial.namingEvidenceSha256 !== entry.second.namingEvidenceSha256) fail(`${expected.pair} FCStd phases changed Shape or naming evidence.`)
}
const expectedSummary = { registeredOperations: 19, orderedPairs: 361, classifiedPairs: 209, accepted: 157, rejected: 52, unknown: 152 }
const expectedSummary = { registeredOperations: 19, orderedPairs: 361, classifiedPairs: 357, accepted: 260, rejected: 97, unknown: 4 }
if (JSON.stringify(report.summary) !== JSON.stringify(expectedSummary)) fail('summary is inconsistent.')
console.log(JSON.stringify({ status: 'freecad-ordered-operation-pair-classification-pass', completedTasks: report.classifications.map(({ taskId }) => taskId), pairs: report.classifications.map(({ pair, classification }) => ({ pair, classification })), nativeBuilderRuns: report.classifications.length * 4, fcstdPhases: report.classifications.length * 3, remainingPairs: report.summary.unknown }, null, 2))

View File

@@ -0,0 +1,24 @@
import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
const root = resolve(new URL('..', import.meta.url).pathname)
const report = JSON.parse(await readFile(resolve(root, 'config/freecad-property-acceleration-failure.json'), 'utf8'))
const fail = (message) => { throw new Error(`FreeCAD PropertyAcceleration failure check failed: ${message}`) }
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-acceleration-failure' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('baseline is invalid')
if (report.object?.typeId !== 'Robot::TrajectoryDressUpObject' || report.property?.typeId !== 'App::PropertyAcceleration' || report.initial?.numeric !== 1000 || report.failures?.length !== 2) fail('failure fixture identity or cases changed')
const expectedFailures = new Map([
['wrong-dimension', { requested: '5 mm', type: 'ArithmeticError', message: 'Not matching Unit!' }],
['malformed-text', { requested: 'not-a-quantity', type: 'ParserError', message: 'syntax error' }],
])
for (const entry of report.failures) {
const expected = expectedFailures.get(entry.id)
if (!expected || entry.requested !== expected.requested || entry.exception?.type !== expected.type || entry.exception?.message !== expected.message || entry.valuePreserved !== true || entry.objectsPreserved !== true || entry.polluted !== false || JSON.stringify(entry.before) !== JSON.stringify(entry.after) || JSON.stringify(entry.beforeObjects) !== JSON.stringify(entry.afterObjects)) fail(`${entry.id} did not reject without document pollution`)
}
if (expectedFailures.size !== report.failures.length) fail('failure cases are not the locked set')
const disabled = report.disabled
if (disabled?.classification !== 'editor-read-only-and-python-immutable' || disabled.requested !== '750 mm/s^2' || disabled.status?.includes('Immutable') !== true || disabled.status.includes('ReadOnly') !== true || JSON.stringify(disabled.editorMode) !== '["ReadOnly"]' || disabled.exception?.type !== 'AttributeError' || disabled.exception.message !== "Object attribute 'Acceleration' is read-only" || disabled.valuePreserved !== true || disabled.objectsPreserved !== true || JSON.stringify(disabled.before) !== JSON.stringify(disabled.after) || JSON.stringify(disabled.beforeObjects) !== JSON.stringify(disabled.afterObjects) || JSON.stringify(disabled.restoredStatus) !== '[]' || JSON.stringify(disabled.restoredEditorMode) !== '[]') fail('disabled property state did not reject and restore cleanly')
const transaction = report.transaction
if (transaction?.undoMode !== 1 || transaction.pendingAfterEdit !== true || transaction.pendingAfterAbort !== false || transaction.activeAfterEdit?.name !== 'property-acceleration-cancel' || !(transaction.activeAfterEdit.id > 0) || transaction.activeAfterAbort?.name !== '' || transaction.activeAfterAbort?.id !== 0 || transaction.restored !== true || transaction.objectsRestored !== true || transaction.before?.numeric !== 1000 || transaction.edited?.numeric !== 250 || transaction.afterAbort?.numeric !== 1000 || JSON.stringify(transaction.objectsBefore) !== JSON.stringify(transaction.objectsAfter)) fail('transaction abort did not restore the property')
if (report.cancellationBoundary?.supported !== false || report.cancellationBoundary.classification !== 'synchronous-property-setter' || report.cancellationBoundary.reason !== 'no-native-cancel-hook' || report.cancellationBoundary.replacement !== 'abort-active-document-transaction') fail('cancellation boundary is not explicit')
if (report.documentIntegrity?.objectsPreserved !== true || report.documentIntegrity.objectCount !== 1 || JSON.stringify(report.documentIntegrity.initialObjects) !== JSON.stringify(report.documentIntegrity.finalObjects)) fail('failure, disabled or cancellation cases polluted the document')
console.log(JSON.stringify({ status: 'freecad-property-acceleration-failure-pass', failures: report.failures.map(({ id, exception }) => ({ id, exception })), disabled: { status: disabled.status, editorMode: disabled.editorMode, exception: disabled.exception }, transactionRestored: transaction.restored, documentObjectsPreserved: report.documentIntegrity.objectsPreserved, cancellationBoundary: report.cancellationBoundary }, null, 2))

View File

@@ -0,0 +1,24 @@
import { createHash } from 'node:crypto'
import { readFile, stat } from 'node:fs/promises'
import { resolve } from 'node:path'
const root = resolve(new URL('..', import.meta.url).pathname)
const sourcePath = resolve(root, '.cache/freecad/reference-desktop.json')
const reportPath = resolve(root, 'config/freecad-property-acceleration-inventory.json')
const fail = (message) => { throw new Error(`FreeCAD PropertyAcceleration inventory check failed: ${message}`) }
const [sourceContent, reportContent] = await Promise.all([readFile(sourcePath), readFile(reportPath)])
const source = JSON.parse(sourceContent)
const report = JSON.parse(reportContent)
const expectedSourceHash = createHash('sha256').update(sourceContent).digest('hex')
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.propertyType !== 'App::PropertyAcceleration' || report.classification !== 'opaque-fcstd-proxy') fail('report boundary is invalid')
if (report.baseline?.freecadVersion !== '1.1.1' || report.baseline?.commit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('baseline is not locked to FreeCAD 1.1.1')
if (report.source?.path !== '.cache/freecad/reference-desktop.json' || report.source.bytes !== sourceContent.length || report.source.sha256 !== expectedSourceHash) fail('source provenance is stale')
if (report.recordCount !== 1 || !Array.isArray(report.records) || report.records.length !== 1) fail('record count is not exactly one')
const [record] = report.records
if (record.objectTypeId !== 'Robot::TrajectoryDressUpObject' || record.objectAvailable !== true || record.probeStatus !== 'available' || record.propertyName !== 'Acceleration' || record.group !== 'TrajectoryDressUp' || JSON.stringify(record.status) !== '[]' || record.defaultRaw !== '1000.0 mm/s^2') fail('native property inventory changed')
if (record.valueModel?.kind !== 'quantity' || record.valueModel.dimension !== 'length/time^2' || record.valueModel.defaultValue !== 1000 || record.valueModel.defaultUnit !== 'mm/s^2') fail('quantity value model is invalid')
if (!Array.isArray(record.dependencies) || record.dependencies.length !== 0 || record.applicability?.requiredObjectTypeId !== record.objectTypeId) fail('dependencies or applicability are incomplete')
const nativeMatches = []
for (const objectType of source.runtimeObjects?.types ?? []) for (const property of objectType.properties ?? []) if (property.typeId === 'App::PropertyAcceleration') nativeMatches.push({ objectTypeId: objectType.typeId, propertyName: property.name, group: property.group, status: property.status, defaultRaw: property.default })
if (nativeMatches.length !== 1 || JSON.stringify(nativeMatches[0]) !== JSON.stringify({ objectTypeId: record.objectTypeId, propertyName: record.propertyName, group: record.group, status: record.status, defaultRaw: record.defaultRaw })) fail('report does not match the locked runtime oracle')
console.log(JSON.stringify({ status: 'freecad-property-acceleration-inventory-pass', propertyType: report.propertyType, recordCount: report.recordCount, objectTypeId: record.objectTypeId, defaultRaw: record.defaultRaw, classification: report.classification }, null, 2))

View File

@@ -0,0 +1,21 @@
import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
const root = resolve(new URL('..', import.meta.url).pathname)
const report = JSON.parse(await readFile(resolve(root, 'config/freecad-property-acceleration-mutation.json'), 'utf8'))
const fail = (message) => { throw new Error(`FreeCAD PropertyAcceleration mutation check failed: ${message}`) }
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-acceleration-mutation' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('baseline is invalid')
if (report.object?.name !== 'AccelerationProbe' || report.object.typeId !== 'Robot::TrajectoryDressUpObject' || report.property?.name !== 'Acceleration' || report.property.typeId !== 'App::PropertyAcceleration') fail('native object/property identity changed')
if (!(report.recompute?.initial > 0) || !(report.recompute.edit > 0) || !(report.recompute.restore > 0)) fail('initial, edit and restore were not recomputed')
if (report.touchedAfterEdit?.value?.numeric !== 500 || JSON.stringify(report.touchedAfterEdit.objectState) !== '["Touched"]' || report.touchedAfterEdit.mustExecute !== false) fail('edit did not preserve the native touched/MustExecute state before recompute')
const expectedValues = [['before', 1000], ['edited', 500], ['restored', 1000]]
for (const [phase, expected] of expectedValues) {
const snapshot = report[phase]
if (snapshot?.value?.numeric !== expected || typeof snapshot.value.unit !== 'string' || !snapshot.value.unit.includes('mm/s^2') || JSON.stringify(snapshot.propertyStatus) !== '[]' || JSON.stringify(snapshot.editorMode) !== '[]' || snapshot.source?.name !== 'SourceTrajectory' || snapshot.source.typeId !== 'Robot::TrajectoryObject' || snapshot.useAcceleration !== true || snapshot.shape?.applicable !== false || JSON.stringify(snapshot.objectState) !== '["Up-to-date"]' || snapshot.statusString !== 'Valid' || snapshot.mustExecute !== false) fail(`${phase} native semantic state is invalid`)
if (snapshot.trajectory?.waypointCount !== 2 || snapshot.trajectory.waypoints?.length !== 2 || snapshot.trajectory.waypoints.some((waypoint) => waypoint.acceleration !== expected)) fail(`${phase} waypoint acceleration semantics are invalid`)
}
if (report.before.trajectory.contentSha256 === report.edited.trajectory.contentSha256 || report.before.trajectory.contentSha256 !== report.restored.trajectory.contentSha256) fail('trajectory content did not change and restore exactly')
if (report.source?.preserved !== true || JSON.stringify(report.source.before) !== JSON.stringify(report.source.edited) || JSON.stringify(report.source.before) !== JSON.stringify(report.source.restored)) fail('source trajectory changed during dress-up mutation')
if (report.document?.objectsPreserved !== true || JSON.stringify(report.document.objectsBefore) !== JSON.stringify(report.document.objectsRestored) || report.document.objectsBefore?.length !== 2) fail('mutation polluted the document object set')
if (report.classification?.propertyChanged !== true || report.classification.trajectoryChanged !== true || report.classification.propertyRestored !== true || report.classification.trajectoryRestored !== true || report.classification.semanticStateRestored !== true || report.classification.geometry !== 'not-applicable-no-shape-property') fail('mutation/restore classification is incomplete')
console.log(JSON.stringify({ status: 'freecad-property-acceleration-mutation-pass', recompute: report.recompute, values: Object.fromEntries(expectedValues.map(([phase]) => [phase, report[phase].value.numeric])), waypointAccelerations: Object.fromEntries(expectedValues.map(([phase]) => [phase, report[phase].trajectory.waypoints.map((waypoint) => waypoint.acceleration)])), sourcePreserved: report.source.preserved, semanticStateRestored: report.classification.semanticStateRestored, geometry: report.classification.geometry }, null, 2))

View File

@@ -0,0 +1,27 @@
import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
const root = resolve(new URL('..', import.meta.url).pathname)
const load = (path) => readFile(resolve(root, path), 'utf8').then(JSON.parse)
const [report, semantics, progress, roundTrip, chrome] = await Promise.all([
load('config/freecad-property-acceleration-promotion.json'),
load('config/freecad-native-property-semantics.json'),
load('config/freecad-follow-up-task-progress.json'),
load('config/freecad-property-acceleration-roundtrip.json'),
load('config/chrome-property-acceleration-verification.json'),
])
const fail = (message) => { throw new Error(`FreeCAD PropertyAcceleration promotion check failed: ${message}`) }
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.taskId !== 'PROP-app-propertyacceleration-I' || report.propertyType !== 'App::PropertyAcceleration' || report.recordCount !== 1 || report.baseline?.freecadVersion !== '1.1.1' || report.baseline?.commit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.systemExact !== false) fail('promotion report boundary is invalid')
const requiredPhases = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
const completed = new Map(progress.completedTasks?.map((entry) => [entry.id, entry]) ?? [])
for (const phase of requiredPhases) {
const taskId = `PROP-app-propertyacceleration-${phase}`
if (!completed.has(taskId) || !Array.isArray(report.phaseEvidence?.[phase]) || report.phaseEvidence[phase].length === 0 || JSON.stringify(report.phaseEvidence[phase]) !== JSON.stringify(completed.get(taskId).evidence)) fail(`phase ${phase} evidence is incomplete`)
}
const propertyType = semantics.types?.find(({ typeId }) => typeId === report.propertyType)
if (report.promotion?.from !== 'opaque-fcstd-proxy' || report.promotion.to !== 'native-editable-codec' || propertyType?.support !== report.promotion.to || report.promotion.facadeValueModel !== 'finite-number-mm/s^2' || report.promotion.fcstdElement !== 'Float' || report.promotion.nativeRoundTripValue !== 500 || report.promotion.browserRoundTripValue !== 500 || report.promotion.zeroUnknownDrift !== true) fail('capability promotion is incomplete')
const sync = report.exactBlockerSync
if (sync?.nativeEditableTypes !== 30 || sync.nativeEditableRecords !== 4361 || sync.opaqueTypes !== 50 || sync.opaqueRecords !== 466 || sync.exactPromotionReady !== false || sync.exactBlocker !== '50 runtime property types and 466 records remain opaque-only; complete native document and property semantics') fail('exact blocker synchronization is stale')
if (JSON.stringify(sync) !== JSON.stringify({ nativeEditableTypes: semantics.supportSummary['native-editable-codec'].typeCount, nativeEditableRecords: semantics.supportSummary['native-editable-codec'].recordCount, opaqueTypes: semantics.supportSummary['opaque-fcstd-proxy'].typeCount, opaqueRecords: semantics.supportSummary['opaque-fcstd-proxy'].recordCount, exactPromotionReady: semantics.exactPromotionReady, exactBlocker: semantics.exactBlocker })) fail('promotion report diverges from global property semantics')
if (roundTrip.classification?.zeroUnknownDrift !== true || chrome.status !== 'pass' || chrome.persistence?.fcstdElement !== 'Float' || chrome.persistence.loadedValue !== 500 || chrome.resource?.released !== true || chrome.release?.workerTerminated !== true) fail('G/H closure evidence regressed')
console.log(JSON.stringify({ status: 'freecad-property-acceleration-promotion-pass', propertyType: report.propertyType, promotion: report.promotion, completedPhases: requiredPhases, exactBlockerSync: sync, systemExact: report.systemExact }, null, 2))

View File

@@ -0,0 +1,16 @@
import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
const root = resolve(new URL('..', import.meta.url).pathname)
const report = JSON.parse(await readFile(resolve(root, 'config/freecad-property-acceleration-roundtrip.json'), 'utf8'))
const fail = (message) => { throw new Error(`FreeCAD PropertyAcceleration roundtrip check failed: ${message}`) }
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-acceleration-roundtrip' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('baseline is invalid')
for (const phase of ['nativeInitial', 'nativeAfter']) {
const snapshot = phase === 'nativeInitial' ? report.nativeInitial : report.nativeAfter?.reopened
if (snapshot?.object?.typeId !== 'Robot::TrajectoryDressUpObject' || snapshot.object.propertyTypeId !== 'App::PropertyAcceleration' || snapshot.object.source?.typeId !== 'Robot::TrajectoryObject' || snapshot.object.useAcceleration !== true || JSON.stringify(snapshot.object.propertyStatus) !== '[]' || JSON.stringify(snapshot.object.editorMode) !== '[]' || snapshot.object.trajectory?.waypointCount !== 2 || snapshot.sourceTrajectory?.waypointCount !== 2) fail(`${phase} native object semantics are incomplete`)
}
if (report.nativeInitial.object.value.numeric !== 1000 || report.nativeInitial.object.trajectory.waypoints.some((waypoint) => waypoint.acceleration !== 1000) || report.nativeAfter.reopened.object.value.numeric !== 500 || report.nativeAfter.resaved.object.value.numeric !== 500 || report.nativeAfter.reopened.object.trajectory.waypoints.some((waypoint) => waypoint.acceleration !== 500) || report.nativeAfter.resaved.object.trajectory.waypoints.some((waypoint) => waypoint.acceleration !== 500)) fail('native initial/reopen/resave values drifted')
if (report.nativeAfter.reopened.sourceTrajectory.contentSha256 !== report.nativeAfter.resaved.sourceTrajectory.contentSha256 || report.nativeAfter.reopened.object.trajectory.contentSha256 !== report.nativeAfter.resaved.object.trajectory.contentSha256) fail('FreeCAD resave did not preserve native trajectory semantics')
if (report.web.before?.typeId !== 'App::PropertyAcceleration' || report.web.before?.element !== 'Float' || Number(report.web.before?.value) !== 1000 || report.web.after?.typeId !== 'App::PropertyAcceleration' || report.web.after?.element !== 'Float' || report.web.after?.value !== '500' || report.web.objectSetPreserved !== true || report.web.semanticObjectsPreserved !== true || report.web.opaqueEntriesPreserved !== true || !Number.isSafeInteger(report.web.opaquePathsPreserved) || report.web.opaquePathsPreserved < 0) fail('Web edit did not preserve native archive semantics')
if (report.classification?.webValue !== '500' || report.classification.reopenedValue !== 500 || report.classification.resavedValue !== 500 || report.classification.nativeOutputMatches !== true || report.classification.unknownSemanticDrift !== false || report.classification.zeroUnknownDrift !== true) fail('round-trip classification is not exact for PropertyAcceleration')
console.log(JSON.stringify({ status: 'freecad-property-acceleration-roundtrip-pass', values: { nativeInitial: report.nativeInitial.object.value.numeric, webEdited: Number(report.classification.webValue), nativeReopened: report.classification.reopenedValue, nativeResaved: report.classification.resavedValue }, opaquePathsPreserved: report.web.opaquePathsPreserved, semanticObjectsPreserved: report.web.semanticObjectsPreserved, zeroUnknownDrift: report.classification.zeroUnknownDrift }, null, 2))

View File

@@ -0,0 +1,17 @@
import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
const root = resolve(new URL('..', import.meta.url).pathname)
const report = JSON.parse(await readFile(resolve(root, 'config/freecad-property-acceleration-success.json'), 'utf8'))
const fail = (message) => { throw new Error(`FreeCAD PropertyAcceleration success check failed: ${message}`) }
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-acceleration-success' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('baseline is invalid')
if (report.object?.typeId !== 'Robot::TrajectoryDressUpObject' || report.property?.name !== 'Acceleration' || report.property?.typeId !== 'App::PropertyAcceleration' || report.property?.group !== 'TrajectoryDressUp') fail('native object/property identity changed')
if (report.diagnostics?.exception !== null || report.diagnostics?.documentObjectCount !== 1 || report.cases?.length !== 4) fail('native success cases are incomplete')
const byId = new Map(report.cases.map((entry) => [entry.id, entry]))
for (const id of ['default', 'nominal', 'lower-bound', 'negative-boundary']) if (!byId.has(id)) fail(`missing case ${id}`)
for (const entry of report.cases) {
if (entry.typeId !== 'App::PropertyAcceleration' || entry.group !== 'TrajectoryDressUp' || JSON.stringify(entry.status) !== '[]' || JSON.stringify(entry.editorMode) !== '[]' || entry.shape?.applicable !== false || !Array.isArray(entry.objectState)) fail(`${entry.id} native metadata is invalid`)
if (typeof entry.value?.unit !== 'string' || !entry.value.unit.includes('mm/s^2') || typeof entry.value.numeric !== 'number' || !Number.isFinite(entry.value.numeric)) fail(`${entry.id} quantity result is invalid`)
}
if (byId.get('default').value.numeric !== 1000 || byId.get('nominal').value.numeric !== 500 || byId.get('lower-bound').value.numeric !== 0 || byId.get('negative-boundary').value.numeric !== -500) fail('nominal or boundary values changed')
console.log(JSON.stringify({ status: 'freecad-property-acceleration-success-pass', cases: report.cases.length, nominal: byId.get('nominal').value, boundary: [byId.get('lower-bound').value, byId.get('negative-boundary').value] }, null, 2))

View File

@@ -0,0 +1,44 @@
import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
const root = resolve(new URL('..', import.meta.url).pathname)
const report = JSON.parse(await readFile(resolve(root, 'config/freecad-property-area-failure.json'), 'utf8'))
const fail = (message) => { throw new Error(`FreeCAD PropertyArea failure check failed: ${message}`) }
const same = (left, right) => JSON.stringify(left) === JSON.stringify(right)
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-area-failure' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('baseline is invalid')
if (report.object?.name !== 'AreaProbe' || report.object.typeId !== 'Measure::MeasureArea' || report.property?.name !== 'Area' || report.property.typeId !== 'App::PropertyArea' || report.input?.name !== 'Elements' || report.input.typeId !== 'App::PropertyLinkSubList') fail('native object/property identity changed')
if (report.initial?.numeric !== 10 || report.initial.statusString !== 'Valid' || !same(report.initial.state, ['Up-to-date']) || report.failures?.length !== 2) fail('initial state or failure case set changed')
const expectedFailures = new Map([
['unsupported-point', { name: 'AreaPoint', subElement: 'Vertex1', shapeType: 'Vertex' }],
['unsupported-line', { name: 'AreaLine', subElement: 'Edge1', shapeType: 'Edge' }],
])
for (const entry of report.failures) {
const expected = expectedFailures.get(entry.id)
if (!expected || entry.source?.name !== expected.name || entry.source.typeId !== 'Part::Feature' || entry.source.subElement !== expected.subElement || entry.source.shapeType !== expected.shapeType) fail(`${entry.id} source fixture changed`)
if (entry.expectedDiagnostic !== 'Cannot calculate area' || entry.assignmentException !== null || entry.recomputeException !== null || entry.recomputeResult !== true) fail(`${entry.id} native failure phase changed`)
if (entry.after?.numeric !== 10 || entry.after.statusString !== 'Cannot calculate area' || !same(entry.after.state, ['Touched', 'Invalid']) || !same(entry.after.elements, [{ object: expected.name, subElements: [expected.subElement] }])) fail(`${entry.id} did not enter the locked invalid state`)
if (entry.valuePreserved !== true || entry.objectsPreserved !== true || entry.recoveredExactly !== true || entry.recovered?.numeric !== 10 || entry.recovered.statusString !== 'Valid' || !same(entry.recovered.state, ['Up-to-date']) || !same(entry.recovered.elements, entry.before.elements) || !same(entry.beforeObjects, entry.afterObjects)) fail(`${entry.id} did not recover without document pollution`)
}
const disabled = report.disabled
if (disabled?.classification !== 'editor-readonly-python-mutable-until-immutable' || disabled.editorReadOnlyRequested !== '20 mm^2' || disabled.immutableRequested !== '30 mm^2' || !same(disabled.propertyStatus, ['24', '27']) || !same(disabled.editorMode, ['ReadOnly'])) fail('read-only property boundary changed')
if (disabled.editorReadOnlyException !== null || disabled.pythonBypassesEditorReadOnly !== true || disabled.editorReadOnlyAfter?.numeric !== 20 || !disabled.immutableStatus?.includes('Immutable') || disabled.immutableException?.type !== 'AttributeError' || disabled.immutableException.message !== "Object attribute 'Area' is read-only") fail('editor read-only and Immutable behavior changed')
if (disabled.immutableAfter?.numeric !== 20 || disabled.immutableValuePreserved !== true || disabled.valueRestored !== true || disabled.restored?.numeric !== 10 || disabled.restored.statusString !== 'Valid' || disabled.objectsPreserved !== true || !same(disabled.restoredStatus, ['24', '27']) || !same(disabled.restoredEditorMode, ['ReadOnly'])) fail('disabled state did not restore cleanly')
const transaction = report.transaction
if (transaction?.undoMode !== 1 || transaction.pendingAfterEdit !== true || transaction.pendingAfterAbort !== false || transaction.activeAfterEdit?.name !== 'property-area-cancel' || !(transaction.activeAfterEdit.id > 0) || transaction.activeAfterAbort?.name !== '' || transaction.activeAfterAbort?.id !== 0) fail('transaction lifecycle changed')
if (transaction.before?.numeric !== 10 || transaction.edited?.numeric !== 75.398223877 || transaction.afterAbort?.numeric !== 10 || transaction.afterRecompute?.numeric !== 10 || transaction.afterAbort.statusString !== 'Touched' || transaction.afterRecompute.statusString !== 'Valid' || transaction.restored !== true || transaction.objectsRestored !== true || !same(transaction.before.elements, transaction.afterRecompute.elements) || !same(transaction.objectsBefore, transaction.objectsAfter)) fail('transaction abort did not restore Elements and derived Area')
if (report.cancellationBoundary?.supported !== false || report.cancellationBoundary.classification !== 'synchronous-measure-recompute' || report.cancellationBoundary.reason !== 'no-native-cancel-hook' || report.cancellationBoundary.replacement !== 'abort-active-document-transaction') fail('cancellation boundary is not explicit')
if (report.documentIntegrity?.objectsPreserved !== true || report.documentIntegrity.objectCount !== 5 || !same(report.documentIntegrity.initialObjects, report.documentIntegrity.finalObjects)) fail('failure, disabled or cancellation cases polluted the document')
console.log(JSON.stringify({
status: 'freecad-property-area-failure-pass',
failures: report.failures.map(({ id, after }) => ({ id, state: after.state, diagnostic: after.statusString })),
disabled: { editorMode: disabled.editorMode, pythonBypassesEditorReadOnly: disabled.pythonBypassesEditorReadOnly, immutableException: disabled.immutableException },
transactionRestored: transaction.restored,
documentObjectsPreserved: report.documentIntegrity.objectsPreserved,
cancellationBoundary: report.cancellationBoundary,
}, null, 2))

View File

@@ -0,0 +1,25 @@
import { createHash } from 'node:crypto'
import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
const root = resolve(new URL('..', import.meta.url).pathname)
const report = JSON.parse(await readFile(resolve(root, 'config/freecad-property-area-inventory.json'), 'utf8'))
const fail = (message) => { throw new Error(`FreeCAD PropertyArea inventory check failed: ${message}`) }
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baseline?.freecadVersion !== '1.1.1' || report.baseline?.commit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.propertyType !== 'App::PropertyArea' || report.recordCount !== 1 || report.classification !== 'opaque-fcstd-proxy') fail('report boundary is invalid')
const [record] = report.records ?? []
if (record?.objectTypeId !== 'Measure::MeasureArea' || record.objectAvailable !== true || record.probeStatus !== 'available' || record.propertyName !== 'Area' || record.group !== 'Measurement' || JSON.stringify(record.status) !== JSON.stringify([24, 27]) || JSON.stringify(record.normalizedStatus) !== JSON.stringify(['PropReadOnly', 'PropOutput']) || record.defaultRaw !== '0.0 mm^2') fail('native property identity or status changed')
if (record.valueModel?.kind !== 'quantity' || record.valueModel.dimension !== 'length^2' || record.valueModel.defaultValue !== 0 || record.valueModel.defaultUnit !== 'mm^2' || record.valueModel.derived !== true || record.valueModel.writable !== false) fail('area value model is invalid')
const [input] = record.inputs ?? []
if (input?.propertyName !== 'Elements' || input.typeId !== 'App::PropertyLinkSubList' || input.group !== 'Measurement' || JSON.stringify(input.defaultValue) !== '[]' || input.scope !== 'Global' || input.allowExternal !== true || input.cardinality !== 'one-or-more') fail('native input contract is incomplete')
const [dependency] = record.dependencies ?? []
if (dependency?.sourceProperty !== 'Elements' || dependency.targetProperty !== 'Area' || dependency.relation !== 'link-sub-list' || dependency.effect !== 'immediate-recompute-on-change') fail('dependency contract is incomplete')
const applicability = record.applicability
if (applicability?.selectionMustBeNonEmpty !== true || applicability.everyElementMustBeValid !== true || JSON.stringify(applicability.supportedMeasureElementTypes) !== JSON.stringify(['PLANE', 'CYLINDER', 'SURFACE', 'VOLUME']) || JSON.stringify(applicability.unsupportedMeasureElementTypes) !== JSON.stringify(['INVALID', 'POINT', 'LINE', 'CURVE']) || applicability.externalDocumentElementsAllowed !== true) fail('selection applicability is incomplete')
if (record.execution?.aggregation !== 'sum-area' || record.execution.resultProperty !== 'Area' || record.execution.invalidGeometryDiagnostic !== 'Cannot calculate area' || record.execution.shape !== 'not-applicable-derived-measurement') fail('execution contract is incomplete')
for (const locked of [report.provenance?.runtime, ...(report.provenance?.sources ?? [])]) {
const content = await readFile(resolve(root, locked?.path ?? ''))
if (content.length !== locked.bytes || createHash('sha256').update(content).digest('hex') !== locked.sha256) fail(`provenance is stale for ${locked.path}`)
}
const sourceText = await readFile(resolve(root, '.cache/freecad/FreeCAD/src/Mod/Measure/App/MeasureArea.cpp'), 'utf8')
if (!sourceText.includes('Elements.setScope(App::LinkScope::Global)') || !sourceText.includes('Elements.setAllowExternal(true)') || !sourceText.includes('App::Prop_ReadOnly | App::Prop_Output') || !sourceText.includes('Cannot calculate area')) fail('locked native source no longer exposes the recorded contract')
console.log(JSON.stringify({ status: 'freecad-property-area-inventory-pass', propertyType: report.propertyType, objectTypeId: record.objectTypeId, defaultRaw: record.defaultRaw, statusNames: record.normalizedStatus, input: record.inputs[0], applicability: record.applicability, execution: record.execution }, null, 2))

View File

@@ -0,0 +1,49 @@
import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
import { isDeepStrictEqual } from 'node:util'
const root = resolve(new URL('..', import.meta.url).pathname)
const report = JSON.parse(await readFile(resolve(root, 'config/freecad-property-area-mutation.json'), 'utf8'))
const fail = (message) => { throw new Error(`FreeCAD PropertyArea mutation check failed: ${message}`) }
const same = isDeepStrictEqual
const near = (left, right, tolerance = 2e-6) => Math.abs(left - right) <= tolerance
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-area-mutation' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('baseline is invalid')
if (report.object?.name !== 'AreaProbe' || report.object.typeId !== 'Measure::MeasureArea' || report.property?.name !== 'Area' || report.property.typeId !== 'App::PropertyArea' || report.input?.name !== 'Elements' || report.input.typeId !== 'App::PropertyLinkSubList') fail('native object/property identity changed')
if (!(report.recompute?.initial > 0) || !(report.recompute.edit > 0) || !(report.recompute.restore > 0)) fail('initial, edit and restore were not recomputed')
const nominalElements = [{ object: 'AreaBox', typeId: 'Part::Box', subElements: ['Face1'] }]
const editedElements = [
{ object: 'AreaBox', typeId: 'Part::Box', subElements: ['Face1', 'Face2'] },
{ object: 'AreaCylinder', typeId: 'Part::Cylinder', subElements: ['Face1'] },
]
for (const [phase, expectedValue, expectedElements] of [
['before', 10, nominalElements],
['edited', 95.398223877, editedElements],
['restored', 10, nominalElements],
]) {
const snapshot = report[phase]
if (!near(snapshot?.value?.numeric, expectedValue) || typeof snapshot.value.unit !== 'string' || !snapshot.value.unit.includes('mm^2') || !same(snapshot.elements, expectedElements)) fail(`${phase} value or Elements changed`)
if (!same(snapshot.propertyStatus, ['24', '27']) || !same(snapshot.editorMode, ['ReadOnly']) || snapshot.shape?.applicable !== false || !same(snapshot.objectState, ['Up-to-date']) || snapshot.statusString !== 'Valid' || snapshot.mustExecute !== false) fail(`${phase} native semantic state is invalid`)
}
for (const [phase, expectedElements] of [['touchedAfterEdit', editedElements], ['touchedAfterRestore', nominalElements]]) {
const snapshot = report[phase]
if (!same(snapshot?.elements, expectedElements) || !same(snapshot.objectState, ['Touched']) || snapshot.mustExecute !== false) fail(`${phase} did not preserve the native dirty state before recompute`)
}
if (!near(report.touchedAfterEdit.value?.numeric, 95.398223877) || report.touchedAfterRestore.value?.numeric !== 10) fail('derived Area was not updated synchronously with Elements')
if (report.sources?.preserved !== true || !same(report.sources.before, report.sources.edited) || !same(report.sources.before, report.sources.restored) || report.sources.before?.length !== 2) fail('source geometry changed during Elements mutation')
for (const source of report.sources.before) if (source.valid !== true || source.shapeType !== 'Solid' || source.solids !== 1 || !(source.faces > 0) || !(source.area > 0) || !(source.volume > 0)) fail(`${source.name} source Shape evidence is invalid`)
if (report.document?.objectsPreserved !== true || !same(report.document.objectsBefore, report.document.objectsRestored) || report.document.objectsBefore?.length !== 3) fail('mutation polluted the document object set')
if (report.classification?.inputChanged !== true || report.classification.derivedValueChanged !== true || report.classification.inputRestored !== true || report.classification.derivedValueRestored !== true || report.classification.semanticStateRestored !== true || report.classification.sourceGeometryPreserved !== true || report.classification.geometry !== 'source-shapes-preserved-derived-measurement-has-no-shape') fail('mutation/restore classification is incomplete')
console.log(JSON.stringify({
status: 'freecad-property-area-mutation-pass',
recompute: report.recompute,
values: { before: report.before.value.numeric, edited: report.edited.value.numeric, restored: report.restored.value.numeric },
elements: { before: report.before.elements, edited: report.edited.elements, restored: report.restored.elements },
sourceGeometryPreserved: report.sources.preserved,
semanticStateRestored: report.classification.semanticStateRestored,
geometry: report.classification.geometry,
}, null, 2))

View File

@@ -0,0 +1,27 @@
import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
const root = resolve(new URL('..', import.meta.url).pathname)
const load = (path) => readFile(resolve(root, path), 'utf8').then(JSON.parse)
const [report, semantics, progress, roundTrip, chrome] = await Promise.all([
load('config/freecad-property-area-promotion.json'),
load('config/freecad-native-property-semantics.json'),
load('config/freecad-follow-up-task-progress.json'),
load('config/freecad-property-area-roundtrip.json'),
load('config/chrome-property-area-verification.json'),
])
const fail = (message) => { throw new Error(`FreeCAD PropertyArea promotion check failed: ${message}`) }
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.taskId !== 'PROP-app-propertyarea-I' || report.propertyType !== 'App::PropertyArea' || report.recordCount !== 1 || report.baseline?.freecadVersion !== '1.1.1' || report.baseline?.commit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.systemExact !== false) fail('promotion report boundary is invalid')
const requiredPhases = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
const completed = new Map(progress.completedTasks?.map((entry) => [entry.id, entry]) ?? [])
for (const phase of requiredPhases) {
const taskId = `PROP-app-propertyarea-${phase}`
if (!completed.has(taskId) || !Array.isArray(report.phaseEvidence?.[phase]) || report.phaseEvidence[phase].length === 0 || JSON.stringify(report.phaseEvidence[phase]) !== JSON.stringify(completed.get(taskId).evidence)) fail(`phase ${phase} evidence is incomplete`)
}
const propertyType = semantics.types?.find(({ typeId }) => typeId === report.propertyType)
if (report.promotion?.from !== 'opaque-fcstd-proxy' || report.promotion.to !== 'native-editable-codec' || propertyType?.support !== report.promotion.to || propertyType.statusNames?.join(',') !== 'PropOutput,PropReadOnly' || report.promotion.facadeValueModel !== 'read-only-derived-mm^2-with-link-sub-list-input' || report.promotion.inputType !== 'App::PropertyLinkSubList' || report.promotion.fcstdAreaElement !== 'Float' || report.promotion.fcstdElementsElement !== 'LinkSubList' || report.promotion.nativeRoundTripArea !== 20 || report.promotion.browserRoundTripArea !== 0 || report.promotion.browserRoundTripElementCount !== 0 || report.promotion.sourceGeometryPreserved !== true || report.promotion.zeroUnknownDrift !== true) fail('capability promotion is incomplete')
const sync = report.exactBlockerSync
if (sync?.nativeEditableTypes !== 30 || sync.nativeEditableRecords !== 4361 || sync.opaqueTypes !== 50 || sync.opaqueRecords !== 466 || sync.exactPromotionReady !== false || sync.exactBlocker !== '50 runtime property types and 466 records remain opaque-only; complete native document and property semantics') fail('exact blocker synchronization is stale')
if (JSON.stringify(sync) !== JSON.stringify({ nativeEditableTypes: semantics.supportSummary['native-editable-codec'].typeCount, nativeEditableRecords: semantics.supportSummary['native-editable-codec'].recordCount, opaqueTypes: semantics.supportSummary['opaque-fcstd-proxy'].typeCount, opaqueRecords: semantics.supportSummary['opaque-fcstd-proxy'].recordCount, exactPromotionReady: semantics.exactPromotionReady, exactBlocker: semantics.exactBlocker })) fail('promotion report diverges from global property semantics')
if (roundTrip.classification?.zeroUnknownDrift !== true || roundTrip.classification.sourceGeometryPreserved !== true || chrome.status !== 'pass' || chrome.ui?.areaReadOnly !== true || chrome.persistence?.fcstdAreaElement !== 'Float' || chrome.persistence.fcstdElementsElement !== 'LinkSubList' || chrome.persistence.loadedArea !== 0 || chrome.persistence.loadedElementCount !== 0 || chrome.resource?.released !== true || chrome.release?.workerTerminated !== true) fail('G/H closure evidence regressed')
console.log(JSON.stringify({ status: 'freecad-property-area-promotion-pass', propertyType: report.propertyType, promotion: report.promotion, completedPhases: requiredPhases, exactBlockerSync: sync, systemExact: report.systemExact }, null, 2))

Some files were not shown because too many files have changed in this diff Show More