kerf-engine/GSD-INITIATE.md
jlightner 1adcbb3348 init: GSD project scaffolding for Kerf — 3 milestones, requirements, decisions
M001: Kerf Engine (pipeline, API, presets, Docker) — 3 slices, 10 tasks
M002: Kerf App (Import UI, Canvas, Text system) — 3 slices (planned, not detailed)
M003: Export, Docker Compose, Embed Mode — 3 slices (planned, not detailed)

25 requirements extracted from GSD-INITIATE.md
7 architectural decisions recorded
Human checkpoints gate M001→M002→M003 transitions
2026-03-26 03:55:59 +00:00

18 KiB

Kerf — Project Brief

Working Directory: /vmPool/r/repos/xpltdco/kerf Deployment Target: Docker container (self-hostable or cloud-hosted) Primary Use Case: Raster-to-vector conversion engine + 2D sign/patch design canvas + DXF export workflow


Vision

Kerf is a modular, Docker-deployed web application with two distinct but composable layers:

  1. The Kerf Engine — a standalone, API-first raster-to-vector conversion module. This is proprietary IP. It must be built with clean, well-documented input/output contracts so it can be extracted and embedded into future applications independently of this one.

  2. The Kerf App — a full-featured 2D design canvas and sign configuration workflow that consumes the Kerf Engine and delivers a complete end-to-end experience: upload an image or design from scratch, refine the vector output, compose a sign layout, and download a production-ready DXF file.

The two layers must remain architecturally decoupled. The Engine is not a feature of the App — the App is a consumer of the Engine.


Repository Structure

/vmPool/r/repos/xpltdco/kerf/
  /engine/          ← Kerf Engine (standalone module, own package.json / pyproject)
  /app/             ← Kerf App frontend (React)
  /server/          ← Kerf App backend API (Python/FastAPI)
  /docker/          ← Dockerfiles and compose configs
  /docs/            ← Engine API docs, architecture notes
  README.md
  docker-compose.yml

Part 1: The Kerf Engine

What It Is

A self-contained service that accepts raster image input and returns clean vector output. It also accepts existing vector input (SVG) for simplification passes. This is the hardest, most valuable piece of the entire project. Build and validate this first before touching the app canvas.

Processing Pipeline

The engine runs a multi-stage pipeline internally:

Input (raster or vector)
  → Preprocessing (OpenCV)
  → Vectorization (Potrace or VTracer, mode-dependent)
  → Post-processing (path simplification, cleanup)
  → Output (SVG, DXF, or JSON path data)

Stage 1 — Preprocessing (raster inputs only)

Uses OpenCV. The following operations are applied in sequence, each tunable via parameters:

  • Grayscale conversion
  • Denoise (bilateral filter — preserves edges better than Gaussian for this use case)
  • Contrast enhancement (CLAHE — adaptive histogram equalization)
  • Threshold (Otsu auto-threshold as default, manual override available)
  • Edge detection mode (optional — Canny, for line-art inputs)
  • Dilation/erosion (for cleaning up noisy inputs before tracing)

Stage 2 — Vectorization

Two modes, selectable per request:

Mode A: Potrace (default)

  • Fast, deterministic, excellent for high-contrast logos and line art
  • Exposes Potrace tuning parameters: turdsize, alphamax, opticurve, opttolerance
  • Best for: clean logos, stencils, bold graphics, sign art

Mode B: VTracer

  • Better handling of photographic or noisy inputs, color-aware
  • Exposes VTracer params: colormode, hierarchical, filter_speckle, color_precision, layer_difference, corner_threshold, length_threshold, splice_threshold
  • Best for: complex images, multi-color inputs, detailed illustrations

The engine selects Mode A by default. The calling application (or user via preset) can override.

Stage 3 — Post-Processing

  • Path simplification: Ramer-Douglas-Peucker algorithm, epsilon tunable. Also applies to vector-only inputs (simplification-only mode).
  • Island detection: Identify and flag interior counter paths (letter holes, enclosed shapes) for proper nesting in DXF output
  • Open path detection and repair: Flag or auto-close open endpoints
  • Node count reporting: Return node count per path so the UI can warn the user if complexity is too high for practical cutting

Stage 4 — Output

