# DesignIR Pipeline This directory owns the STEP reconstruction and distillation boundary: ```text teacher STEP -> deterministic OCCT extraction into DesignIR 3.0 -> SurfaceIR: independent geometry/topology program -> Semantic FeatureIR: canonical names, features and constraints -> isolated OCCT compiler rebuilds STEP without teacher access -> reconstruction/distillation agent proposes repairs and semantic bindings -> acceptance agent compares geometry and executes parameter perturbations -> deterministic publisher promotes repeated validated experience ``` ## Security boundary | Component | Teacher STEP | Private evidence | DesignIR | Rebuilt STEP | | --- | --- | --- | --- | --- | | Ingestion service | read | write | no | no | | Reconstruction agent | denied | read | write | request compilation/edit | | Isolated compiler | denied | no | read | write | | Acceptance agent | read | read | read | read | | Publisher | denied | aggregate only | schema only | reports only | The reconstruction environment must remain functional after the teacher STEP is removed. `scripts/designir_pipeline.py anti-cheat` rejects source STEP references, imported B-Reps, embedded meshes, topology references, and generator source that calls STEP import APIs. ## Data layout The operator-facing layout has only three directories: ```text designir-pipeline/ input/ drop source STEP/STP files here runs/ all private process artifacts output/library.json verified experience consumed at runtime output/distillation-report.json public aggregate result and validation state ``` `input/` and `runs/` are ignored by Git. Only the deterministic result in `output/` is versioned. The pipeline creates these private run directories as needed: | Local path | Purpose | | --- | --- | | `runs/evidence/` | Deterministic evidence extracted from source STEP. | | `runs/designir/` | DesignIR authored by Reconstruction Agent. | | `runs/rebuilt/` | STEP rebuilt without access to source STEP. | | `runs/acceptance/` | Independent geometry and editability reports. | | `runs/review/` | Sanitized semantic batches and untrusted drafts. | | `runs/quarantine/` | Failures and unsupported feature vocabulary. | The shallow directory structure is for usability, not authorization. Agent and compiler access is enforced by their contracts and by anti-cheat checks. ## DesignIR contracts `contracts/designir-3.0.schema.json` is the authoritative contract for both text/image semantic authoring and uploaded-STEP reconstruction. `contracts/designir-2.0.schema.json` remains only for legacy migration. DesignIR 3.0 combines: - an executable OCCT SurfaceIR for independent geometric reconstruction; - a Semantic FeatureIR for paper-style names such as `plate_thickness`, `hole_diameter`, `hole_spacing`, `bolt_circle_diameter`, and `rib_count`; - explicit edit operations and acceptance contracts. STEP does not contain the original sketch, parameter names, feature tree, or construction history. Extraction therefore keeps a strict epistemic boundary: - analytic surfaces, axes, radii, topology, and bounds are observed evidence; - feature instances, semantic names, constraints, and datums are inferred hypotheses with confidence; - canonical stages are recommended reconstruction order, never recovered source history; - a hypothesis becomes trusted DesignIR only after isolated compilation, geometry comparison, and targeted parameter-edit validation. The private evidence names editable candidates using a stable vocabulary such as `plate_thickness`, `hole_diameter`, `hole_spacing`, `bolt_circle_diameter`, and `rib_count`. Ambiguous cylinder groups retain aliases and reduced confidence instead of being silently declared holes. The semantic DesignIR 3.0 compiler currently supports this initial vocabulary through Build123d and SimpleCADAPI: - `extrude_circle` - `extrude_rectangle` - `add_cylinder` - `through_hole` - `polar_hole_pattern` Build123d and SimpleCADAPI are not the geometry fidelity boundary. Analytic and B-Spline surfaces unsupported by those adapters are compiled directly by OCCT from SurfaceIR. Unsupported operations are quarantined instead of embedding the source B-Rep. The SimpleCADAPI adapter also emits its replayable `*.simplecad.model.json` operation graph beside the STEP. DesignIR remains the backend-neutral source of truth. ## DesignIR 3.0 geometry and semantic layers DesignIR 3.0 adds an independent low-level parameter layer for STEP regions that are not yet expressible as semantic features. It stores analytic surface parameters, B-Spline poles/weights/knots, exact boundary curves, pcurves, and face-wire-shell-solid topology as JSON. It does not store the STEP file, an import instruction, an embedded B-Rep, or a triangle mesh. The semantic layer is the preferred modification interface. Parameters remain non-editable candidates until an executable binding passes a real perturbation. Feature-specific bindings enlarge cylindrical holes and bores by applying deduplicated OCCT cut features to the independently rebuilt SurfaceIR. Every geometry-bearing model also exposes `overall_scale` as a dimensionless minimum editability fallback about a deterministic SurfaceIR datum. This fallback does not claim recovery of feature-specific parameters such as plate thickness, hole spacing, or rib count. The acceptance agent checks the requested axes/radii for cylindrical edits, solid validity, declared volume direction, non-target parameter stability, and source independence. For uniform scale it additionally requires volume to change by the scale factor cubed, center and bounds to undergo the same transform, and solid/face/edge counts to remain stable. Equivalent vertex normalization performed by STEP serialization is retained as a diagnostic. ```bash # Convert every input STEP into an independent DesignIR 3.0 instance program. ../text-to-cad/.venv/bin/python scripts/surfaceir_pipeline.py extract-folder \ input --output-dir runs/surfaceir # Rebuild and compare a deterministic batch without loading STEP at runtime. ../text-to-cad/.venv/bin/python scripts/surfaceir_pipeline.py validate-folder \ input --designir-dir runs/surfaceir \ --rebuilt-dir runs/surfaceir-rebuilt --limit 100 # Apply one named parameter without loading the teacher STEP in the compiler. ../text-to-cad/.venv/bin/python scripts/surfaceir_pipeline.py edit \ runs/surfaceir/part.designir.json \ --parameter hole_diameter --value 6 \ --output-designir runs/edited/part.designir.json \ --output-step runs/edited/part.step # Agent B runs process-isolated +10% perturbations over a corpus. ../text-to-cad/.venv/bin/python scripts/surfaceir_pipeline.py \ validate-edits-folder input \ --designir-dir runs/surfaceir \ --output-dir runs/semantic-edit-acceptance \ --geometry-report runs/surfaceir-rebuilt/validation-report.json \ --workers 4 # Validate the universal source-independent edit fallback on every non-empty # model. Empty STEP documents remain explicitly non-editable. ../text-to-cad/.venv/bin/python scripts/surfaceir_pipeline.py \ augment-overall-scale runs/surfaceir \ --output runs/surfaceir/overall-scale-augmentation.json ../text-to-cad/.venv/bin/python scripts/surfaceir_pipeline.py \ validate-edits-folder input \ --designir-dir runs/surfaceir \ --output-dir runs/overall-scale-acceptance \ --geometry-report runs/surfaceir/strategy-selection-final.json \ --parameter overall_scale --workers 4 # Merge incremental failure retries into one authoritative acceptance report. ../text-to-cad/.venv/bin/python scripts/surfaceir_pipeline.py \ merge-acceptance-reports \ --baseline runs/semantic-edit-acceptance/batch-acceptance-report.json \ --retry runs/semantic-edit-retry/batch-acceptance-report.json \ --output runs/semantic-edit-authoritative.json ``` Boundary reconstruction strategies are evaluated by paired held-out A/B. The Promoted methods and their exact held-out evidence are stored in `output/library.json`. Geometry methods and semantic-edit methods have separate counts; a geometry-only result never increases the edit-capability count. The current 1,000-file corpus contains 999 geometry-bearing STEP documents and one truly empty STEP document. Of the geometry-bearing documents, 996 contain solids and three contain top-level open shells. SurfaceIR preserves all three open shells through `surface_layer.free_shells`; the empty source is rebuilt as an equivalent empty STEP document. Full-corpus validation therefore produces 1,000 independent rebuilt STEP documents from 1,000 DesignIR programs. The compiler restores exact 3D curves, binds per-face pcurves, preserves seam branches, keeps vertex and edge tolerances independent, groups shells under their declared solid, and keeps top-level open shells outside fake solids. Validation requires matching solid/face/edge topology, volume or surface area, center and bounds. Boolean symmetric difference is the primary solid check. For two numerically unstable coincident-solid booleans, a bidirectional sample contract checks vertices, edge samples and valid face-interior samples instead; the larger measured maximum distance is `0.0000647066 mm`, below the declared `0.0001 mm` limit. Every one of the 999 geometry-bearing documents has at least one non-generic, named parameter with a completed real perturbation contract. The private DesignIR corpus contains 1,213 validated named parameter instances: - cylindrical cuts: `hole_diameter` and `bore_diameter`; - primary-axis dimensions: `outer_diameter`, `body_length`, and `plate_thickness`; - canonical envelope dimensions: `overall_size_x`, `overall_size_y`, and `overall_size_z`. `overall_scale` remains available as a source-independent fallback, but is not counted in the 999/999 named-parameter coverage. Canonical envelope dimensions describe the DesignIR coordinate-system bounds and are not presented as recovered source sketch history. The one truly empty document has no geometry to modify and intentionally exposes no fabricated parameter. ```bash # Validate the pcurve-bound strategy over the complete corpus. ../text-to-cad/.venv/bin/python scripts/surfaceir_pipeline.py validate-folder \ input --designir-dir runs/surfaceir \ --rebuilt-dir runs/rebuilt-pcurve --boolean \ --boundary-strategy exact_3d_pcurve # Compare with the exact-boundary fallback and fix the validated choice in each # source-independent DesignIR document. ../text-to-cad/.venv/bin/python scripts/surfaceir_pipeline.py select-strategies \ --designir-dir runs/surfaceir \ --primary-report runs/rebuilt-pcurve/validation-report.json \ --fallback-report runs/rebuilt-exact/validation-report.json \ --output runs/surfaceir/strategy-selection-final.json ``` ## Agents - `agents/reconstruction-agent.md`: Agent A authors DesignIR from private evidence and promoted methods, then requests an isolated rebuild. - `agents/acceptance-agent.md`: Agent B independently checks geometry and parameter perturbations against the teacher. Neither agent publishes experience. `config/promotion-policy.json` is evaluated by deterministic code after several independent cases pass. ## Commands Drop files into `input/`, then use the CAD Python environment: ```bash # Build a deterministic, family-stratified 800/75/100 train/validation/test split. node scripts/trajectory_pipeline.mjs init # Agent A proposes DesignIR; the isolated compiler and Agent B contract reject # geometry or edit failures. Private attempts are written below runs/trajectory/. node scripts/trajectory_pipeline.mjs run \ --split train --limit 10 --attempts 3 --max-faces 24 # Generalize only replay-validated trajectories into non-consumable candidates. node scripts/trajectory_pipeline.mjs distill # Compare the same model on the same held-out cases with and without candidates. node scripts/trajectory_pipeline.mjs benchmark \ --split validation --limit 10 --attempts 3 --max-faces 24 scripts/cad-experience extract-folder scripts/cad-experience prepare # The semantic distiller writes runs/review/experience-draft.json. scripts/cad-experience publish \ --draft runs/review/experience-draft.json \ --validation-report runs/review/heldout-validation.json scripts/cad-experience audit output/library.json ../text-to-cad/.venv/bin/python scripts/designir_pipeline.py validate part.designir.json ../text-to-cad/.venv/bin/python scripts/designir_pipeline.py compile \ part.designir.json --output rebuilt.step ../text-to-cad/.venv/bin/python scripts/designir_pipeline.py isolated-rebuild \ part.designir.json --output rebuilt.step --backend simplecadapi ../text-to-cad/.venv/bin/python scripts/designir_pipeline.py accept \ --teacher teacher.step --designir part.designir.json \ --rebuilt rebuilt.step --report acceptance.json ``` Repeated support only creates a candidate. `output/library.json` receives a method only when its validation report identifies at least three independent teacher hashes, every declared edit contract passes, and the held-out A/B score delta against the empty-library baseline is positive across at least ten paired cases. Until then `router_consumable` remains false and CAD Router cannot use the candidate. The execution trajectory is the actual unit of learning: ```text private B-Rep evidence -> proposed DesignIR -> isolated rebuild without source STEP -> geometry and edit-contract verdict -> validator feedback and retry -> successful trajectory candidate ``` Counts, detector confidence, and repeated geometric motifs are not treated as improvement. Improvement is reported only by a positive paired held-out A/B result. `output/distillation-report.json` separates corpus extraction, untrusted candidates, execution-validated trajectories, and promoted methods.