Rust Phase 4 native worksheet reader/writer slice

Status: accepted native product slice.

Decision and boundary

WorksheetView is a borrowed, source-ordered reader for both modern kicad_wks and legacy page_layout roots. It promotes metadata, setup, line, rectangle, polygon, text/font, repeat, corner, and bitmap fields while preserving the Python model's defaults and first-value behavior. Modern bitmap data retains string scalars only; legacy pngdata retains its first payload scalar. Unknown root forms stay outside the typed projection.

The reader performs one structural scan of the root and direct children. Individual known items are decoded lazily, so callers can iterate a large worksheet without retaining a generic tree for the whole file. Item order and bitmap data-part boundaries are observable. WorksheetDocument owns the exact UTF-8 source and writes it unchanged unless a promoted edit is requested.

The first edit creates or updates the setup line width. It rejects ambiguous setup/linewidth forms, preserves unknown text and newline style, reparses the candidate before commit, and returns a stable no-op when the requested value is already present. This is an exact source writer, not a canonical worksheet pretty-printer.

Resource and safety behavior

Reader admission consumes at most max_source_bytes + 1. Structural depth, retained direct-root forms, and typed item count have independent bounds before typed iteration, so forward-compatible unknown forms cannot consume the item allowance. Each lazy item has independent node and decoded-string ceilings. A streaming lexical preflight counts polygon point sets/points, accepted justification tokens, and exactly the bitmap values retained by the selected modern or legacy data form before the generic per-item tree is retained. Bitmap part and aggregate decoded-byte limits therefore stop oversized data without first collecting the complete typed vector.

All writes enforce max_output_bytes before publishing output. Invalid UTF-8, I/O failures, nonfinite mutation values, ambiguity, and resource failures use the core diagnostic envelope and leave the owned document unchanged. Lazy item positions are rebased to the original source. The implementation is linear in input plus emitted output, contains no package-owned unsafe code, and adds no dependency.

Evidence and retained work

Rack case L1_033 requires all five package-local worksheets. Its native executable compares every promoted field with the Python model, preserves interleaved item order, performs exact first and stable second writes, and cannot silently skip missing corpus files. Focused Rust tests cover modern and legacy defaults, every advertised lazy semantic ceiling, bounded input and output, absolute diagnostics, I/O failure, unknown-form preservation, CRLF insertion, ambiguity, and transactional update/no-op behavior.

KiCad does not expose a dedicated command-line worksheet parser, so this slice does not claim an independent kicad-cli worksheet oracle. The durable Python implementation and exact source round trip are the current semantic authorities. Later board/schematic plotting integration can add an application-level worksheet rendering oracle.

Native schematic compiler/writer and project writeback obligations are covered by the accepted Phase 4 exit under separate governed surfaces. Plotter and native Cruncher closure are governed by later accepted phases; they do not widen this worksheet reader/writer boundary.