Supported output formats:

  • SVG — standard, browser-renderable
  • DXF — AC1015+ (AutoCAD 2000 compatible), via makerjs or direct entity generation
  • JSON — raw path data (array of bezier/polyline commands) for consuming applications to render or further process

All outputs include metadata:

{
  "format": "svg",
  "path_count": 12,
  "node_count_total": 847,
  "open_paths": 0,
  "warnings": ["High node count — consider increasing simplification"],
  "processing_ms": 340
}

Engine API Contract

The Engine exposes a clean HTTP API. This is the stable interface other applications will consume.

POST /engine/trace

Trace a raster image to vector.

Request: multipart/form-data

file          — image file (PNG, JPG, BMP, TIFF, WebP)
mode          — "potrace" | "vtracer" (default: potrace)
output_format — "svg" | "dxf" | "json" (default: svg)
preset        — "sign" | "patch" | "stencil" | "detailed" | "custom" (default: sign)
params        — JSON string of override parameters (optional, merges over preset defaults)

Response: application/json

{
  "output": "<svg>...</svg>",
  "format": "svg",
  "metadata": { ... }
}

POST /engine/simplify

Simplify an existing SVG vector.

Request: multipart/form-data

file          — SVG file
epsilon       — float, RDP simplification tolerance (default: 1.0)
output_format — "svg" | "dxf" | "json"

Response: same shape as /engine/trace

GET /engine/presets

Returns the full list of available presets and their parameter values.


Presets

Presets are named configurations that set all tuning parameters to sensible defaults for a given application. Users pick a preset first, then fine-tune from there.

Preset Description Key Biases
sign Metal signage, bold text cutouts High contrast, aggressive simplification, low node count
patch Embroidered patches, fabric cutting Medium detail, smooth curves, closed paths enforced
stencil Physical stencil cutting Simplified, bridges flagged, no islands
detailed High-fidelity illustration work Low simplification, maximum path fidelity
custom All params exposed, no defaults applied

Presets are stored as JSON config files in /engine/presets/ so new ones can be added without code changes.


Engine Testing Checkpoint

Stop here and validate the engine before building anything else.

Prompt the human to:

  1. Submit a clean high-contrast PNG logo via the API and confirm the SVG output renders correctly in a browser
  2. Submit the same image in dxf output mode and open the result in Inkscape or LightBurn — confirm paths are closed and geometry is clean
  3. Submit a noisy or photographic input and compare Mode A vs Mode B output
  4. Submit an existing complex SVG and run it through /engine/simplify — confirm node count drops and shape is preserved
  5. Test each preset and confirm the outputs differ meaningfully

Do not proceed to the App canvas until the human explicitly signs off on engine output quality.


Part 2: The Kerf App

Overview

A React-based single-page application served by a FastAPI backend. Deployed as a Docker container. Functions both as a standalone web app (direct URL access) and as an embeddable component (script tag + div).

The App is composed of three views that function as a linear workflow with the ability to jump back:

[1. Import & Convert] → [2. Design Canvas] → [3. Export]

View 1: Import & Convert

This is the Kerf Engine's UI surface. The user arrives here first.

Import Options

  • Upload raster image (PNG, JPG, BMP, TIFF, WebP) — primary flow
  • Upload existing vector (SVG) — routes to simplification mode
  • Start blank — skip import, go directly to canvas with empty artboard

Vectorization Controls (shown after upload)

Layout: image preview on the left, controls on the right, live output preview updates as controls change.

Preset Selector

  • Visual cards for each preset (icon + label + one-line description)
  • Selecting a preset populates all sliders with preset defaults
  • User can then adjust individual sliders freely

Control Sliders / Toggles All controls update the preview in real time (debounced, ~300ms):

Control Type Description
Detail Level Slider Master control — maps to simplification epsilon. Low = more detail, High = simpler paths
Threshold Slider Black/white cutoff for rasterized input preprocessing
Noise Filter Slider Speckle/noise removal aggressiveness
Smooth Curves Slider Curve fitting vs sharp corners
Path Mode Toggle Outline only vs filled regions
Color Mode Toggle (VTracer only) B&W vs color-aware tracing
Advanced Expandable panel Exposes all raw Potrace/VTracer parameters for power users

Output Info Bar Below the preview — shows live stats: path count, total node count, open path warnings, estimated file size. Color-coded: green (good), yellow (high complexity warning), red (open paths or unusable geometry detected).

