KiCad Plotter IR Contract

Purpose

The KiCad Plotter IR is the canonical JSON rendering exchange format for KiCad Monkey. It records drawing operations with names aligned to KiCad plotter calls, while keeping the payload independent from Python object identity and renderer implementation details.

Consumers can use the IR to render SVG, compare drawing output, inspect schematic or board geometry, or translate KiCad drawing primitives into a separate scene model. A consumer should be able to implement that translation from this document and the JSON Schema without reading the Python implementation first.

Contract File

The machine-readable contract is docs/contracts/kicad_plotter_ir_a0.schema.json. It uses JSON Schema draft 2020-12 and validates documents whose root schema value is kicad.plotter_ir.a0.

The schema is intentionally forward-compatible. Known operation kinds have required field checks, records and documents allow additional properties, and unknown operation kinds remain valid when they at least carry a string kind. Consumers should ignore fields they do not understand unless their own workflow requires them.

Document Envelope

A document is an object with schema, source_kind, total_operations, and records. Optional metadata includes source_path, generated_utc, document_id, canvas, coordinate_space, background_color, render_hints, and context.

source_kind identifies the source family: SCH, SYM, PCB, MOD, or PCB_FOOTPRINT. MOD represents a standalone .kicad_mod footprint, while PCB_FOOTPRINT represents a footprint extracted from a board. canvas normally carries page or board extents in nanometres. coordinate_space should use {"unit":"nm","y_axis":"down"}. Coordinates are integers unless a KiCad plotter call naturally uses an angle, radius, or control point represented as a number.

{
  "schema": "kicad.plotter_ir.a0",
  "source_kind": "SCH",
  "total_operations": 0,
  "canvas": {"width_nm": 297000000, "height_nm": 210000000},
  "coordinate_space": {"unit": "nm", "y_axis": "down"},
  "records": []
}

Records

A record groups all operations emitted for one KiCad source item or one synthetic document item. Required fields are uuid, kind, object_id, operation_count, and operations. Optional bounds is an axis-aligned box with left, top, right, and bottom in nanometres.

Record kind is a source-facing name such as wire, symbol_instance, gr_line, segment, via, zone_fill, or footprint. Additional record fields may carry source metadata such as layer names, net identifiers, page paths, or variant state. Consumers should use those fields as hints and should not require them for basic geometry rendering.

Operations

An operation is a flat object whose required kind is the plotter call name. Serialized records also include zero-based index. All other fields belong to that operation's payload or to optional metadata such as context. Known operation kinds are:

Units And Geometry

Linear coordinates and dimensions are nanometres in KiCad drawing space. The Y axis points down. Angles are degrees. Text orientation follows the plotted orientation, not necessarily the raw source orientation. Point arrays are two-item integer arrays, for example [[0,0],[1000000,0]].

Fill values are KiCad fill names: NO_FILL, FILLED_SHAPE, FILLED_WITH_BG_BODYCOLOR, FILLED_WITH_COLOR, HATCH, REVERSE_HATCH, and CROSS_HATCH. Colors are uppercase or lowercase hex strings in #RRGGBB or #RRGGBBAA form.

Text And Images

Text operations carry the resolved display string in text. Multiline text uses embedded newline characters and sets multiline to true. Font face is an empty string for KiCad stroke text and a face name for outline text. Render cache fields are optional acceleration data; consumers that cannot use them should fall back to the normal text fields.

PlotImage stores the bitmap as base64 in image_data_b64 with an image_format string. Consumers should treat the image rectangle as the authoritative placement and should not infer document scale from embedded pixel dimensions.

Context Extensions

context is an optional object allowed on the document, records, and operations. Version a0 standardizes the extension container and the context.hyperlink.href key for linked text. Unknown keys must not break consumers. Producers should use stable, namespaced keys when metadata is intended for more than one tool.

Geometry rendering must not require context. The field is for source annotations, semantic links, provenance, and future non-geometric metadata. Text hyperlink metadata lives in the context of the affected Text operation: {"hyperlink":{"href":"https://example.test"}}.

Normalization

Normalized IR removes nondeterministic fields such as generated_utc and may normalize source_path separators. Operation order and record order remain significant. operation_count and total_operations are derived counts and should match the serialized arrays.

Consumer Guidance

Scene converters should walk records in order, then operations in index order. Use record identity and grouping operations to preserve source traceability. Treat state operations as optional renderer hints unless the operation payload already contains the effective stroke or fill fields needed by the consumer.

A consumer that targets another drawing model should preserve source linkage separately from geometry. The IR can describe a rectangle, polygon, text, or pad flash without explaining why the source object exists. Record metadata and context provide the place to keep those semantics without changing primitive geometry.

Validation

Contract tests validate runtime IR examples against the schema and check that known operation kinds in the schema match the public KiCadPlotterOpKind enum. A producer should run the schema validator on exported IR before publishing a new contract-bearing output.