Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

StitchCraft — Technical Design Document

StatusDraft 0.1 — design approved for M0/M1, later sections refined as milestones land
Date2026-10-08
ScopeA Rust machine-embroidery engine and its integration with VectorCraft
Reading time~25 minutes; every section links to the detailed design it summarizes

StitchCraft turns vector art into machine embroidery. It is two things that ship together:

  1. An engine — host-agnostic Rust crates that turn shapes plus embroidery parameters into a stitch plan and encode it as machine files (PES for Brother first, then DST, EXP, JEF, VP3 …).
  2. A VectorCraft plug-in — the engine inside VectorCraft, ArtCraft’s open-source, clean-room Illustrator written in Rust, so embroidery is designed where the art is drawn.

It covers the common machine-embroidery stitch types (running, bean, satin, tatami fill, contour, meander, ripple, …) and reads the embroidery parameters Ink/Stitch stores in SVG files, so designs move between the tools. Its quality bar: it never crashes, it produces the same file on every platform, and every behaviour is pinned by a conformance suite and by sew-outs on a real machine.


1. Goals

IDGoalHow we know
G1Read and write every parameter in the Ink/Stitch compatibility contract, in phasesCompatibility contract coverage column reaches 100 % for phase P1–P3 rows
G2Never crash on any inputNo-panic lints, fuzzing, bounded work budgets (guardrails, robustness)
G3Correctness proven, not assumedEvery requirement has a passing conformance case; machine checkpoints signed off (conformance, machine testing)
G4DeterminismByte-identical files on Linux, macOS, Windows and wasm32 (determinism)
G5Host-agnostic engineVectorCraft plug-in, CLI and (later) an in-tree VectorCraft crate share one engine (architecture)
G6Documentation that cannot drift from the codeReference generated from code, images regenerated in CI on every PR (docs pipeline)
G7Code we are proud to showEnforced layering, small modules, playbooks for contributors (guardrails)
G8Survive VectorCraft releasesPlug-in tested against VectorCraft stable, pre-releases, release and main (compatibility gate)

Non-goals for 1.0

  • An Inkscape extension.
  • Photo stitch: photographs sewn in blended colours. Pictures of flat colour, such as logos, clip art and drawings, are digitized automatically from M13 (image to embroidery).
  • Sending files to machines over USB/Wi-Fi; the output is a file you copy to the machine.
  • A standalone GUI. The GUI is VectorCraft; the CLI renders previews to PNG.

2. Target machine and the first user

The first production target is a Brother PE800, a home embroidery machine whose largest hoop, 5 × 7 in, sews at most 130 × 180 mm, loading PES files (ADR 0013). It becomes the built-in profile brother-pe800-5x7, the reference profile, with one profile for each of its other hoops: brother-pe800-4x4 (100 × 100 mm) and brother-pe800-small (20 × 60 mm).

Profile fieldValueBehaviour
Hoop (hard limit)130 × 180 mmError SC-E0701 if the plan does not fit
Comfort zonenoneA profile may have one: warning SC-W0702 if the design is larger
File formatPES v1 with PEC blockChanged only after a machine checkpoint proves another works
Max stitch length12.0 mm (split above)Refined at MC-1
Min stitch length0.3 mm (merged below)Refined at MC-2
TrimsA trim flag on every PEC jump after the first move (REQ-FMT-010)MC-1: the PE800 cuts none of them
Thread paletteBrother PEC palette (nearest colour, CIEDE2000)—

Profiles are data (see data model); adding a machine never touches the engine.

3. Background

3.1 File compatibility with Ink/Stitch

Ink/Stitch, a GPL-3.0 extension for Inkscape, stores its embroidery settings in SVG files as inkstitch:<name> attributes. StitchCraft reads and writes the same attribute names, values and defaults, so a design moves between the tools unchanged. Those names, types and defaults are facts listed in the compatibility contract; where StitchCraft’s behaviour differs on purpose, the deviations ledger (conformance/deviations.toml) says how and why. StitchCraft is an independent project and contains no Ink/Stitch code, documentation text or data files (ADR-0001).

