epiphany/crates/epiphany-core/src
Levi Neuwirth 17c1d67561 P13-S19: what a partial measure actually costs
Filed as a deferral -- pickups unmodelled -- it is closer to a live defect, and
the tree already held the proof. m35 placed a first measure at offset 0 and its
successor half a whole note later under a whole-note signature and asserted
invariant 20 fires. That is a pickup. The test has been labelled "wrong distance"
since packet 2. create_measure applies the same rule as a refusal, now observed
end to end rather than cited: the successor comes back NoOp with
MeasureMeterMismatch. Authoring a pickup does not leave it unmodelled; it makes
the rest of the instance unauthorable.

Both refusals carry the same reason code, so the fixture is the only thing
separating them. Pickup and successor both declare None, which keeps clause 2
from running on either side and makes the observed refusal provably clause 3's.
The pickup's own mint is asserted Applied before the successor's NoOp, because a
fixture whose operations never execute produces a non-Applied result
indistinguishable from a refusal.

The exemption is narrower than every document said. A first measure escapes only
the predecessor-dependent checks -- invariant 20's boundary clause, and
create_measure's clauses 1 and 3 -- plus agreement when it declares None or a
matching signature, and only when its other preconditions hold. It can still be
refused for a dead parent or an unresolving anchor referent, and invariant 10 can
still flag it. Seven surfaces carried the loose form; one had hardened into
falsehood, claiming all three clauses are vacuous for a first measure when
clause 2 has no predecessor dependency at all.

core/DECISIONS.md is deliberately untouched. It already said "never flagged by
the boundary clause" -- the one site that drew the distinction correctly -- and
an earlier contract draft listed it as defective by matching the phrase without
reading its qualifier. The corrected ops entry now quotes that qualifier, and a
positive gate check protects it.

A mid-score partial enters successfully and its successor fails, so the scope is
boundaries following any partial measure, not partial measures. The root cause is
a missing quantity rather than a missing exemption: both rules compare the
start-to-start distance against the governing signature's full measure_duration
when it actually equals the predecessor's own content duration. Introducing that
quantity is a semantic rung; this one stops at its edge, with both function
bodies byte-identical.

P13-S24 is filed for the Chapter 3 splitter deferral, which shares the missing
partial-duration concept and is otherwise independent.

Executed against spec/CONTRACT_P13S19_PARTIAL.md, four mutations.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QjsEnYhm1gPpf6ii2iFxFV
2026-07-31 18:13:44 -04:00
..
prepass Schema major 2 Phase B: snapshot side + honest stamps (data-model fills) 2026-07-07 16:30:07 -04:00
accidental.rs Push 4b tranche 3b-ii: one SmuflVersion, and a live ordering bug dies with the homonym 2026-07-23 19:30:52 -04:00
codec.rs G3b packet 1: CreateMeasure reaches the wire, the mint, and the grid oracle 2026-07-30 12:19:32 -04:00
event.rs Land M1 + M2 (Agent C): framework edge fixes and real-Score graph integration 2026-06-21 16:37:51 -04:00
fuzz.rs Push 4b tranche 3b-i: the score wire opens schema major 3 2026-07-23 17:35:55 -04:00
generators.rs G3b packet 2: graph invariant 20, and the operations that must preserve it 2026-07-30 15:13:07 -04:00
graph.rs P13-S19: what a partial measure actually costs 2026-07-31 18:13:44 -04:00
ids.rs Text Projection: every graph id projects, because graph_id! says so 2026-07-21 13:41:40 -04:00
indexes.rs Schema major 2 Phase D: the repeat-authoring pair (code tranche) 2026-07-07 20:06:18 -04:00
invariants.rs P13-S19: what a partial measure actually costs 2026-07-31 18:13:44 -04:00
lib.rs G3b packet 2: graph invariant 20, and the operations that must preserve it 2026-07-30 15:13:07 -04:00
pitch.rs Push 4b: ji-adaptive-5limit resolves, and the blocker was never HarmonicContext 2026-07-24 10:17:46 -04:00
pitch_space.rs Push 4b tranche 1: pitch spaces become structure, and cmn-24 transposes end-to-end 2026-07-23 09:41:18 -04:00
prepass.rs A transposition moves the authored spelling; recording Propagated is not enough 2026-07-09 16:40:06 -04:00
tempo.rs Push 4: Binary Format companion, F1 benches, subquadratic reduction order 2026-07-02 19:02:07 -04:00
textvalue.rs Text Projection: the Chapter-5 value layer, from one field list 2026-07-21 12:17:49 -04:00
textvalue_event.rs Text Projection: the Chapter-5 value layer, from one field list 2026-07-21 12:17:49 -04:00
textvalue_graph.rs Genesis G2b: SetTuningContext, and the accept-set raise it pays for 2026-07-29 09:30:32 -04:00
textvalue_impls.rs Text Projection: every graph id projects, because graph_id! says so 2026-07-21 13:41:40 -04:00
textvalue_pitch.rs Text Projection: the Chapter-5 value layer, from one field list 2026-07-21 12:17:49 -04:00
textvalue_time.rs Text Projection: the Chapter-5 value layer, from one field list 2026-07-21 12:17:49 -04:00
time.rs Text Projection: the Chapter-5 value layer, from one field list 2026-07-21 12:17:49 -04:00
tuning.rs Push 4b: ji-adaptive-5limit resolves, and the blocker was never HarmonicContext 2026-07-24 10:17:46 -04:00
vectors.rs The decode vector corpus reaches the core score wire 2026-07-24 11:38:15 -04:00