InvariantCAD 0.2.0
InvariantCAD 0.2.0 adds one public exact-import workflow and makes the 0.1 foundation strict and predictable. Builders now check their inputs when each method is called. Parsing, the CLI, and signal-bearing evaluation bound untrusted documents, options, and files before using them. Kernels report only measurements they can stand behind. Public document authoring remains Document v6. Imported-body documents use a fixed Document v7 subset, read and evaluated only by the imported-body functions. This release contains breaking changes for some 0.1.1 callers. Read the upgrade notes before upgrading.Highlights
- Verified single-body import.
createImportedBodyDocument,stringifyImportedBodyDocument,parseImportedBodyDocument, andEvaluator.evaluateImportedBodypersist and evaluate one exact solid backed by a SHA-256 byte commitment.- Bytes come from a caller callback and are verified before use. The workflow never falls back to weak native import or to a mesh conversion.
- Author-time checks.
- Builder methods validate option values, ownership, and ceilings when they are called, and read caller records once through their own data properties.
build()returns a detached, deeply frozen document that satisfies the strict document grammar.SketchBuilder.regularPolygon(...)now works.
- Hardened untrusted input.
parseDocumentrejects duplicate JSON member names.- Serialization and the CLI are bounded.
- Diagnostic paths are RFC 6901 JSON Pointers that escape every document key.
- The CLI fails closed on bad arguments and escapes document text.
- An evaluation with a
signalsnapshots its request, then yields to the host so aborts from timers, UI handlers, and workers take effect.
- Correct, bounded evaluation.
- Assemblies have fixed occurrence, path, and depth ceilings.
- Mirror normals, revolve axes, sweep miters, and loft phases are checked before kernel work.
- Custom sketch solvers are held to their declared protocol.
- Expression evaluation and validation are linear in distinct nodes.
- Honest kernel results.
ShapeMeasurements.genusisnumber | null, andnullmeans unsupported.- Stock OCCT transforms spheres and cones.
- OCCT
mesh()no longer depends on earlier tessellations. - STEP export on stock OCCT is bounded, and single-product export is byte-deterministic.
- Manifold rejects foreign shapes and profiles beyond ±1e10 mm with readable diagnostics.
- A GitHub-driven release flow.
- Every change reaches npm through a reviewed release pull request.
- Publication uses OIDC trusted publishing with npm provenance.
- The tagged GitHub release and the live documentation follow the published package.
Verified single-body import
createImportedBodyDocument(...) records a caller-owned SHA-256 digest, exact
byte length, format and media type, and unit policy without performing I/O.
Evaluator.evaluateImportedBody(...) resolves the bytes through a callback. It
checks the committed length against the resource ceiling and verifies the digest
before the strong exact B-Rep single-solid import runs. STEP uses the file’s
units; text and binary BREP use caller-declared units.
The saved JSON is a fixed, minimal Document v7 subset: one resource, one
importedBody node, and one solid output. Tests pin its canonical bytes and
digest, so imported-body documents saved by 0.2.0 stay readable. The general
Document v1–v6 APIs reject Document v7. validateDocument, parseDocument,
parseDocumentValue, migrateDocument, hashDesignFeatures,
analyzeDesignImpact, and Evaluator.evaluate return one IR_INVALID
diagnostic that names the imported-body functions. stringifyDocument and
cloneDocument throw a TypeError, and hashDocument rejects with one. See
verified single-body import.
Strict authoring
- Plain records and lists. Option records must be plain objects, and the
lists and records a document stores must be plain dense arrays and plain
objects. Own fields are read once, whether enumerable or not. Accessors never
run, and fields inherited from
Object.prototypeare never read. - Ownership. A
Parameterfrom another builder, a handle created with an exported constructor, or a builder used after its callback returned now throws. - Ceilings. Metadata, topology selections, option records, and raw expression IR have fixed size and depth ceilings. They are refused before their contents are copied.
Untrusted input and diagnostics
Parsing, serialization, the CLI, and evaluation with asignal now apply
their documented ceilings before they allocate the data those ceilings
protect. An evaluation without a signal reads the supplied document
directly, so pass untrusted values through parseDocument or
parseDocumentValue before evaluating them. Every
diagnostic path escapes / and ~ in document keys, so a node named a/b is
reported at /nodes/a~1b. A non-string outputs entry or configuration
option fails with IR_INVALID. See
diagnostics and limits.
Kernels and exchange
- Genus. Manifold reports exact per-component genus. Stock and owned OCCT
report
null(unsupported) instead of the 0.1.1 Euler-characteristic heuristic. - STEP export. On stock OCCT it has output, input, scan, and entity ceilings. Single-product zero-override export is byte-deterministic.
- Binary STL. Headers fit long multi-byte names on a character boundary,
and a name starting with
solidis prefixed so readers do not mistake the file for ASCII STL. - OCCT runtime. Kernel
capabilitiesare frozen,dispose()releases every remaining native handle, and OCCTmeasure()counts each occurrence of a solid that a compound repeats.
Public entry points
The five public entry points are unchanged:invariantcadinvariantcad/conformanceinvariantcad/kernels/occtinvariantcad/kernels/occt/browserinvariantcad/kernels/occt/node
Important boundaries
- Public document authoring, schemas, migration targets, and aliases remain Document v6. Documents v1–v6 remain frozen and directly supported.
- The imported-body subset is the only public Document v7 JSON. Resources beyond it, datums, body sets, products, external occurrences, and feature-hash protocol v2 remain staged, repository-only work.
- The InvariantCAD-owned OCCT facade is not distributed in the npm package. Draft geometry and some exact topology-history guarantees still require it.
- Mesh and exact behavior remain distinct. Unsupported exact work is never silently converted to an approximate operation.
Upgrade notes
Node.js 22.13 or newer is still required, and existing v1–v6 documents need no migration. Review these changes:- Document v7 JSON. Code that passed Document v7 JSON to
validateDocument,parseDocument,stringifyDocument,hashDocument, orEvaluator.evaluatemust use the imported-body functions instead. - Option records and lists. They must be plain object literals and plain
arrays. Class instances, getter-backed objects, array subclasses, and sparse
arrays now throw
TypeError. - Genus.
ShapeMeasurements.genuscan benull; handle it explicitly. - Manifold shape ownership. Each
ManifoldKernelaccepts only the shapes it created. - Revolve. A revolve profile that crosses its axis now fails with
FEATURE_INVALIDinstead of being clipped on Manifold. - Sweep. It now accounts for the corner miter, so some tight 0.1.1 sweeps need longer segments, gentler corners, or a smaller profile.
- Custom sketch solvers. They must advertise every entity and constraint
kind they accept, and their
statusis authoritative. - Assemblies. Those beyond 100,000 occurrence records, 1,000,000 instance
path segments, or depth 64 now fail with
RESOURCE_LIMIT_EXCEEDED. - CLI export.
invariantcad exportrequires--outputfor documents with more than one output. - Declaration maps. The package no longer ships TypeScript declaration maps; declarations keep their JSDoc.