3.2 VectorCraft, the host

VectorCraft (MIT OR Apache-2.0, Rust 2024, ~290,000 lines) is a clean-room Illustrator. What matters here (details and file references in VectorCraft integration):

  • Plug-in ABI v1: sandboxed WebAssembly modules run by wasmi with no imports. Two kinds: object filters (one undo step) and live effects (rewrite one object’s geometry whenever it is drawn). Parameters come from a manifest schema (number, int, bool, choice; at most 64).
  • Live-effect parameters are stored per object in the document as {"id": "plugin.<id>", "params": {…}} — so embroidery settings can live on the art today, with no VectorCraft change.
  • Limits that shape our design: 50 M instructions per call (+4,000 per input byte), 5 s per live-effect run, input is geometry only (no paint), no file-format plug-ins, no panels.
  • Everything is a command, reachable from the UI, a JSON control channel, an MCP server and a headless CLI (vectorcraft-cli run --in f --cmd … --export out.png), which our tests and screenshot pipeline drive.

3.3 Licence and clean room

Ink/Stitch is GPL-3.0; VectorCraft forbids GPL code in its tree. StitchCraft is MIT OR Apache-2.0 and never copies GPL code: the design docs in this folder describe behaviour (inputs, outputs, parameters, algorithms) in our own words, and implementers work from these docs. Ink/Stitch’s source may be read to understand its behaviour, never copied or transliterated. Parameter names are kept identical to Ink/Stitch’s SVG attributes because that is the interoperability contract. See ADR-0001 and ADR-0012.

4. Requirements

4.1 Functional scope by phase

CapabilityPhaseMilestone
Stitch plan, Brother profile, PES + DST writers, test sheetsP1M1
PES/DST readers, preview renderer, fuzzingP1M2
Running stitch (repeats, bean, random length), manual stitch, lock stitches, trims, stops, colour changes, SVG inputP1M3
Satin column (rails/rungs, underlays, pull/push compensation, short and split stitches)P1M4
Tatami fill (underlay, pull compensation, staggers, gap fill, underpath travel)P1M5
VectorCraft plug-in (ABI v1), export from .vectorcraft, compatibility gate, and the plug-in features VectorCraft added from 0.14 (exports from File › Export, labelled dialogs, design settings and a machine for each document, and the tools filter)P1M6
Zigzag/E/S stitches, contour, meander, circular fillP2M7
Image to embroidery: stitch types chosen by width, overlaps, sewing order, VectorCraft’s Auto effectP2M13, between M7.5 and M7.6
Ink/Stitch SVG import (attributes, commands, clones) and differential testingP2M8
Lettering in embroidery fonts, and text in pictures set again as letteringP3M14
Guided, gradient, ripple, tartan, cross stitch; auto-run/auto-satinP3M10
EXP, JEF, VP3, XXX, U01 formats; thread cataloguesP3M11
1.0 hardening, translations, release automation—M12
VectorCraft plug-in features still proposed upstream (RFC), for previews drawn as overlays, heavy live effects and the objects beside a live effectafter 1.0M9, last

The full milestone and step list is in the roadmap.

4.2 Non-functional requirements

IDRequirement
NFR-ROB-1No panics in shipped code; no unsafe outside the one audited plug-in ABI module
NFR-ROB-2All work is bounded by explicit budgets (stitches, iterations, input sizes); exceeding one is a diagnostic, never a hang
NFR-DET-1Same input and version ⇒ byte-identical output on every supported platform, including wasm32
NFR-PERF-1A 130 × 180 mm tatami fill at 0.4 mm spacing, the reference hoop’s whole field, plans in ≤ 50 ms natively. Baseline set at M5.9: 29 ms on a 2.1 GHz Xeon, 282 million instructions, guarded by the instruction count (cargo xtask perf)
NFR-PERF-2Live-effect previews fit VectorCraft’s v1 budget (≤ 50 M instructions, ≤ 5 s) for a 130 × 180 mm design
NFR-PORT-1Engine crates build for wasm32-unknown-unknown without WASI
NFR-DOC-1100 % of parameters, diagnostics, CLI commands and formats have generated reference pages
NFR-TEST-1Every requirement in conformance/requirements.toml has ≥ 1 passing case before its milestone closes
NFR-SEC-1Every parser of untrusted bytes (SVG, .vectorcraft, PES, DST, …) is fuzzed and resource-capped

