epiphany/crates/epiphany-ops
Levi Neuwirth a207077cd7 Agent K M2c (Group 3): structural container CRUD operations
Third broad-K0 subsystem group — six new value-typed ops for the score-graph
containers, reusing M1's disciplines (additive: OperationKind variants 15-20,
new apply arms + reduction methods; framework frozen). Per the project lead's
call, container deletes are EMPTY-ONLY (no cascade): a precondition NoOp unless
the container has no live children, so the caller deletes contents first.

- CreateRegion / DeleteRegion, CreateStaffInstance / DeleteStaffInstance,
  CreateVoice / DeleteVoice. Creates are value-typed mints of an empty container
  (set-union creation); deletes are delete-wins tombstones gated on emptiness.
- core: expose Region / StaffInstance / Voice via CanonicalValue (no new byte
  layout — they already have whole-score Codec impls), with round-trip coverage.
- New PreconditionFailureReason::ContainerNotEmpty (additive discriminant 10;
  encode + decode), reported when an empty-only delete hits a non-empty container.

Reduction (reduce.rs):
- Two child-existence indices, region_instances and instance_voices, drive the
  emptiness checks (a voice's events are read from voice_occupancy), so the
  ledger projection and the graph agree on every delete result. Populated by
  seed_from_graph, the create ops, and implicit voice creation in insert_event.
- CreateStaffInstance / DeleteStaffInstance maintain the region's staff_extent so
  it lists exactly the manifested staves (Chapter 5 RegionExtents); valuegen's
  fresh region uses a far-future wall-clock extent so it never overlaps an
  existing region in both time and staff.

Migration: v1-native (no lossy v0 predecessor) -> project/migrate by identity;
group1_and_group2_kinds_round_trip_by_identity extended to cover Group 3.

Coverage:
- testkit operation_payload + ops fuzz gen_payload emit the six kinds, so the
  convergence / determinism / migration-equivalence gates exercise the
  bookkeeping projection at scale.
- A reduce_onto graph test materializes a region -> staff instance -> voice
  subtree (invariant-clean), asserts the empty-only delete refuses a non-empty
  container with ContainerNotEmpty, and verifies an ordered teardown clears the
  subtree from both graph and ledger.

Gates: build/fmt/clippy -D warnings clean; cargo test --workspace green (criterion
1 green with the new container objects in the corpus); conformance_suite scale 1
passes. Catalog sections + DECISIONS for these ops land in M2e per the staged
plan. The unrelated Agent-I working tree is left uncommitted; this commit stages
only core/ops/testkit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 18:10:15 -04:00
..
examples A B C D F 2026-06-19 12:42:31 -04:00
src Agent K M2c (Group 3): structural container CRUD operations 2026-06-25 18:10:15 -04:00
tests Agent K M2c (Group 3): structural container CRUD operations 2026-06-25 18:10:15 -04:00
Cargo.toml A B C D F 2026-06-19 12:42:31 -04:00
DECISIONS.md Agent K: DeleteEvent re-anchoring — make the graph follow the ledger 2026-06-25 17:23:11 -04:00
README.md Land M1 + M2 (Agent C): framework edge fixes and real-Score graph integration 2026-06-21 16:37:51 -04:00

README.md

epiphany-ops

The Epiphany concurrent semantics: the operations through which the score graph becomes a live model, and the deterministic reduction by which a set of operations becomes a materialized score state. Implements the normative requirements of Chapter 6 (Semantic Operations and Concurrent Reduction) of the core specification (spec/core_spec.pdf). This is Agent C's crate per spec/QUICKSTART.md, building on Agent A's epiphany-determinism and Agent B's epiphany-core.

A score's state is defined by the set of operations committed to it. Any materialized graph is a deterministic reduction of that set; caches, snapshots, and partial reductions are acceleration structures, never the source of truth. — Chapter 6, Design Principles

The thesis in one paragraph

The replicated operation set is a grow-only CRDT: replicas accumulate envelopes and converge on the same set. The materialized graph is not a CRDT — it is the deterministic reduction of that set in a single canonical order (causal-first, then the HLC tuple). Any permutation of the same envelopes reduces to byte-identical materialized state. That property is the determinism heart of the architecture, and the reduction fuzzer is its tripwire.

What's here

Area Items Spec
Stamps HybridLogicalClock, OperationStamp, the reduction & monotonicity tuples Ch. 6 §"Operation Identity and Stamps"
Causal context CausalContext (dotted version vector), covers, the missing-predecessor signal Ch. 6 §6.2
Payloads OperationKind, the discriminator-only OperationKindTag, OperationPayload, the §6.10 representative ops Ch. 6 §"Operation Envelopes", §6.10
Envelopes OperationEnvelope, EnvelopeHash (MUSCENVH), well_formed (incl. stamp.id == id) Ch. 6 §6.4
Slots OperationSlot::{Single, Equivocated}, the order-independent (Pass-10) transitions Ch. 6 §6.5
Anomalies AnomalousReplicaSegment, IntegrityAnomaly/Kind, the HLC-monotonicity detector Ch. 6 §6.6; Ch. 5 §"System-Derived Counter Collisions"
Effects OperationEffect, NoOpReason, the typed PreconditionFailureReason, RepairRecord/RepairKind Ch. 6 §6.3.2, §6.5
Conflicts ConflictRecord, ConflictKind, content-derived ConflictId (derive_conflict_id), the registry, resolution Ch. 6 §6.4
Transactions / undo TransactionDescriptor with the causal-prior-descriptor rule, UndoTransactionPayload / UndoPolicy Ch. 6 §6.6, §6.8
Operation set OperationSet: accept pipeline (well-formedness → slot → causal), grow-only Ch. 6 §"Envelope Acceptance"
Reduction canonical_reduction_order (single function), MaterializedState, the reduction driver Ch. 6 §6.3

The determinism this crate enforces

  1. A single reduction-order function. canonical_reduction_order performs deterministic causal topological ordering, using the intrinsic stamp tuple (physical, logical, replica, counter) only among ready operations.
  2. Order-independent equivocation. A duplicate OperationId with different canonical bytes transitions its slot to Equivocated regardless of which envelope arrived first (Pass 10). Equivocated slots contribute nothing to reduction; dependents are held pending.
  3. Content-derived facts. ConflictId and IntegrityAnomalyId are derived from content, so two replicas reducing the same set agree on every conflict and anomaly id — the conflict registry and anomaly register are deterministic materialized facts, not local bookkeeping.
  4. Byte-identical materialized state. MaterializedState::canonical_bytes serializes the effect log, conflict registry, anomaly register, object existence, spellings, and LWW fields in their normative orders.
  5. Real graph materialization. OperationSet::reduce_onto(&base_score) returns GraphMaterialization { state, score }. The graph is mutated in the same canonical order and compares by canonical event identity, independent of arena storage order.

Hand-off gates

Run the gate harnesses (QUICKSTART, Agent C):

cargo test -p epiphany-ops
cargo run --release -p epiphany-ops --example fuzz_reduction          # 10k iters, seed 0
cargo run --release -p epiphany-ops --example fuzz_reduction 100000 7 # soak, seed 7
  • Reduction determinism — every randomized envelope set reduces to byte-identical materialized state under any acceptance order (v0 acceptance criteria 1 and 5).
  • Equivocation order-independence — every duplicate-id-with-different-bytes scenario equivocates regardless of arrival order (v0 acceptance criterion 3).

The integration tests (tests/concurrent_reduction.rs) exercise these plus transaction atomicity, descriptor precedence, anomaly exclusion, and forward undo through the public API.

Scope and decisions

Chapter 6 specifies the framework and a representative selection of operations; the full ~6080-primitive catalog is an explicit open question (§6.11) deferred to the Operation Catalog companion. This crate implements the framework in full and the representative operations, which is sufficient to exercise every reduction discipline. The representative operations can also reduce onto an epiphany_core::Score: insert/delete, voice promotion, supported cross-cutting structures, system breaks, migration checks, transaction rollback, and undo mutate the real graph while preserving Agent B's invariants. reduce() remains the base-free CRDT/bookkeeping API; reduce_onto() is the graph-aware editing path. See DECISIONS.md for remaining payload boundaries.

Per QUICKSTART "Don't do these": undo is the spec's forward compensating operation, never inverse-based; unsafe is forbidden; everything is sync.