Independent audit of b2f2e20 / a7adbdc. The canonical, document-state byte
layouts were already correct and golden-locked; this closes the one real
spec-vs-code gap (in the non-canonical layout namespace) and the smaller
doc/test gaps around it.
LayoutObjectId (item 2.6): the spec normatively stated the id "is derived ...
with MUSCLOID" and the ratification log / layout DECISIONS header called it
"pinned" -- but no code uses MUSCLOID (stable_layout_id and
manifestation_layout_id are untagged; synthesized_layout_id borrows MUSCCONF),
and MUSCLOID cannot even be constructed: DomainTag::from_bytes accepts only
built-ins or MUSCS-prefixed tags, so wiring it requires changing the frozen
determinism crate (out of scope for a spec pass, and the spec itself says
MUSCLOID is not a canonical system tag). Kept MUSCLOID as the pinned Track-A
target and made every artifact honest that the v0 code is provisional:
- spec: "is derived" -> "MUST be derived" (forward contract) + a note that
the prototype mints provisional ids; changelog "pinned" -> "specified ...
as the Track-A target".
- records: ratification-log line 2.6 and layout DECISIONS header/body now
state spec-pinned-but-code-provisional; stale "Pass 11 candidate 3"
pointer now cites the ratified requirement.
- provenance.rs comments name the MUSCLOID target and label the current
derivation provisional.
Other fixes:
- epiphany-core/DECISIONS.md: the Tuplet bullet still claimed degenerate
ratios are caught by runtime invariant 16 "since a Tuplet is a plain
struct" -- stale after the construction-time TupletRatio change. Rewritten.
- codec.rs: added degenerate_tuplet_ratio_is_rejected_on_decode, guarding
the TupletRatio::dec re-validation branch that no test exercised (the
constructor was tested, the decode path was not).
- spec: integrity-anomaly snippet kind.canonical_bytes() ->
to_canonical_bytes() (the actual method).
- ids.rs / reduce.rs: clarifying comments (ManifestId's intentional,
golden-locked document_id/generation duplication; compute_promotions
bucketing by voice == (staff_instance, original_voice) via Invariant 5).
Verification: cargo test --workspace (434 pass, +1), clippy --all-targets clean
(0 warnings), fmt clean; spec rebuilds (lualatex, 0 undefined refs, 254pp).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Spec-revision pass (architecture unchanged) converting the v0
implementation's provisional, golden-locked choices into ratified
core_spec.tex text, so durable byte layouts are fixed before the
next-phase build-outs. Worklist: spec/PASS11_WORKLIST.md; per-item
dispositions: spec/PASS11_RATIFICATION_LOG.md.
Adopt-and-pin (bytes): TypedObjectId 16-bit BE discriminant table
0..=27 (added the 5 variants the code carried); promoted-voice
(MUSCSVCE), synthetic-pitch (MUSCSPCH, tuning always in identity),
and integrity-anomaly (MUSCSANM, now a reserved built-in tag)
derivations; ChunkKind/ProfileId/CompressionAlgorithm discriminants;
ManifestId preimage (manifest_id excluded); RationalTime/scalar
layouts + the codec convention baseline the Binary Format companion
inherits.
Decide-and-pin: tempo Linear interpolates speed (not bpm);
StructuralFieldCollision tags the winner Conflicted; lifted the
>2-way / partial-overlap voice-promotion rule to normative; pinned
TransactionCategory and ObjectKind core vocabularies; added
ResolutionAction::Dismiss so the Dismissed state is reachable by an
authored op; pinned the (non-canonical) LayoutObjectId derivation
(MUSCLOID).
Fixes: blob hashing is bare MUSCBLOB||payload (deleted the
contradictory "identically to chunks" phrasing); equal-generation
superblock rule (DivergentSameGeneration); defined ProfileConstraints
with the required RetentionPolicy + first-declared precedence; made
the DVV zero-based floor normative; reconciled the invariant count to
19 and named the three construction-time MUSTs — TupletRatio now
rejects degenerate ratios at construction (zero term or
actual==notated), enforced by a checked constructor + codec decode
validation.
Code changes carry regression tests; byte-layout golden tests now
cite their ratified requirements. Workspace green: cargo test, clippy
-D warnings, fmt; spec builds (lualatex, 253pp). Per-crate DECISIONS
files annotated with the ratification status.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011giSRaHCFCGm1Z2SWv6JHt
Closes the three remaining item-5 sub-parts found in the audit.
② Typed tolerance + overflow (tempo.rs, invariants.rs):
- Replace the ad-hoc `f64::EPSILON` speed-degeneracy guards with a named
TempoIntegration `Tolerance` (relative, non-finite-safe), per Appendix D
"no ad-hoc epsilons"; aligns code with the module's own claim.
- Guard the continued-fraction convergent recurrence with checked i128 ops
(break on overflow) and bound the residual-fraction stop by 1/max_den
instead of f64::EPSILON, so a pathological input can't silently wrap.
- Endpoints::of: wall-clock event end uses checked_add -> Endpoints::Unknown
on overflow, not saturating_add (which could mask an ordering violation).
- Regression tests: equal-endpoint linear segment uses the constant limit;
extreme inversion inputs don't overflow.
① Region-overlap honesty (invariants.rs):
- Unresolvable region-overlap checks (symbolic anchors + shared staff extent)
were silently treated as valid. Add DeferredCheck + deferred_checks() to
surface them explicitly; check_invariants stays sound (no false positives).
- Test proves an undecidable overlap is reported as deferred, not passed, and
that a wall-clock-resolvable disjoint pair is neither violation nor deferred.
③ Identifier-derivation lock-down (graph.rs, pitch.rs, ids.rs):
- Golden-bytes tests pin derive_promoted_voice_id (MUSCSVCE 64-byte preimage),
derive_system_pitch_id (MUSCSPCH input layout), and the TypedObjectId
discriminant table + Registered layout, so an accidental layout change is
caught (the derivations were concrete but unlocked).
- canonical_pitch_bytes NFC-normalizes strings at the derivation boundary,
making the documented NFC guarantee explicit (no-op for the already-NFC
catalog ids).
- DECISIONS P11-1/3/6 updated to record the pinned-and-locked layouts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Implements a total, reversible canonical byte form for the entire
epiphany_core::Score graph, unblocking the byte-level full-Score serialization
gate that M3 had to defer.
epiphany-core/src/codec.rs:
- Score::canonical_bytes() / Score::decode_canonical() with a validating
ScoreDecodeError and a forward-only Reader cursor.
- A local Codec trait with generic combinators (Option/Vec/BTreeSet/BTreeMap/
tuple) and macros (struct_codec!/cstyle_enum_codec!/unit_codec!/
catalog_id_codec!) so encode and decode stay symmetric across ~110 types
spanning graph.rs, event.rs, pitch.rs, time.rs, tempo.rs.
- Uniform form: LE integers, one discriminant byte per tagged union, u32
counts/length-prefixes, every variable-width leaf length-prefixed, raw UTF-8
for free text (so decode(encode(x)) == x for any valid score; catalog ids are
already NFC). EventArena round-trips via iter_canonical + insert.
- Two pub(crate) accessors added for the codec: EventOrderingDAG::edges_ref,
SpellingPrecedence::order_ref.
- Tests: generator-score corpus (valid_score + valid_score_rich), exotic
event/pitch variants the generators omit, distinctness, and decoder
rejection of trailing/truncated/empty bytes.
epiphany-testkit:
- roundtrip::assert_score_serialization_stable: encode the real Score, store it
as a bundle Snapshot, reopen + hash-verify, decode to an equal Score, and
assert a byte-identical re-encode.
- convergence::materialized_score builds a real ~50-bar reduce_onto
materialization for the gate.
- criterion_4_full_score_byte_roundtrip flips from #[ignore] to a live gate;
wired into the conformance suite. Docs (lib.rs, README, core DECISIONS P11-4)
updated to reflect the landed codec.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
M1 — fix Agent C framework defects, tests-first:
- causal ordering: topologically order DVV edges instead of assuming HLC
alone implies causal order (false for adversarial remote envelopes);
HLC only breaks ties among ready operations.
- anomaly cutoff: quarantine from the earliest counter participating in
any violating HLC pair (suffix-minima), e.g. [100,200,50] quarantines
from counter 0, not counter 1.
- pending detection: DVV contiguous ranges use the zero-based per-replica
counter floor; first absent id in any asserted range holds the dependent
pending (vector coverage, not only dots).
- transaction snapshots: rollback removes member-generated conflicts.
- edge tests in concurrent_reduction.rs for all six audited cases.
M2 — reduce onto Agent B's real score graph:
- OperationSet::reduce_onto(&Score) -> GraphMaterialization { state, score }
mutates the real arena, voices, regions, tombstones, indexes, and
cross-cutting structures; base-free reduce() retained.
- VoiceOrigin::SystemPromoted now carries { winning_operation,
losing_operation, original_voice }; spec and Invariant 18 updated.
- graph-aware migration, forward undo, system breaks, promotion pre-pass.
- tests/graph_reduction.rs: 11 tests asserting check_invariants is clean,
plus a 64-seed order-independence sweep.
Pass-11 spec decisions resolved (blocking subset): DVV floor (P11-C7),
HLC-vs-causality, promoted-voice derivation inputs (P11-C4 / core P11-3).
Payload/Score canonical encoding remain deferred to the companion docs.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>