G3b packet 3a: the seven inbound surfaces a measure undo can strand
Undoing a CreateMeasure removes it from the owning StaffInstance, reached through measure_values' carried parent rather than a search. The strand guard covers seven surface classes, not the two earlier drafts assumed: spanner, repeat, another measure's start, meter change, system break, page break, and tempo segment -- the last at both its start and its optional end anchor. It cannot use the structures index, which is event-only by construction and would make the guard born green; rewriting it that way breaks fifteen tests. RepeatStructure is not a CrossCuttingValue variant, so the modify chain structurally cannot hold one and a repeat_values ledger carries it instead -- seven sites, no delete site. Deleted repeats stay in the map, matching the ratified retention discipline and making the tombstoned-referencer row reachable at all. Owner rules are per surface. Six classes always have one; tempo segments split by key, since a score-level segment has no owning object to test for liveness. The five WriteChain surfaces are restoration-aware in both directions, and the shared path now normalizes a value that does not reference the target to absent. That is behaviour-preserving -- the guard only ever asks whether a value names this target -- and it is what lets the two directions fail independently: spanner chains have no explicit-removal form at all, and a removed break is still Some((anchor, false)). Also closes a hole that predates G3b: a minted TimeSignature still named by a live Measure.time_signature now blocks its own undo. Executed against spec/CONTRACT_GENESIS_G3B_MEASURE.md pin 10, mutations M48-M63. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QjsEnYhm1gPpf6ii2iFxFV
This commit is contained in:
parent
314cd7a80d
commit
acd7a7690f