epiphany/crates/epiphany-ops
Levi Neuwirth aee4ff92b7
P13-S16 EXECUTED: StaffGroup.members becomes a maintained projection
Disposition A replaces genesis tranche G3a's disposition B. Staff.group was
already the sole authority, but members was stored exactly as carried and
neither maintained nor trusted, so both disagreeing states were permitted
outcomes. Neither is authorable any more.

  - CreateStaffGroup refuses a non-empty carried members (ContainerNotEmpty).
    This is an empty-container precondition on the carried value, NOT a
    referential one, so unlike the sibling mints it is not graph-gated and
    holds base-free too. t7's assertion inverts for exactly that reason.
  - CreateStaff carrying group: Some(g) appends the staff to g's members in
    the graph, idempotently; undo of a staff strips it back out.
  - Graph invariant 21, StaffGroupMembershipAgreement, flags disagreement in
    either direction between live objects via two independently removable
    checks. It abstains on dangling membership -- an undeclared member is
    invariant 10's concern, not a disagreement.
  - staff_group_values keeps the carried value, and seed_from_graph reseeds it
    with members emptied, closing the reload hazard that only appears after a
    snapshot round trip.
  - CURRENT_REDUCTION_ALGORITHM_VERSION 0 -> 1 with its Bumps entry, naming
    both causes separately: CreateStaffGroup changes a reduction verdict,
    CreateStaff changes canonical reduced state. Either alone requires it.
    Bases materialized before this rung must be rebuilt, not reused.

Specification: operation_catalog.tex 0.15.0 and core_spec.tex's Revision
History; nine disposition-B prose sites rewritten, invariant 21 appended to the
Chapter 5 enumeration (count 20 -> 21), both PDFs rebuilt. No payload bytes
move, no schema or epoch moves, no vector artifact changes.

Evidence: 20 pins, 14 gates, 11 mutation executions. Baseline 1577 -> 1583
(six net-new tests). Both S27 tripwires fired on the bump and were updated to
independent literals, never to the constant.

Six findings reported against the contract rather than patched into it:
invariant 21's abstention vs the undo-hole attribution in 0.6/pin 5a/pin 6b;
M6a's failure set is seven, not six; t8d under M2 is falsified as a survivor;
pin 10 cites four of nine prose sites; cargo test --workspace truncates the
failure set without --no-fail-fast; pin 8's line numbers had drifted.

CLAUDE.md and spec/HANDOFF_2026-08-07.md are deliberately NOT in this commit
(contract 4a) and still describe the pre-bump state; their reconciliation is
post-acceptance work.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ps1szk2mSfgp4Cz21eVH9x
2026-08-10 17:18:20 +02:00
..
examples A B C D F 2026-06-19 12:42:31 -04:00
src P13-S16 EXECUTED: StaffGroup.members becomes a maintained projection 2026-08-10 17:18:20 +02:00
tests Schema major 2 Phase B: snapshot side + honest stamps (data-model fills) 2026-07-07 16:30:07 -04:00
Cargo.toml A B C D F 2026-06-19 12:42:31 -04:00
DECISIONS.md P13-S19: what a partial measure actually costs 2026-07-31 18:13:44 -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.