Schema already in 001_init.sql; this is just the Go store layer.
IO markers are project-scoped wall-outlet terminators (a cable's
"this end plugs into a wall socket outside the diagram" endpoint).
Power-by-convention; no schema-level type enforcement.
- CreateIOMarker validates frame_id is in the same project (cross-project
ref → ErrInvalidInput), defaults label to "IO" when blank.
- GetIOMarker is project-scoped — wrong-project read returns ErrNotFound.
- UpdateIOMarker uses the FrameRef tri-state for frame_id (same as
DeviceUpdate) so callers can clear it explicitly.
- DeleteIOMarker is direct delete — ON DELETE SET NULL from the schema
drops the io_markers.frame_id ref cleanly when the frame is deleted
(verified by TestDeleteFrame_SetsIOMarkerFrameIDToNull).
Snapshot now populates IOMarkers from the store; field type tightened
from []any to []IOMarker.
7 new table-driven tests, all green with -race.