VextCAD

Write a VXL document

Connected VextCAD MCP: When mcp__vextcad__* tools are available, work only through them. Read docs with read_docs/search_docs (they match the server's engine), validate with check_vxl, build with start_build + get_build, render with get_preview, and upload STEP/STL inputs with upload_asset. Do not read local skill files or run local vextcad/ scripts/vextonline.mjs in that session. Otherwise, follow this skill as written. A link FILE.md#section means read_docs with page = the lowercase file name and section = the anchor. Read only the sections the current step needs; a diagnostic code goes to search_docs.

Authoring rules

  • Write and maintain VXL documents directly. No script writes *.vxl.json; scripts may prepare captured inputs, build committed documents, read delivered files or inspect slicing.
  • Use native profiles[] for mechanical geometry that follows dimensions and parameters. Use SVG regions for fixed artwork and organic outlines.
  • Put families in one document with variants[]; use when only when finite-domain parameters change structure.
  • Use each and templated names for repeated arrays and statements, and functions[] for shared formulas. Do not paste expanded copies.
  • Keep scans, photographs, sculpt captures, fonts and requirement-named STEP/STL files as assets. Declare descriptors from captured bytes with vextcad vxl asset describe or refresh them with vextcad vxl assets sync.
  • Self-review with vextcad vxl fmt, vextcad vxl check --preview DIR, vextcad vxl check, and vextcad vxl reference. Exit 3 means the document has errors; the full report is still printed (result.ok, result.errors). A static check is not a measured build.

Start

VXL is a closed JSON design-document language for exact (B-Rep) and triangle-mesh parts. Read the core conventions, the selector and requirement conventions and the needs and check loop blocks, then choose one card and one checked example. Write one <name>.vxl.json directly. vxl check is not geometric acceptance. Requirements are independent of the model. An unresolved problem means HOLD.

Choose a card

The part needs Read
Field shapes of any op Op table
Frames, representation choice Frames, when to use
Profiles, slots, curves, SVG outlines 2D profiles
Selecting faces and edges Selector cookbook
Rounds and chamfers Robust rounds
Repeats, fragments, std Composition, language features, STD.md
Sheet metal Flat-first sheet, bend and gauge requirements
Cones, spheres, tori, revolves Analytic card, conventions
Gears and racks Spur gears, racks, conventions
Threads, coils, springs Threads card
Sweeps, lofts, surfaces Paths, surfaces, conventions, surface conventions
Imported STEP or STL Imported parts, conventions
Text, draft, face offset Finishing card, conventions
Several bodies, split, imprint Split card, conventions
Mesh or organic shapes Mesh card, fields
Requirements Required fields, feature table, templates, evidence and repair
Revisioned sessions, recovery EDITING.md

Gated loop

Do these in order. The common failure is writing geometry before noticing a missing fact.

  1. Facts → needs[]. One fact per need: split the request into its separate claims and restate each in the user's words rather than copying a compound sentence wholesale. Add source: "user".

  2. Gap scan. For each feature ask: position? size? orientation? count? side? Treat a missing value or ambiguous instruction as a question when resolving it chooses among geometrically different parts, unless the user already authorized that choice. A declared assumption alone does not resolve it; ask for the undetermined attributes or name the competing readings explicitly. An assumption without a question is allowed for a value derived from supplied facts, an unambiguous documented default, or a sourced standard dimension for an already determined component and function; identify the basis and adopted value. A complete request needs no question. Scan every requested feature, including ones omitted from a draft; ask explicitly about each undetermined size, position, orientation, count, side or interface attribute, not just whether a proposal is acceptable. For a useful provisional model, keep unresolved questions in both the document and the answer, mark provisional choices in assumptions[], and call it provisional until resolved; open questions cap the build label at HOLD while every file is delivered, and answering means removing the question and recording the user's answer as a need, parameter or assumption (assumptions alone do not cap the label). See the worked example.

  3. Frame recipe. Apply the coordinate-frame recipe before writing any geometry.

  4. Values. params[] for user-supplied facts (with domain when a reopen is expected); lets[] for derived values; checks[] for design inequalities.

  5. Geometry. Consult the op table for required fields. In each part, write creators first, then Booleans, holes, patterns/mirror, then fillet/chamfer last. For rounds, follow the robust route: profile arcs, then revolve-meridian arcs, then a small final fillet set; disclose an omitted round. When a shape repeats, or a screw axis needs its hole and keep-out, reach for a use: std.mount_hole for a verified hole, std.tool_access for the keep-out, a defs[] fragment for anything else. State a use's target when the fragment drills or unions into it. On a body with fillets or other blends, cut (or union) all tools of one set with one multi-tool Boolean ("tools": ["bore_a", "bore_b"]), not a sequence of single-tool Booleans: each sequential step re-processes the whole blended body. One measured part took 666 s of one-at-a-time bore cuts versus 84 s in one Boolean with all tools, about 8× faster.

  6. Requirements. Consult the required fields. Every measurable need gets a requirement with covers. For an unmeasurable exact-part claim, use kind: "unmeasured" with describe; it needs exactly one of subject or operands (VXL-S011 if both are given; VXL-R660 if neither is given), and a mesh subject is refused (VXL-R761). For a mesh disclosure, put the reason in that need's unmodeled field. A need may instead use a reserved gap kind where appropriate. Every need must be covered or marked unmodeled.

  7. Check loop. Run vxl check and read result.ok, result.errors, result.warnings, and result.notes in the CLI check result. Fix one code at a time and re-run. Hard cap 6 checks.

  8. Build and revise. For retained source, open the checked document, then replace it or set the full overrides map, inspect status/entities/preview, undo when needed, cancel a named request when abandoning work, and publish labelled files for delivery (see the session workflow). One-shot vextcad vxl build FILE --output-dir DIR (or the hosted upload) builds the part and writes DIR/report/summary.json; on failure or HOLD it also writes DIR/report/revision-packet.json. Use --progress jsonl for long builds to observe completed operations and later phases on stderr. Read the packet, fix the document, rebuild. A chamfer_size row with outcome: fail shows setbacks_mm and support_signed_offsets_mm: compare each with nominal; a station that differs means the chamfer is on other stock or between other faces than between says. Hard cap 4 builds.

    On a Mac, or with no local vextcad, see Local and remote builds.

Deliver

Read the output contract and delivery decision. Deliver labelled files and the report; use native export when requested.

Stop

Keep the six-check/four-build limits above, including session rebuilds. Read HOLD and repair; unresolved intent, required nonpass or unavailable evidence stays HOLD. Compact replies, filters and previews never decide RELEASE.

Local and remote builds

On a Mac, local measured acceptance is available. vextcad vxl build on macOS arm64 runs without --cell-manifest in macos_arm64_local_verification_v1, authenticating the resident OCCT package and worker. Every summary, build report and manifest carries cell: {kind, unqualified: true, os: macos, arch: aarch64, package_manifest_digest, worker_digest}. When every required geometry row passes and the authored ceiling permits it, the local label is RELEASE; a required failure, unsupported/not-measured row (including an unavailable clearance proof), or open question keeps HOLD. The banner still includes development_unqualified, but that warning is not a verdict_ceiling.because cause. This is local acceptance, not production qualification: the hosted scope and sealed Linux qualification are unchanged, and the hosted service refuses this cell. Old generations with kind: development_macos_arm64 remain readable and always HOLD.

No local vextcad, or need a Linux-cell result from a Mac? Use the hosted service. With the user's API key, node scripts/vextonline.mjs check|build ... replaces vxl check and vxl build and returns the same out/ layout. See Remote build.