5. Architecture

 Hosts / adapters                   Engine                                      Outputs
┌────────────────────┐      ┌───────────────────────────────────────┐      ┌──────────────────┐
│ SVG (Ink/Stitch)   │─┐    │ normalize ─▶ validate ─▶ generate     │      │ PES / DST / …    │
│ .vectorcraft file  │─┼──▶ │   per element (StitchGroup)           │ ──▶  │ PNG preview      │
│ VectorCraft plug-in│─┘    │ ─▶ assemble plan (order, travel,      │      │ JSON report      │
└────────────────────┘      │    ties, trims, colours) ─▶ finalize  │      │ plug-in geometry │
        Design              │    (profile limits) ─▶ StitchPlan     │      └──────────────────┘
                            └───────────────────────────────────────┘
                                    + Diagnostics at every stage

The workspace is split into layered crates; a crate may depend only on lower layers, enforced by cargo xtask layers:

LayerCrateResponsibility
L0stitchcraft-coreUnits (mm), points, deterministic math and RNG, diagnostics model
L0stitchcraft-paramsThe parameter registry: the single source of truth for every parameter
L1stitchcraft-planStitch plan model, machine profiles, thread palettes, plan invariants
L2stitchcraft-engineDesign model, stitch generators, plan assembly
L2stitchcraft-formatsMachine file readers and writers
L2stitchcraft-renderDeterministic CPU preview renderer (docs, CLI, conformance)
L3stitchcraft-svgSVG and Ink/Stitch-attribute adapter
L3stitchcraft-vectorcraft.vectorcraft document adapter and effect-record mapping
teststitchcraft-testkitFixtures, property-test strategies, invariant checkers
appstitchcraft-cli (stitch)Command-line tool
appstitchcraft-vc-pluginVectorCraft WebAssembly plug-ins

Details, dependency rules and the reasoning are in architecture.

6. Key decisions

ADRDecision
0001MIT OR Apache-2.0, clean-room from Ink/Stitch; keep its parameter names for interoperability
0002Host-agnostic engine; VectorCraft ABI v1 plug-in first, new plug-in features upstream, in-tree crate optional
0003One parameter registry generates UI schemas, CLI, docs, SVG mapping and test strategies
0004Determinism by construction: ordered collections, libm, seeded RNG, absolute quantization
0005kurbo for curves, i_overlay for polygon booleans/offsets, petgraph + own Eulerian walk, rstar
0006mdBook, Diátaxis structure, generated reference, CI-regenerated images
0007PES v1 first for the Brother machine; DST second
0008Conformance-first development: requirement IDs and cases before code
0009Adopt VectorCraft’s proven conventions; improve the ones that drift
0010Every user-facing problem is a coded diagnostic with an explanation page
0011StitchCraft can move into VectorCraft’s repository as a folder
0012Ink/Stitch’s source may be read, never copied
0013A Brother PE800 is the reference machine, with a profile for each of its 3 hoops
0014Elements are generated in order, each seeing the needle before it and the next element

7. Data model (summary)

