OCCT + FreeCAD Runtime Architecture Audit¶
Operational source:
D:\02_Code\45_merged_macos_colabui_dfmanim\docs\contracts\occt-freecad-runtime-architecture-audit.mdScope: curated mirror of the current mixed FreeCAD + OCCT runtime audit. A no-FreeCAD architecture is intentionally left for a separate branch.
This audit documents the current mixed CAD runtime architecture in this repo. It covers the implemented FreeCAD + OCCT behavior only. A no-FreeCAD architecture is intentionally out of scope here and should be handled in a separate branch.
Code references are relative to the repository root.
Kernel Split Summary¶
| Area | Current runtime | Primary code/artifact | What it does | If FreeCAD is removed today | Evidence |
|---|---|---|---|---|---|
| Browser preview render | FreeCAD + trimesh | server/cad_service.py, preview.glb |
Loads CAD through Part.read, tessellates FreeCAD shapes, exports a GLB preview for Three.js |
Upload preview breaks until an OCCT GLB preview exporter replaces it | server/cad_service.py:93-137, server/cad_service.py:287-369, web/src/components/ModelViewer.tsx:1945-1974 |
| Canonical/selectable scene | OCCT/pythonOCC | server/canonical_scene_service.py, scene.json, scene_components/*.json |
Loads STEP through OCCT, resolves components, builds face/edge inventories, feature refs, face batches, edge batches | Mostly survives conceptually, but worker runtime setup must stop depending on FreeCAD Python discovery | server/canonical_scene_service.py:247-300, server/canonical_scene_service.py:523-622, server/canonical_scene_service.py:746-781, server/canonical_scene_warmup.py:376-383 |
| DFM light/deep geometry facts | OCCT/pythonOCC | server/part_facts.py, server/cnc_geometry_occ.py, Part Facts JSON |
Extracts topology, face inventory, holes, pockets, CNC corners, internal radii, then maps facts to DFM inputs | STEP DFM can survive if pythonOCC is packaged independently; IGES/DXF still need separate loader/bridge work | server/part_facts.py:1473-1603, server/part_facts.py:1847-2026, server/cnc_geometry_occ.py:4018-4103, server/dfm_part_facts_bridge.py:67-202 |
| OCC orthographic views | OCCT/pythonOCC | server/cad_service_occ.py, occ_views/*.png |
Uses OCCT HLR to generate projection PNGs | Survives if pythonOCC runtime is available | server/cad_service_occ.py:45-88, server/cad_service_occ.py:216-243, server/main.py:4331-4355 |
| FreeCAD Shape2D/isometric views | FreeCAD Draft + FreeCAD mesh projection | server/cad_service.py, shape2d, isometric_shape2d, isometric_matplotlib |
Generates drafting-style or projected 2D view artifacts | Breaks unless ported to OCCT HLR or retired | server/cad_service.py:413-550, server/main.py:4072-4088, server/main.py:4391-4447 |
| Candidate/remediation geometry | FreeCAD | server/dfm_candidate_geometry_worker.py, candidate STEP |
Applies simple booleans, cylinders, fillets, fuses, and STEP export for candidate sessions | Breaks until ported to raw OCCT modeling/export APIs | server/dfm_candidate_geometry_worker.py:62-100, server/dfm_candidate_geometry_worker.py:176-183, server/dfm_candidate_geometry_worker.py:230-237, server/dfm_candidate_geometry_worker.py:273, server/dfm_candidate_geometry_worker.py:324-325 |
| Collaboration comments and pins | Browser + backend storage; geometry source can be FreeCAD or OCCT | web/src/components/ModelViewer.tsx, web/src/components/CollaborationWorkspace.tsx, server/review_store.py |
Emits pin payloads from viewer, posts tickets/reviews, stores pin data | Can keep working if preview/canonical coordinates and component IDs remain stable | web/src/components/ModelViewer.tsx:566-609, web/src/components/ModelViewer.tsx:1953-1985, web/src/components/CollaborationWorkspace.tsx:1262-1299, server/review_store.py:18-35, server/review_store.py:69-95 |
| Runtime discovery | FreeCAD-oriented | server/freecad_setup.py |
Finds FreeCAD libraries, FreeCAD Python, and optionally probes OCC in that runtime |
Must be replaced by an OCCT/pythonOCC runtime setup before FreeCAD can be retired | server/freecad_setup.py:119-136, server/freecad_setup.py:173-209, server/freecad_setup.py:212-239 |
Findings Validation¶
| Finding | Status | Evidence | Practical consequence |
|---|---|---|---|
| Fast rendering and fast feature detection are too tightly coupled | Partially confirmed | Preview upload is separate/backgrounded: server/main.py:3976-4045; docs say preview is ready before canonical: docs/contracts/canonical_scene_pipeline.md:41-42. But canonical component detail couples face inventory, edge inventory, detectors, feature refs, face batches, and edge batches: server/canonical_scene_service.py:523-622. |
Users can get a first GLB preview, but selectable/canonical geometry can still wait on semantic extraction work. |
Intended architecture is preview first, canonical second |
Confirmed | Contract says this directly: docs/contracts/canonical_scene_pipeline.md:3-5, docs/contracts/canonical_scene_pipeline.md:121-136. UI renders preview and overlays canonical when ready: web/src/components/ModelViewer.tsx:1333-1442, web/src/components/ModelViewer.tsx:1945-2007. |
This is the right large-model direction; keep it. |
| Canonical component detail does too much in one pass | Confirmed | _build_component_scene builds faces, edges, detectors, feature refs, face batches, and edge batches in one call. |
One slow exact step delays all canonical usability for that component. Evidence: server/canonical_scene_service.py:523-622. |
| Exact edge extraction is a hotspot | Partially confirmed | Edge inventory samples/measures edges: server/canonical_scene_service.py:693-744, server/canonical_scene_service.py:1057-1084; face batches remesh component geometry: server/canonical_scene_service.py:746-760. "Major hotspot" is inferred because canonical per-stage timings are not recorded. |
Edge-heavy parts likely make selectable detail feel stuck. Add timing before optimizing blindly. |
| Canonical warmup is serial for requested components | Confirmed | Worker loops requested components one-by-one. | A selected component can wait behind earlier requested components in the same warmup request. Evidence: server/canonical_scene_warmup.py:490-531. |
| Deep Part Facts budgets exist but are not true stop conditions | Confirmed | Budgets/statuses exist: server/dfm_scanner_plan.py:46-88; Part Facts only records overtime: server/part_facts.py:1220-1279; warmup calls extraction directly without timeout enforcement: server/part_facts_warmup.py:490-502. |
Deep scans can continue long after the UI thinks they exceeded budget. |
| Large-part failure likely combines heavy canonical detail and deep Part Facts | Partially confirmed | Canonical heavy path: server/canonical_scene_service.py:523-622; deep scanners include exact inventory, CNC corner, internal radii: server/dfm_scanner_plan.py:236-241, server/dfm_scanner_plan.py:302-308; extraction paths: server/part_facts.py:1847-2026. Causality is inferred. |
Large parts have two independent expensive background workloads competing for responsiveness. |
| Viewer and DFM are sibling flows over same geometry/component identity | Confirmed | Upload returns preview/source/components plus optional scene URL: server/main.py:4026-4049; viewer uses preview/canonical: web/src/components/ModelViewer.tsx:1945-2007; DFM resolves Part Facts from model/component: server/main.py:1368-1447. |
Viewer fixes do not automatically fix DFM, and DFM should not depend on canonical scene payloads. |
| DFM consumes Part Facts/extracted facts, not canonical scene payloads | Confirmed | Main builds extracted_part_facts from Part Facts: server/main.py:1420-1447; DFM job does the same: server/dfm_review_pipeline.py:561-625, server/dfm_review_pipeline.py:690-713; bridge maps Part Facts to extracted facts: server/dfm_part_facts_bridge.py:67-202. |
DFM reliability work belongs in Part Facts/scanners/planning, not canonical scene rendering. |
| CoLab using HOOPS is unverified | Not confirmed | Repo search found no HOOPS, Tech Soft, or Communicator references. Rendering evidence points to FreeCAD/trimesh/GLB, OCCT analysis, and Three.js. |
Treat HOOPS as external/product inference only, not a code-backed fact. Evidence: server/cad_service.py:287-369, web/src/components/ModelViewer.tsx:1945-2007. |
Runtime Audit Table¶
| User action | Format | Pipeline stage | Primary file/artifact | Key code path | Purpose | Dependencies | Current bottleneck or limitation | Recommended improvement | Likely code changes | UX impact | If removed | Evidence |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| User imports a STEP file | STEP/STP | Upload, format gate, preview build | source .step/.stp, preview.glb, metadata.json |
upload_model -> model_store.create -> cad_service.import_model |
Create model, preview, components, then prewarm Part Facts/canonical | FreeCAD Part.read, FreeCAD tessellation, trimesh |
Preview generation is synchronous before response | Keep preview/exact extraction decoupled; add OCCT preview parity before retiring FreeCAD | server/main.py, server/cad_service.py, future OCCT preview service |
First usable model depends on GLB export time | No upload preview/components | server/main.py:3963-4050, server/cad_service.py:287-369, server/model_store.py:147-181 |
| User imports IGS/IGES | IGS/IGES | Preview/comment-only import policy | source .igs/.iges, maybe preview.glb |
format policy allows viewer/comments, blocks canonical/DFM | Let users view/comment non-STEP CAD | FreeCAD import support today; explicit bridge needed for exact path | Exact path still uses STEP-centric loaders; no bridge cache | Add format-aware loader branches and explicit IGES -> STEP bridge cache | cad_import_formats.py, preview loader, canonical/Part Facts loaders, model store bridge artifact |
Users can inspect/comment IGES, but DFM/canonical remain blocked unless bridged | IGES becomes unsupported or misleading | server/cad_import_formats.py:78-93, server/main.py:4021-4049, docs/validation/cad-format-import-eval.md:42-44, docs/validation/cad-format-import-eval.md:100-107 |
| User imports DXF | DXF | Format gate | none | unknown extension fallback, HTTP 415 | Block unsupported CAD | detect_cad_format |
No DXF policy, no loader branch | Add DXF policy only if product wants 2D/vector preview/comment path | server/cad_import_formats.py, upload validation, possible 2D viewer |
User gets unsupported-format failure today | If fallback removed, DXF behavior becomes accidental | server/cad_import_formats.py:199-207, server/main.py:3968-3970 |
| User sees first preview render | STEP/STP; IGES if importer succeeds | Runtime preview rendering | preview.glb |
frontend loads preview artifact and renders ModelContents |
Fast visual feedback | GLB URL, Three.js scene | Preview waits for server GLB generation; exact canonical overlay is separate | Preserve browser viewer; replace only the backend preview generator when migrating off FreeCAD | server/cad_service.py, new OCCT preview exporter, ModelViewer.tsx unchanged if GLB contract holds |
Faster perceived load if preview remains cheap | No initial visual model | server/main.py:4091-4100, web/src/components/ModelViewer.tsx:1127-1142, web/src/components/ModelViewer.tsx:1945-1974 |
| User waits for canonical/selectable geometry | STEP/STP only | Manifest and component detail warmup | scene.json, scene_status.json, scene_components/*.json |
canonical warmup worker -> manifest -> component detail | Topology identity, selectable faces/edges, feature refs | OCCT STEP source, analyzer, cache files | Component detail bundles exact semantics and render batches | Stage as preview mesh -> selectable faces -> feature hints -> exact specialty metrics |
Split _build_component_scene; add detail levels/status fields |
Selection appears earlier | No face/edge selection or DFM anchors | docs/contracts/canonical_scene_pipeline.md:87-150, server/canonical_scene_warmup.py:429-573, server/canonical_scene_service.py:523-622 |
| User selects a component | STEP/STP canonical; preview all supported viewer formats | Focus and selected-component warmup | component node name, canonical component JSON | frontend queues warmup for focused component | Make selected component selectable/canonical first | component identity from import | Requested components in one worker are serial | Prioritize selected-component-first warmup, supersede stale queues | canonical_scene_warmup.py, ModelViewer.tsx warmup request ordering |
Less waiting after click | Component selection becomes preview-only | web/src/components/ModelViewer.tsx:1578-1602, server/canonical_scene_warmup.py:490-531 |
| User selects a face/edge | STEP/STP canonical only | Selection resolution | canonical component scene | /scene/resolve-selection |
Map click/face/edge to topology identity/features | ready component scene | Original model path returns 409 if detail missing | Return partial resolution when selectable faces are ready; defer exact edge facts | server/main.py, canonical_scene_service.py |
Earlier selection feedback | Feature anchoring loses topology identity | server/main.py:4228-4284, server/canonical_scene_service.py:451-513 |
| User opens Part Facts | STEP/STP DFM-capable models | Cache read/status/warmup | Part Facts JSON/status | frontend GET facts/status, may enqueue warmup | Show measured/inferred geometry facts | PartFactsService, OCCT geometry analyzer |
Initial GET only returns cache; background warmup is light | Keep light default; expose clear deep refresh when needed | ModelViewer.tsx, main.py, part_facts_warmup.py |
Facts panel appears progressively | DFM loses extracted fact source | web/src/components/ModelViewer.tsx:1662-1805, server/main.py:2765-2818 |
| User refreshes Part Facts | STEP/STP | Forced warmup | Part Facts request/status/cache | POST refresh -> enqueue | Recompute facts | background subprocess | Refresh always enqueues geometry_scan_depth="light" from endpoint helper |
Add explicit depth param; default large parts to topology_light |
server/main.py, Part Facts API contract, UI button |
Users understand light vs deep cost | Stale facts remain | server/main.py:876-889, server/main.py:2804-2818, web/src/components/ModelViewer.tsx:1705-1724 |
| User runs DFM light | STEP/STP | DFM job, planning, Part Facts light | DFM job status, Part Facts, review payload | sidebar job POST -> run_job -> Part Facts bridge -> rules |
Generate manufacturability review | scanner plan, Part Facts cache, profile | Light still may run nontrivial topology/feature inventory | Cost heuristic: face/edge/component complexity, not face-count only | dfm_scanner_plan.py, part_facts.py, dfm_review_pipeline.py |
More reliable first-pass DFM | No automated review | web/src/components/DfmSidebar.tsx:2232-2298, server/dfm_review_pipeline.py:454-771, server/dfm_scanner_plan.py:269-330 |
| User runs DFM deep | STEP/STP | Exact extraction + DFM rules | exact Part Facts, extracted facts | deep context requests exact inventory/CNC/internal radii | Richer evidence for corners/radii/plastics | OCCT analyzers and caches | Budgets are metadata; exact scans can overrun | Make budgets real timeout/overtime controls; reuse one exact face inventory | part_facts.py, part_facts_warmup.py, cnc_geometry_occ.py |
Deep review finishes or degrades predictably | Deep DFM becomes unavailable | web/src/components/DfmSidebar.tsx:2511-2529, server/part_facts.py:1473-1603, server/part_facts.py:1847-2026, server/dfm_scanner_plan.py:72-88 |
| User comments or anchors geometry | STEP/STP, IGES viewer/comment; mesh viewer/comment | Pin/comment overlay | reviews.json, tickets/design reviews |
viewer emits pin -> workspace POSTs ticket -> store persists pin | Collaboration comments anchored to model coordinates/topology when available | preview/canonical hit payload, auth/share checks | Topology anchors depend on format/canonical readiness; mesh anchors are separate capability | Keep format-aware anchor capability visible in UI; preserve coordinate and component contracts in any OCCT preview migration | cad_import_formats.py, viewer pin payloads, review store |
Comments work even when DFM is unavailable | Collaboration review loses spatial context | server/cad_import_formats.py:21-59, web/src/components/ModelViewer.tsx:566-609, web/src/components/CollaborationWorkspace.tsx:1262-1299, server/review_store.py:69-95 |
| User previews DFM candidate/remediation | STEP/STP | Candidate session/viewer path | candidate scene/session | sidebar creates candidate session; worker may materialize candidate STEP | Compare proposed fix geometry | FreeCAD candidate mutation worker today; viewer scene path | Candidate mutation is FreeCAD-dependent | Port candidate mutation separately or preserve FreeCAD until candidate branch is replaced | dfm_candidate_geometry.py, dfm_candidate_geometry_worker.py, candidate scene endpoints |
Candidate previews fail if FreeCAD disappears too early | Remediation UX disappears | web/src/components/DfmSidebar.tsx:2448-2496, server/dfm_candidate_geometry.py:77-109, server/dfm_candidate_geometry_worker.py:62-100 |
Improvement Matrix¶
| Improvement | Applies to which user actions/stages | Core files/services touched | Why this helps | Expected UX gain | Technical risk / downside | Recommended implementation approach | Priority | Evidence |
|---|---|---|---|---|---|---|---|---|
Stage canonical detail as preview mesh -> selectable faces -> feature hints -> exact specialty metrics |
canonical wait, component select, face/edge select | canonical_scene_service.py, canonical_scene_warmup.py, ModelViewer.tsx |
Removes feature/edge extraction from the critical selectable path | Faster clickable model | Requires cache/version contract changes | Add detail_level artifacts and progressive status per component |
P0 | server/canonical_scene_service.py:523-622, docs/contracts/canonical_scene_pipeline.md:121-150 |
| Defer exact edge extraction | canonical detail, selection | canonical_scene_service.py |
Edge sampling/radius/bounds work is expensive and not always needed immediately | Earlier face selection; less blocked warmup | Edge-specific anchors may arrive later | Build face batches first; compute edge inventory on demand or after idle | P0 | server/canonical_scene_service.py:693-744, server/canonical_scene_service.py:1057-1084 |
| Prioritize selected-component-first warmup | component select, canonical wait | canonical_scene_warmup.py, ModelViewer.tsx |
Current worker serializes requested components | Selected component becomes ready first | Queue coordination complexity | Supersede stale requests; process focused component before prefetch list | P1 | server/canonical_scene_warmup.py:490-531, web/src/components/ModelViewer.tsx:1578-1602 |
| Make scanner budgets real timeout/overtime controls | Part Facts refresh, DFM deep | dfm_scanner_plan.py, part_facts.py, part_facts_warmup.py |
Budgets currently describe work but do not stop it | DFM returns degraded results instead of hanging | OCC calls may not be interruptible in-process | Run heavy scanners in cancellable subprocesses or checkpointed loops; mark partial facts | P0 | server/dfm_scanner_plan.py:72-88, server/part_facts.py:1220-1279 |
Default large parts to topology_light unless exact scans are required |
Part Facts, DFM light/deep | dfm_scanner_plan.py, part_facts.py, DfmSidebar.tsx |
Avoids accidental exact scans on costly parts | More reliable first review | Some findings may be lower confidence | Use process/profile/evidence needs plus complexity heuristic | P0 | server/dfm_scanner_plan.py:211-250, server/dfm_scanner_plan.py:269-330, web/src/components/DfmSidebar.tsx:2511-2529 |
| Reuse one exact face inventory across downstream detectors | canonical, Part Facts deep, DFM | cnc_geometry_occ.py, part_facts.py, possibly canonical cache |
Face inventory is rebuilt for exact detectors | Less duplicated OCCT traversal | Cache invalidation/versioning | Promote inventory artifact with profile/depth/version keys | P1 | server/cnc_geometry_occ.py:4180-4360, server/cnc_geometry_occ.py:4364-4481, server/part_facts.py:1495-1547 |
| Replace face-count-only fallback with cost heuristic | canonical large components, DFM scan planning | canonical_scene_service.py, dfm_scanner_plan.py, part_facts.py |
MAX_DETAILED_FACE_COUNT ignores edge count, curve complexity, and triangles |
Better large-part behavior | Needs telemetry to tune | Compute cost from face count, edge records, triangle count, bbox/features | P1 | server/canonical_scene_service.py:28, server/canonical_scene_service.py:525-533, server/cad_service.py:325-331 |
| Add format-aware source/loader branches | STEP, IGES, mesh, future DXF | cad_import_formats.py, cad_service.py, cad_service_occ.py, canonical_scene_service.py, part_facts.py |
Current exact services are STEP-centric | Fewer confusing format failures | More code paths to validate | Introduce loader interface: preview loader, exact STEP loader, bridge loader | P1 | server/cad_import_formats.py:21-59, server/cad_service_occ.py:61-69, docs/validation/cad-format-import-eval.md:100-107 |
| Add explicit IGES -> STEP bridge caching | IGES canonical/DFM | model store, bridge service, canonical/Part Facts services | IGES preview can be separate from exact analysis | Makes IGES DFM possible without pretending native support | Conversion quality and cache storage | Store bridged STEP artifact with checksum/source format metadata | P2 | server/cad_import_formats.py:78-93, docs/validation/cad-format-import-eval.md:42-44, docs/validation/cad-format-import-eval.md:100-107 |
| Keep preview render and exact semantic extraction decoupled | upload, preview, canonical, DFM | main.py, ModelViewer.tsx, docs |
This is already intended and partly implemented | Preserves first-render speed | Regression risk if new features call exact paths during upload | Add tests/contract checks that upload success only requires preview | P0 | docs/contracts/canonical_scene_pipeline.md:3-5, docs/contracts/canonical_scene_pipeline.md:41-42, server/main.py:4021-4024 |
| Replace FreeCAD preview with OCCT preview only after parity checks | upload, preview, comments, canonical overlay | new OCCT preview service, cad_service.py, model_store.py, ModelViewer.tsx |
Retires the biggest FreeCAD dependency without changing the web collaboration shell | Cleaner runtime and consistent geometry identity | Component order, meshing, units, and GLB output can drift | Add OCCT preview behind a flag; compare GLB nonblank, component count/order, triangle counts, pins, selected component | P1 | FreeCAD preview: server/cad_service.py:287-369; OCCT canonical mesh proof: server/canonical_scene_service.py:746-781 |
| Keep candidate geometry as a separate migration track | DFM candidate/remediation | dfm_candidate_geometry.py, dfm_candidate_geometry_worker.py |
Candidate mutation is the most FreeCAD-specific path | Avoids blocking preview/DFM cleanup on remediation port | Temporary mixed runtime remains | Port booleans/fillets/STEP export to OCCT only in the no-FreeCAD branch | P2 | server/dfm_candidate_geometry_worker.py:62-100, server/dfm_candidate_geometry_worker.py:176-183, server/dfm_candidate_geometry_worker.py:273 |
FreeCAD Retirement Assessment¶
| Question | Current answer | Evidence | Risk |
|---|---|---|---|
| Can the app still render if FreeCAD is removed? | Not yet. The main browser preview GLB is FreeCAD-backed today. | server/cad_service.py:93-137, server/cad_service.py:287-369 |
High until an OCCT preview exporter produces the same ImportResult and preview.glb contract. |
| Can DFM light/deep still run? | Yes for STEP in principle, because DFM facts are already OCCT-backed. Runtime setup still needs cleanup. | server/part_facts.py:1473-1603, server/part_facts.py:1847-2026, server/cnc_geometry_occ.py:4018-4103 |
Medium. Packaging/runtime risk is larger than algorithmic risk for STEP. |
| Can collaboration still work? | Yes, if preview/canonical coordinates, component node names, and anchor payloads stay stable. | web/src/components/ModelViewer.tsx:566-609, web/src/components/CollaborationWorkspace.tsx:1262-1299, server/review_store.py:69-95 |
Medium. Identity drift would make old pins or selected components point to the wrong geometry. |
| Can IGES become DFM-capable just by using OCCT? | Not automatically. The current exact loaders are STEP-centric. | server/cad_import_formats.py:78-93, server/cnc_geometry_occ.py:4098-4103 |
Medium. Needs IGESControl_Reader support or bridge caching. |
| Can DXF be supported by retiring FreeCAD? | No. DXF is currently unsupported and has no loader policy. | server/cad_import_formats.py:199-207, server/main.py:3968-3970 |
Product decision plus separate 2D/vector implementation. |
Top 5 Highest-ROI Changes¶
-
Make scanner budgets real and degrade deep Part Facts gracefully. This is the highest DFM reliability win. It is an architectural change because heavy OCCT work may need subprocess cancellation or checkpointing.
-
Stage canonical component detail and defer exact edge extraction. This is the highest viewer responsiveness win for large models. It is architectural, but the boundary is already documented.
-
Add selected-component-first canonical warmup. This is a relatively safe refactor: change queue ordering/status behavior before redesigning all canonical artifacts.
-
Default large parts to
topology_lightusing a real cost heuristic. This is a safe-to-moderate refactor if introduced as planning policy first, then tuned with telemetry. -
Add an OCCT preview service behind a flag before removing FreeCAD. This is the key bridge from the current mixed architecture to a future no-FreeCAD branch. It is architectural because component identity, GLB output, and collaboration pins must remain stable.
Sources¶
- Repo-local audit:
D:\02_Code\45_merged_macos_colabui_dfmanim\docs\contracts\occt-freecad-runtime-architecture-audit.md - Runtime repo commit:
1dad556(docs: add OCCT FreeCAD runtime architecture audit) - Active runtime repo:
D:\02_Code\45_merged_macos_colabui_dfmanim