Action Buttons

  • "Use This" — accepts current output and advances to the Design Canvas, carrying the vector data forward
  • "Re-import" — start over with a new file

View 2: Design Canvas

A 2D design environment. Think Illustrator-lite meets a CNC layout tool. Built with Konva.js + React (react-konva).

Artboard Setup

On first entering the canvas (or when starting blank), the user defines their artboard:

Shape:

  • Rectangle
  • Square
  • Circle
  • Oval/Ellipse
  • Shield (common patch shape)
  • Pennant
  • Custom (width + height freeform)

Dimensions:

  • Width and Height inputs (inches)
  • Units toggle: inches / mm
  • The artboard renders at a scaled representation — 1:1 real-world proportion maintained

Canvas Objects

All objects are layered, selectable, moveable, resizable, and deletable. Standard selection handles. Multi-select supported.

Text Objects

  • Add text via toolbar button
  • Font picker — reads from /fonts/fonts.json manifest (same pattern as the sign component: local .otf files, dynamic manifest, per-font warning flags)
  • Font size, letter spacing, line height
  • Alignment: left, center, right
  • Text renders using opentype.js for accurate glyph representation
  • Toggle: "Convert to paths" — flattens text to vector paths for export (required for DXF)

Imported Vector Object

  • The output from View 1 drops onto the canvas as a vector object
  • Fully moveable, scaleable, rotatable
  • Can be duplicated

Basic Shape Objects

  • Rectangle / Square
  • Circle / Ellipse
  • Line — with style variants:
    • Solid
    • Dashed (configurable dash/gap length)
    • Dotted
    • Double line
    • Centerline (long-short-long pattern, common in CAD)
  • Stroke weight control
  • Fill toggle (filled vs outline only)

Object Panel Right sidebar showing layer stack — all objects listed, reorderable via drag, visibility toggle per object, lock toggle per object.

Canvas Toolbar

Top bar with:

  • Select tool
  • Text tool
  • Shape tools (rectangle, circle, line)
  • Zoom in / out / fit to screen
  • Undo / Redo (full history stack)
  • Grid toggle (snap to grid, configurable grid size)
  • Rulers toggle

Alignment Tools

When one or more objects are selected:

  • Align left / center / right (relative to artboard or to selection)
  • Align top / middle / bottom
  • Distribute horizontally / vertically
  • Center on artboard (single click to center both axes)

View 3: Export

Clean, focused export screen. No distractions.

File Format Selector

  • DXF (default — AC1015+)
  • SVG
  • PNG (raster export at specified DPI)

DXF-Specific Options

  • All text must be converted to paths before DXF export — if any unconverted text objects exist on canvas, warn the user and offer a one-click "Convert All Text to Paths" before proceeding
  • Layer assignment — assign canvas objects to named DXF layers (e.g., "cut", "engrave", "score")
  • Units: inches or mm

Filename

  • Default pattern: [project-name]_[width]x[height].[ext]
  • Editable before download

Download Button

  • Label: "Download File"
  • Shows spinner during generation
  • Triggers browser file download immediately on completion

Export Validation

Before generating the file, run a pre-export check and display results:

  • All paths closed
  • No open endpoints
  • ⚠️ High node count (suggest simplification)
  • Unconverted text objects (block export until resolved)

Embeddability

Kerf App can run in two modes:

Standalone — accessed directly via URL, full-page experience

Embedded — dropped into an existing website as a component:

<script src="https://your-kerf-host.com/kerf.js"></script>
<div id="kerf-app"></div>

In embedded mode:

  • Renders within its container div
  • All styles scoped (Shadow DOM or prefixed classes)
  • Communicates back to host page via postMessage events (e.g., on file download, on export complete)
  • No host page dependencies required

Docker Deployment

Services

services:
  kerf-engine:     # Python/FastAPI — vector processing
  kerf-app:        # Node/React — frontend build served by nginx
  kerf-server:     # Python/FastAPI — app backend API

kerf-engine can be deployed independently if consuming apps only need the engine API.

Environment Config

KERF_ENGINE_URL=http://kerf-engine:8000
KERF_FONTS_DIR=/app/fonts
KERF_PRESETS_DIR=/app/presets
KERF_MAX_UPLOAD_MB=20
KERF_OUTPUT_FORMATS=svg,dxf,json