Full types in data model.

  • Units: millimetres as f64, y pointing down (same as SVG and VectorCraft). Adapters convert (pt × 25.4/72, SVG user units through the viewBox). Encoders quantize absolute positions to 0.1 mm once, so long designs never drift.
  • Design (engine input): ordered Elements — id (stable host id), shape (Region, Path or Satin), thread, params (ParamSet), commands (start/end points, trim, stop, ignore) — plus design settings (collapse length, minimum stitch length, origin) and a machine profile.
  • StitchPlan (engine output): colour blocks of stitches; every stitch has a position, a kind (Normal, Jump, Trim, Stop, ColorChange, End) and provenance (element id and role: underlay, top, travel, lock) used by previews, reports and diagnostics.
  • Diagnostics: SC-E… errors and SC-W… warnings with element, location, message and a fix hint; each code has a generated explanation page (diagnostics).

8. Engine pipeline (summary)

Detailed in engine pipeline.

  1. Normalize each element. Curves are flattened to tolerance, and each fill’s region is built by its fill rule. Degenerate pieces are dropped with a diagnostic.
  2. Validate parameters against the registry (type, range, applicability) and shapes against the stitch type (e.g. a satin needs two rails).
  3. Generate a StitchGroup per element with its stitch type’s generator. Generators are pure functions of (shape, typed params, seed, budget) — no globals, no I/O.
  4. Assemble the plan: keep document order, connect groups (travel inside a region, or tie-off → jump/trim → tie-in), insert colour changes and stops, apply commands.
  5. Finalize against the profile: split stitches above the maximum, merge below the minimum, check the hoop and colour limits.
  6. Check invariants (the same checker the conformance suite uses) before any file is written.

9. Stitch generators (summary)

GeneratorPhaseDesign
Running, bean, manual, random-lengthP1strokes
Satin column (+ E, S, zigzag variants)P1/P2satin
Tatami fillP1fills
Contour, meander, circularP2fills
Guided, linear gradient, tartan, cross stitchP3fills
Ripple, zigzag strokeP2/P3strokes
Lock stitches, travel, orderingP1engine pipeline

Generators follow Ink/Stitch’s stitch placement, worked out from its behaviour and from published algorithms such as an Eulerian path through a fill’s rows, or offset curves for a contour fill’s rings. Each generator’s page cites them. Where one differs, conformance/deviations.toml says how and why.

10. Machine formats

PES (v1 header + PEC block) and DST first, then EXP, JEF, VP3, XXX, U01. Writers quantize once, encode commands per the format’s rules and validate against limits (displacement per record, colour count). Readers are bounded and fuzzed. pyembroidery (MIT) is used in CI as an independent oracle: it must read our files back to the same stitches. Details: formats.

11. Robustness

  • Shipped code has no unwrap, expect, panic!, unreachable!, todo!, unimplemented!, and no unchecked indexing on data; enforced by workspace lints (adopted from VectorCraft).
  • Every generator receives a work budget (stitch count, iterations); running out returns a diagnostic and the partial-free result “nothing for this element”, never a hang. Budgets are counted in work units, not wall time, so they are deterministic.
  • Degradation is explicit: when a fill is too small for rows, the outline fallback is emitted with SC-W0305; when travel cannot stay inside a region, the plan uses tie-off + trim + tie-in and says so — never a silent straight line across the design.
  • Parsers cap sizes and counts before allocating; files are untrusted.

12. Determinism

Ordered collections only (BTreeMap, Vec), transcendental functions from libm, a documented seeded PRNG (SplitMix64) with seeds derived from element id and the random_seed parameter, absolute quantization at encode time, and golden files compared byte for byte on every operating system CI tests on. Details: determinism.

13. VectorCraft integration (summary)

Three phases (full design in VectorCraft integration):

  1. ABI v1, no upstream change (M6). Plug-ins dev.stitchcraft.running, .satin and .fill are live effects: applying one stores the embroidery parameters on the object and draws a lightweight stitch preview. VectorCraft’s own commands make satin columns of 2 paths, add rungs and bake previews, and its Graphic Styles keep embroidery settings as presets. Machine files come from stitch export design.vectorcraft. (The namespace is one constant, changed in one place once the project has a domain.)
  2. Plug-in features, proposed upstream. An RFC for the ArtCraft team proposed exporter plug-ins, rich parameter schemas (labels, units, groups, conditions), a display-only overlay channel for real stitch previews, budget classes and document-level plug-in data. Every item is generic, not embroidery-specific. VectorCraft took most of them into ABI v1, in 0.14.0 to 0.17.0, and M6.8 to M6.12 use them. M9, after 1.0, proposes the rest: overlays, heavy live effects and the objects beside a live effect’s object.
  3. In-tree crate, optional. Because the engine is MIT/Apache and host-agnostic, VectorCraft (or a fork) can embed it natively with panels and a simulator.

