epiphany/crates/epiphany-ops/src
Levi Neuwirth a28d888c8e epiphany-editor-core: a headless editor API + a conformance UI-seam gate
Packages the proven editing-loop vertical slice as the API a GUI calls -- no UI,
no rendering backend of its own (it produces a RenderIR). EditorSession owns:

  - selection state (Selection { source, layout_object }): click(point) selects the
    topmost hit, select(id) restores a selection, selection()/clear_selection();
  - render/hit-test query: render() and hit_test() for the GUI to draw and resolve
    clicks/drags;
  - operation minting -- the ergonomics gap the harness exposed, closed before UI
    depends on it: the caller passes an OperationKind to apply() (or an intent like
    transpose_selection(+1)) and the session assembles the OperationEnvelope (id,
    author, stamp, causal context). A GUI never hand-rolls envelope bookkeeping;
  - apply/re-render -- ATOMIC: a minted op the reducer rejects (e.g. a reserved
    replica identity) returns Err(RejectedOperation), not a silent no-op, and a
    diagnostic-only layout returns Err(NotRenderable); on any error nothing mutates,
    operation counter included (the candidate id is committed only on success);
  - selection preservation: the selection is re-resolved against the new layout,
    kept when its layout object survives and cleared when it is gone.

The session is solver-agnostic (Box<dyn ConstraintSolver>), so a GUI plugs in the
Engraver, the stub, or any conformant solver. EditorError implements Display/Error.
epiphany-ops now re-exports AcceptOutcome (accept()'s return type, previously
unreachable) so a caller can inspect a rejection.

Also wires the edit-loop harness into the conformance suite as the [7c] UI-seam
gate: over both fixtures (ten_measure_single_staff and valid_score_rich) every seed
must drive a click->sharpen->re-render cycle whose selection survives the relayout
-- the contract a GUI's correctness rests on.

Full gate green: build, fmt, clippy, 606 tests, conformance scale 1 (incl. [7c]).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 16:47:34 -04:00
..
anomaly.rs Phase 2 (Agent K) M1: value-typed operation payloads + Operation Catalog scaffold 2026-06-24 11:52:02 -04:00
causal.rs Pass 11: ratify provisional byte choices into normative spec text 2026-06-21 22:30:06 -04:00
conflict.rs Pass 11: consolidated byte-layout appendix + pin ObjectKind/ResolutionAction discriminants 2026-06-22 13:16:20 -04:00
decode.rs Agent K M2d (Group 4): score-settings operations 2026-06-25 19:26:31 -04:00
effect.rs Agent K M2c (Group 3): structural container CRUD operations 2026-06-25 18:10:15 -04:00
encode.rs A B C D F 2026-06-19 12:42:31 -04:00
envelope.rs Phase 2 (Agent K) M1: value-typed operation payloads + Operation Catalog scaffold 2026-06-24 11:52:02 -04:00
fuzz.rs Agent K M2d (Group 4): score-settings operations 2026-06-25 19:26:31 -04:00
lib.rs epiphany-editor-core: a headless editor API + a conformance UI-seam gate 2026-06-27 16:47:34 -04:00
migrate.rs Agent K M2d (Group 4): score-settings operations 2026-06-25 19:26:31 -04:00
opset.rs Phase 2 (Agent K) M1: value-typed operation payloads + Operation Catalog scaffold 2026-06-24 11:52:02 -04:00
payload.rs Agent K M2d review follow-up: harden the Group-4 score-settings ops 2026-06-25 21:45:51 -04:00
reduce.rs Agent K M2e review follow-up: tighten catalog accuracy + container creates 2026-06-26 09:52:13 -04:00
slot.rs A B C D F 2026-06-19 12:42:31 -04:00
stamp.rs A B C D F 2026-06-19 12:42:31 -04:00
support.rs Pass 11 follow-up: golden-lock the ratified discriminant tables; fix three spec-text inaccuracies 2026-06-22 09:22:55 -04:00
undo.rs A B C D F 2026-06-19 12:42:31 -04:00
v0.rs Agent K M2d (Group 4): score-settings operations 2026-06-25 19:26:31 -04:00
valuegen.rs Agent K M2d review follow-up: harden the Group-4 score-settings ops 2026-06-25 21:45:51 -04:00