EditorSession::delete_selection() deletes the selected object through the right
operation: a selected pitch (a notehead) -> DeleteIdentifiedPitch (the reducer
degrades a last-pitch event to a rest of the same duration, so the rhythm
survives; a chord note simply drops), a selected event (a rest, a stem) ->
DeleteEvent. The deleted object's layout id no longer exists, so the selection is
cleared. Errors (NoSelection / WrongSelection) leave the session untouched, via the
atomic apply().
This exercises a different reducer path from transpose (tombstone-with-rest-degrade
vs. in-place pitch mutation) and stays small. Tests: deleting a note changes the
graph and the render and drops the selection; the intent requires a selection.
(Duration editing is intentionally not added here: a ModifyEvent duration change is
not materialized into the graph -- graph_replace_event defers position/duration
edits pending the voice non-overlap semantics -- which is an epiphany-ops increment,
not editor-core code.)
Full gate green: build, fmt, clippy, 608 tests, conformance scale 1.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>