14. Testing and conformance (summary)

Conformance-first (conformance): requirements have IDs; cases are data files; the runner reports a requirement × case matrix.

LevelWhatWhere it runs
L0Plan invariants on every generated planevery PR
L1Format conformance: golden bytes, round trips, pyembroidery oracle, fuzzingPR + nightly
L2Generator properties: containment, coverage, spacing, determinism, monotonicityevery PR
L3Ink/Stitch differential metrics on a corpus (pinned Ink/Stitch as a black-box oracle)nightly
L4Physical sew-outs on the Brother machine, recorded through an issue formmilestone gates

Plus unit tests, property tests (proptest), snapshot tests (insta), CLI-in-docs tests (trycmd), mutation testing (cargo-mutants) and coverage ratchets.

15. Documentation (summary)

mdBook site organised by Diátaxis (tutorials, how-to, reference, explanation) plus these design docs. Reference pages are generated from the code and CI fails if they are stale; stitch images are rendered by our renderer from conformance fixtures; VectorCraft UI screenshots are produced by scripted scenarios through VectorCraft’s control channel and compared on every PR. A label on the PR regenerates them. Details: docs pipeline.

16. Security and supply chain

cargo-deny (licences allow-list with GPL denied, advisories, duplicate versions), unsafe forbidden outside the audited ABI module, fuzzed parsers, pinned toolchain, Dependabot for crates and Actions, least-privilege workflow tokens.

17. Release and versioning

SemVer per crate; the plug-in’s version and its VectorCraft ABI version are reported in its manifest. Changelogs from conventional commit scopes (release-plz, M12). Plug-in .wasm files and CLI binaries are attached to GitHub Releases with checksums. A release requires: green gates, compatibility gate green for the current VectorCraft stable, and the machine checkpoint for that milestone signed off.

18. Risks

IDRiskMitigation
R1PES header fields are partly undocumented; the machine could reject a filePES v1 minimal header; pyembroidery oracle; MC-1 in the first milestone
R2ABI v1 budgets too small for full previewsBudget-aware coarse previews, full fidelity in the CLI, and the RFC’s overlay proposal
R3ArtCraft declines the RFC’s open proposalsThe plug-in works without them, and an in-tree integration in a fork is optional
R4Polygon offset/boolean robustnessSpike M0.7; input sanitizing; fuzzing; fallback to diagnostics, never panics
R5Copied GPL code slips inDesign docs first, in our own words (ADR-0012); cargo xtask cleanroom; review checklist
R6Cross-platform float differenceslibm, no FMA-sensitive formulas in quantization, cross-platform hash CI
R7Scope: the compatibility contract is largePhases; compatibility contract tracks coverage; post-1.0 items explicit
R8Brother trim behaviour varies by modelProfile flag; MC-1 tests both encodings
R9VectorCraft breaking changesCompatibility gate on stable, pre-release, release and main
R10Headless UI screenshots need a GPUSpike M0.8 found none needed. Mesa draws the window in software under Xvfb, and the screenshots match above the status bar (docs pipeline)

19. Open questions

  1. Exact Brother model (affects PES version and trim support) — answered at MC-1 at the latest.
  2. Final project name and plug-in id namespace (working name StitchCraft; plug-in ids derive from one constant).
  3. ArtCraft’s appetite for the RFC’s open proposals and for embroidery in-tree. Ask on their Discord before M9. VectorCraft adopted the rest from 0.14.
  4. Where the repository lives on GitHub (needed for the docs site URL and badges).