Volumes

./fonts      → /app/fonts       (font .otf files + fonts.json manifest)
./presets    → /app/presets     (preset JSON configs)
./uploads    → /app/uploads     (temp storage, auto-purged)

Repository README

Must cover:

  • What Kerf is (app + engine overview)
  • Quick start (docker-compose up)
  • Engine API reference (endpoint docs, request/response shapes, preset list)
  • How to add fonts (drop .otf + update fonts.json)
  • How to add presets (drop JSON config into /presets/)
  • Embed snippet for host site integration
  • Engine standalone usage (for developers consuming just the engine)
  • Known limitations
  • License

Build Order

Build in this sequence. Do not skip ahead.

  1. Kerf Engine — pipeline, API, presets → Checkpoint 1: Engine validation (human review)
  2. Canvas + Artboard — Konva setup, artboard shape/size, basic object manipulation → Checkpoint 2: Canvas UI review (human plays with it)
  3. Text + Font system — font manifest loading, opentype rendering, path conversion
  4. Import flow — View 1 UI, Engine integration, vector lands on canvas
  5. Export flow — View 3 UI, DXF generation, pre-export validation → Checkpoint 3: DXF opened in LightBurn/Inkscape (human confirms geometry)
  6. Docker packaging — compose file, env config, volumes
  7. Embed mode — script tag delivery, scoped styles, postMessage events → Checkpoint 4: Embedded in a plain HTML test page (human confirms no style bleed, component works)

Testing & Review Checkpoints

Checkpoint 1 — Engine Output Quality

Human must:

  • Submit a clean logo PNG → confirm SVG output in browser
  • Submit same file as DXF → open in Inkscape or LightBurn, confirm closed paths
  • Submit a noisy photo → compare Potrace vs VTracer output
  • Submit a complex SVG → run simplification, confirm node count drops
  • Test sign and detailed presets, confirm outputs differ meaningfully

Do not build the App canvas until this is signed off.

Checkpoint 2 — Canvas UI Review

Human must:

  • Create an artboard in each available shape
  • Add text, change fonts, resize, move
  • Add shapes and lines, test all line styles
  • Test undo/redo stack
  • Test alignment tools against artboard

Do not build the import/export flows until this is signed off.

Checkpoint 3 — DXF Export Validation

Human must:

  • Design a sign with text and an imported vector object
  • Export as DXF
  • Open in Inkscape or LightBurn
  • Confirm all paths closed, geometry clean, no open endpoints, correct scale

Do not proceed to Docker packaging until this is signed off.

Checkpoint 4 — Embed Mode Validation

Human must:

  • Drop embed snippet into a plain HTML page
  • Confirm component renders correctly inside host page
  • Confirm no style bleed into surrounding page
  • Confirm download works from embedded context

Key Technical Decisions

Concern Decision
Engine language Python + FastAPI (OpenCV, Potrace, VTracer all native here)
Frontend framework React + react-konva
Canvas library Konva.js
Font rendering opentype.js — same object reused for preview and DXF path extraction
Font loading Local .otf files + fonts.json manifest, resolved relative to server font volume
DXF generation makerjs (handles opentype integration and DXF export natively)
Raster tracing Potrace (Mode A) + VTracer (Mode B), OpenCV preprocessing
Path simplification Ramer-Douglas-Peucker
Vectorization API REST over HTTP, JSON responses — engine is stateless
Deployment Docker Compose, engine as independent service
Embed delivery Single bundled JS + scoped CSS via Shadow DOM

What Success Looks Like

  • Engine accepts a dirty raster logo and returns a clean, cuttable SVG or DXF with no manual cleanup required for a typical sign input
  • Engine runs as an independent API that a separate app can consume with no knowledge of the Kerf App
  • User can upload a logo, tune vectorization with intuitive sliders, place it on a correctly-sized artboard, add business name text, and download a DXF that 1:1 represents their design at real-world scale
  • DXF opens in LightBurn with zero geometry errors and is ready to cut
  • Entire app ships as a single docker-compose up command
  • Component can be embedded in a third-party site with two lines of HTML

Engine first. Everything else is a cakewalk once the engine is solid.