Files
OneCAD/CLAUDE.md
T
e12758ff91 Public reference tests: analytic and FreeCAD expected values (#310)
The oracle no longer uses Fusion measurements. tests/oracle/<case>/ now holds the 76 recipes
(our own format, with recorded measurements and tool-specific fields removed) and an
expected.json per case:

- 55 analytic cases: closed-form values from tools/oracle-analytic/ (stdlib Python, formulas
  in each case's "method").
- 21 FreeCAD cases: the same recipe built with FreeCAD's public scripting API by
  tools/freecad-oracle/ (an external program, not a dependency), with a reference.stl for 20.

solvecraft-cli oracle compares body count, volume, area, centre of mass, bbox, face counts
where the geometry fixes them, and, against reference.stl, the sampled Hausdorff distance and
the principal moments (spatial.rs from #301). cargo xtask oracle reads tests/oracle, writes
docs/oracle.md with the source of each value, and supports known_failure marks for tracked
bugs. CI runs it on every PR; a manual workflow regenerates the FreeCAD values. step-corpus,
seam normalisation and the through-all emulation, which only existed to compare with Fusion,
are removed.

75/76 pass; 75-sm-bracket-holes is a known failure (#296).


Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT

Co-authored-by: bherbruck <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-12 10:43:43 -04:00

8.0 KiB

SolidCraft — instructions for agents

SolidCraft is a clean-room, open-source, pure-Rust parametric 3D CAD application: sketches with a constraint solver, a parametric timeline of features, a B-rep kernel, and a desktop UI that agents can drive. Projects published by storytold can serve as references for implementation conventions. Any code adapted from other projects (MIT OR Apache-2.0) is noted in ATTRIBUTION.md.

Product name and compatibility

SolidCraft is the displayed product name; solidcraft is the repository name. Keep existing solvecraft crate/binary names, .solvecraft files, format markers, environment variables, settings/recovery paths and package IDs compatible. Published SolveCraft release artifacts and attribution records keep their historical names. Public docs/web/Flatpak deployments use project Pages /solidcraft/; do not add permanent old-name Pages aliases. See README's compatibility notes.

Start every session here

  1. Read plan/STATUS.md (current milestone, next task), then the task in plan/execution-plan.md and the relevant plan/architecture.md section. Behaviour reference: plan/fusion/ (menu-tree.json is Fusion's toolbar dump).
  2. Kernel and library decisions: plan/adr/0001-geometry-kernel.md (what we may depend on, what is rejected for licence reasons).
  3. Follow the autonomous operation protocol (plan/execution-plan.md §6). Don't stop to ask unless it lists the decision as the owner's.

plan/ is gitignored (local only).

Never crash

People trust SolidCraft with their designs; a crash loses their work. This outranks feature work.

  • No panics in non-test code: no unwrap(), expect(), panic!, unreachable!, todo!, unimplemented!; no unsafe (unsafe_code = "forbid").
  • Errors are Result<T, E> through the crate's error type and ?. An unfinished feature returns an error ("not supported yet: …"); it never panics.
  • Input-derived numbers are hostile (command parameters, design files, control-channel input): get() not [i], finite checks, caps on sizes and loop counts.
  • Third-party kernel calls are guarded: everything that calls truck goes through solvecraft_kernel::guard, which turns a panic into KernelError::Internal.
  • Last-resort guard: Session::execute runs every command under catch_unwind; an escaped panic restores the design and reports EngineError::Internal.
  • Prove it: every crash fix lands with a regression test (see hostile_params_never_panic).
  • Every production crate root carries #![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)].

Non-negotiables

  • Clean-room. Fusion may be observed black-box (its UI, its toolbar dump, parts built in it and their measurements, kept under plan/fusion/, never committed). Never copy Autodesk icons, artwork, help text, tooltips, templates or materials, and never commit files produced by Fusion. Command ids and command names are used as identifiers only (xtask/data/fusion-catalog.tsv holds ids and names, nothing else). File formats come from public specifications. Never read, copy or link GPL/LGPL/AGPL code: OpenCASCADE, FreeCAD (incl. planegcs), SolveSpace, CadQuery/OCP, LibreCAD, QCAD — don't even read their sources. (tools/freecad-oracle/ runs FreeCAD as a separate program through its public scripting API to compute reference values; nothing from FreeCAD is linked, vendored or shipped.) The sketch solver and the blend operations are our own.
  • Assets — absolutely essential. SolidCraft contains no Autodesk iconography, images, fonts or artwork — ever. Every icon is drawn in code (crates/ui-egui/src/icons.rs). Any file asset must be original or openly licensed and must have a row in ATTRIBUTION.md (cargo xtask assets enforces it). Screenshots of Autodesk software are never committed. Breaking this rule is the most serious mistake you can make in this repo.
  • Everything is a command. User-visible behaviour = a command in crates/engine/src/cmd/* (CommandSpec: id = our own dotted, lower-case id <area>.<thing>[.<variant>] such as solid.extrude or sketch.rectangle.two_point, never another product's command id; label; toolbar tab and panel; icon; shortcut; params doc; enabled; JSON run) + tests. The toolbar, dialogs, sketch tools, palette, scripts, CLI and control channel all reach the same commands.
  • Programmatic calls never open dialogs. engine.execute runs the JSON form; only toolbar clicks (ui.start) start interactive tools and dialogs, which then run commands.
  • Layering is enforced by cargo xtask layers: L0 geom → L1 sketch, kernel, render → L2 doc → L3 io → L4 engine → L5 ui-egui → apps. Nothing below L5 depends on egui/eframe/winit/wgpu/rfd. The UI crate is swappable. Only crates/kernel may use truck.
  • The UI is thin: panels read engine state and act through app.run(id, params) / app.start(id). Colours come from theme::Tokens.
  • Rust only. Units are millimetres and radians internally; Z is up.
  • Quality gates before every commit: cargo xtask ci (fmt, clippy -D warnings, tests, assets, layers). Commit after every feature arc that builds.
  • Publishing: origin is github.com/bherbruck/solidcraft. Changes land through pull requests: push a branch, open a PR, and let GitHub CI run. Maintainers (and agents working for them) may merge their own PR as soon as CI is green (gh pr merge --squash); a trivial fix (docs, typos) may be merged right away. Keep each PR to one topic, rebase or merge main into it when it conflicts, and never force-push main. Never commit plan/, build dirs (target*/) or generated reference data; check git ls-files before pushing.
  • Never break wasm: everything below the apps must build for wasm32-unknown-unknown (cargo xtask wasm, part of cargo xtask ci).

Application releases

Development pushes are not application releases. Follow docs/releasing.md when asked to prepare or ship a release: choose the version from the actual changes, update Cargo.toml and Cargo.lock, pass the quality gates, advance release without force-pushing, and verify the resulting draft and its artifacts. When shipping is authorized, publish that verified draft and confirm its tag and downstream deployment. Do not auto-release every push to main, infer version bumps solely from commit prefixes, overwrite published versions, or push release tags before the draft is verified.

Running and looking at the app

  • cargo run --release -p solvecraft -- --sample --control PORT (sample design + control channel). Pick a free port. Without a display, run it under Xvfb :99 with DISPLAY=:99.
  • Drive it with JSON lines on 127.0.0.1:PORT (see docs/control-protocol.md):
    • {"id":1,"method":"engine.execute","params":{"command":"solid.extrude","params":{"distance":20}}}
    • {"id":2,"method":"ui.start","params":{"command":"sketch.create"}} then ui.click {x, y}
    • {"id":3,"method":"ui.screenshot","params":{"path":"/tmp/shot.png"}} then read the PNG.
  • For UI work, look at the result (screenshot, read the PNG). Without a window use ui.render or solvecraft-cli snapshot.
  • Headless: solvecraft-cli run script.json --out part.step, solvecraft-cli eval design.solvecraft, solvecraft-cli snapshot script.json --out shot.png, solvecraft-cli commands.
  • Reference tests: cargo xtask oracle replays tests/oracle/*/recipe.json and compares with each case's expected.json (analytic or FreeCAD values; writes docs/oracle.md). Expected values never come from Fusion or any other commercial CAD product.
  • Build with CARGO_TARGET_DIR=<repo>/target. Windows: cargo xwin build --release --target x86_64-pc-windows-msvc -p solvecraft.

Roadmap

ROADMAP.md (committed) tracks status, milestones, parity and estimates. Update it whenever a milestone task lands. cargo xtask parity recomputes command parity in docs/parity.md; cargo xtask oracle recomputes docs/oracle.md.