Schema major 2 Phase D: ratify the repeat-authoring pair (spec tranche)

CreateRepeatStructure / DeleteRepeatStructure enter the ratified
operation set — the dedicated pair for RepeatStructure (repeats live in
the cross-cutting registry but are deliberately NOT CrossCuttingValue
wire kinds; the reconciliation note follows Ch6's CrossCuttingStructure
listing).

operation_catalog (0.6.0 -> 0.7.0):
- New K0 §"Repeat Structures": the full six-part schema for the pair.
  Set-union mint with the ALL-anchors-live precondition (start/end, the
  kind's jump targets, each volta's span — the mint must leave the graph
  satisfying reference-resolution invariants; dead anchor =>
  TargetMissing no-op); live-id re-create reads AlreadyApplied without
  value comparison (cross-cutting discipline; RecreateContentMismatch
  scope unchanged); delete-wins tombstone; create-undo tombstones the
  mint, delete-undo does not restore (P11-C8); volta well-formedness
  stays advisory.
- K1 gains the "Added in the schema-major-2 revision" entry (net-new
  primitives, never drafted as slots).

binary_format (0.5.0 -> 0.6.0):
- OperationKind wire table appends 28 (lp(RepeatStructure)) / 29 (bare
  identifier); OperationKindTag 28/29, name-verbatim projection;
  requirement bounds move past 29.
- Honest per-op stamping ratified: the CREATE is born at v2 (kind/voltas
  are unconditional fields — no lower-major payload layout exists, so
  every block carrying one stamps major 2 under minimal stamping); the
  DELETE's bare-id payload is a major-0 layout, so minimal stamping
  gives its blocks major 0 — the kind discriminant itself being a
  schema-minor vocabulary append (mechanism claim only; the stamp always
  follows minimal stamping, as discriminant 24's always-2 CreateStaff
  shows).
- §Schema Major 2 restructured: RepeatStructure moves from the
  snapshot-only bullet to the canonical operation layer (eight embedding
  payloads now); the CanonicalValue seam grows to twenty-three
  (RepeatStructure joins — CreateRepeatStructure embeds it per
  req:catalog:value-encoding).

core_spec:
- Ch6 OperationKind + Ch8 OperationKindTag listings gain the variants;
  the CrossCuttingStructure/wire-vocabulary reconciliation note; the
  re-anchoring rule table gains the "Repeat structure / Anchor" row
  (re-anchor to the nearest surviving anchor across EVERY
  event-referencing anchor site; cascade-delete only when none
  survives — the spanner discipline); Ch8's schema-versioning paragraph
  now enumerates eight embedding payloads with the born-at-v2/major-0
  split; revision-history row.

Review-hardened: five-dimension workflow review, 22 findings, 9
confirmed + 1 recovered from a failed verifier (an API-error casualty,
assessed by hand) — all fixed (the load-bearing ones: Ch8's stale
seven-payload enumeration; the mis-attributed "Phase-3 precedent" gloss
that would have taught a false stamping rule; the pair filed under
"Snapshot-only"; the CanonicalValue seam omission). All three documents
compile clean, zero undefined references.

Code tranche follows this commit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NEs4aYiu8MXjdYdMxw8PTd
This commit is contained in:
Levi Neuwirth 2026-07-07 17:31:51 -04:00
parent 437e0758a0
commit b816144a43
6 changed files with 202 additions and 20 deletions

Binary file not shown.

View File

@ -235,7 +235,7 @@
{\Large\scshape\color{epiphanyslate}Binary Format}\\[6pt]
{\large\itshape\color{epiphanyslate}A companion to the Core Specification}\\[14pt]
{\color{epiphanygold}\rule{3in}{0.8pt}}\\[24pt]
{\normalsize\color{epiphanyink}Version 0.5.0 --- Schema major 2 (data-model expansion: cross-cutting bodies, repeats/voltas, staff/instrument/metadata fills; total default-fill migration)}\\[4pt]
{\normalsize\color{epiphanyink}Version 0.6.0 --- Repeat authoring (OperationKind/Tag 28/29; the born-at-v2 create, the major-0 delete)}\\[4pt]
{\small\color{epiphanyslate}Normative for the byte layouts it defines}
\vfill
\end{titlepage}
@ -1132,7 +1132,10 @@ The public per-value codec --- the seam between this document and the
Operation Catalog's value-typed payloads (Operation Catalog,
\sectionsc{Value-Typed Payloads}, requirement
\texttt{req:catalog:value-encoding}) --- is defined for exactly these
twenty-two types (the Phase-3 operation tranche added the last four):
twenty-three types (the Phase-3 operation tranche added
\texttt{Staff}/\texttt{TimeSignature}/\texttt{TempoSegment}/%
\texttt{StaffLineConfiguration}; the repeat-authoring revision added
\texttt{RepeatStructure}):
\begin{quote}
\texttt{Event}, \texttt{Rest}, \texttt{Pitch}, \texttt{IdentifiedPitch},
@ -1142,7 +1145,7 @@ twenty-two types (the Phase-3 operation tranche added the last four):
\texttt{DecompositionAttachment}, \texttt{SpellingSourceKind},
\texttt{ScoreMetadata}, \texttt{MetricGrid}, \texttt{Staff},
\texttt{TimeSignature}, \texttt{TempoSegment},
\texttt{StaffLineConfiguration}.
\texttt{StaffLineConfiguration}, \texttt{RepeatStructure}.
\end{quote}
The seam introduces \textbf{no new bytes}: a value's stand-alone canonical
@ -1298,7 +1301,7 @@ AcceptLoser, \tablenums{1} KeepWinner, \tablenums{2} Override
\label{req:binfmt:kind-discriminants}
The \texttt{OperationKind} wire discriminant is one byte, golden-locked to
the table below. The vocabulary is \textbf{append-only}: new primitive kinds
take discriminants past \tablenums{27}; the assignments below never change.
take discriminants past \tablenums{29}; the assignments below never change.
\end{requirement}
Each row also pins the payload's byte layout; the field \emph{set and order}
@ -1415,6 +1418,14 @@ sequence sorted ascending by canonical bytes.
$\mathrm{lp}$(\texttt{StaffLineConfiguration}) if present \cat{}
\texttt{visible} (bool, 1) &
\sectionsc{SetStaffLayout} \\
\tablenums{28} & \texttt{CreateRepeatStructure} &
$\mathrm{lp}$(\texttt{RepeatStructure}) --- the schema-major-2
layout, unconditionally (born at v2;
Section~\ref{sec:evolution:major2}) &
\sectionsc{Repeat Structures} \\
\tablenums{29} & \texttt{DeleteRepeatStructure} &
\texttt{repeat} (16) &
\sectionsc{Repeat Structures} \\
\bottomrule
\end{longtable}
\endgroup
@ -1459,7 +1470,7 @@ assigned independently of Section~\ref{sec:ops:kinds}, with both encode and
validating decode. One byte; only \texttt{Registered} carries a payload (its
\texttt{OperationKindRegistryId}, 16 big-endian bytes, total 17). Unknown
discriminants and wrong lengths are decode errors. Append-only past
\tablenums{27}.
\tablenums{29}.
\end{requirement}
\begingroup\small
@ -1482,6 +1493,7 @@ discriminants and wrong lengths are decode errors. Append-only past
\tablenums{11} & \texttt{InsertStaffInstance} & \tablenums{23} & \texttt{SetMetricGrid} \\
\tablenums{24} & \texttt{InsertStaff} & \tablenums{25} & \texttt{SetTimeSignature} \\
\tablenums{26} & \texttt{SetTempoSegment} & \tablenums{27} & \texttt{SetStaffLayout} \\
\tablenums{28} & \texttt{CreateRepeatStructure} & \tablenums{29} & \texttt{DeleteRepeatStructure} \\
\bottomrule
\end{longtable}
\endgroup
@ -1495,7 +1507,9 @@ discriminants and wrong lengths are decode errors. Append-only past
\texttt{OperationKindTag::\allowbreak InsertStaff}. The mismatch is
intentional
(the tag space predates the M2c naming) and is pinned here so barrier
authors target the right tag.
authors target the right tag. The repeat-structure pair projects
name-verbatim (\texttt{CreateRepeatStructure}/%
\texttt{DeleteRepeatStructure}), as the cross-cutting tags do.
\section{Stamps and Causal Contexts}
\label{sec:ops:stamp}
@ -2292,9 +2306,16 @@ The \emph{only} minor-additive mechanism in schema major~0 is
\textbf{appending discriminants to open vocabularies}:
\begin{itemize}
\item \texttt{OperationKind}: append at ${\geq}\,\tablenums{24}$
(Requirement~\ref{req:binfmt:kind-discriminants});
\item \texttt{OperationKindTag}: append at ${\geq}\,\tablenums{24}$
\item \texttt{OperationKind}: append at ${\geq}\,\tablenums{30}$
(Requirement~\ref{req:binfmt:kind-discriminants}; the Phase-3
tranche took \tablenums{24}--\tablenums{27} under this mechanism,
and the repeat pair \tablenums{28}/\tablenums{29} in the
schema-major-2 revision --- the discriminant space is one append-only
table across majors, but a kind's \emph{block stamp} follows minimal
stamping over its payload: \tablenums{28}'s payload embeds a v2
layout, so its blocks stamp major~2,
Section~\ref{sec:evolution:major2});
\item \texttt{OperationKindTag}: append at ${\geq}\,\tablenums{30}$
(Requirement~\ref{req:binfmt:kind-tag});
\item \texttt{OperationPayload}: append at ${\geq}\,\tablenums{4}$
(Section~\ref{sec:ops:payload});
@ -2523,12 +2544,28 @@ The major is assigned per payload type, exactly as in major~1:
\begin{itemize}
\item \textbf{Snapshot-only:} \texttt{Instrument} (no operation embeds
one) and \texttt{RepeatStructure} (no operation embeds one \emph{at
this revision}; the repeat-authoring operations planned for the same
push are born at v2 and change nothing about lower majors). These
reach only the acceleration full-\texttt{Score} snapshot.
\item \textbf{Canonical operation layer:} seven existing operation
payloads embed filled values ---
one); it reaches only the acceleration full-\texttt{Score} snapshot.
(\texttt{RepeatStructure} was snapshot-only when this section was
first ratified; the repeat-authoring pair moved it to the canonical
operation layer --- next bullet.)
\item \textbf{Canonical operation layer:} eight operation
payloads embed filled values. \texttt{CreateRepeatStructure} (this
revision --- Operation Catalog \sectionsc{Repeat Structures},
discriminant \tablenums{28}) embeds the v2 \texttt{RepeatStructure}
layout unconditionally (\texttt{kind} and \texttt{voltas} are not
optional fields) and is \emph{born at v2}: no lower-major layout for
its payload exists, so every block carrying one stamps major~2 under
minimal stamping. Its sibling \texttt{DeleteRepeatStructure}
(\tablenums{29}) carries a bare identifier --- a major-0 layout ---
so minimal stamping gives its blocks major~0; the kind discriminant
itself is an append-only schema-\emph{minor} vocabulary event (the
same append mechanism the Phase-3 tranche used for
\tablenums{24}--\tablenums{27} --- a mechanism claim only: what a
kind's blocks \emph{stamp} always follows minimal stamping over its
payload, as discriminant \tablenums{24}'s always-major-2
\texttt{CreateStaff} shows). Neither changes anything about
lower-major layouts. The seven payloads of the first ratification
embed filled values ---
\texttt{CreateCrossCutting} and \texttt{ModifyCrossCutting} (a
\texttt{CrossCuttingValue} embedding \texttt{Slur}, \texttt{Tie},
\texttt{Beam}, or \texttt{Spanner}); \texttt{CreateStaff} (a
@ -2567,8 +2604,12 @@ The major is assigned per payload type, exactly as in major~1:
\textbf{1} (the major-1 bool is always present);
\texttt{CreateStaffInstance} / \texttt{SetStaffLayout}
$\Rightarrow$ \textbf{2} iff their \texttt{staff\_lines\_override}
is \texttt{Some}, else \textbf{0}; every other payload keeps its
prior major. A block stamps the maximum over its payloads.
is \texttt{Some}, else \textbf{0};
\texttt{CreateRepeatStructure} $\Rightarrow$ always \textbf{2}
(born at v2); \texttt{DeleteRepeatStructure} $\Rightarrow$
\textbf{0} (a bare identifier under a minor kind append); every
other payload keeps its prior major. A block stamps the maximum
over its payloads.
(Operation names are the Operation Catalog's; core Chapter~6's
enum spells the creates \texttt{InsertStaff} /
\texttt{InsertStaffInstance} / \texttt{InsertRegion}.)
@ -3122,6 +3163,20 @@ layouts of Section~\ref{sec:values:representative}.
implementation phases land). Semantics: core specification schema-major-2 revision
(leaf-type definitions, clef/key content-model ratification,
\texttt{ClefId} retirement, strictly-authored timestamp requirement). \\
\today & Operation vocabularies & 0.6.0 --- Repeat authoring
(schema-major-2 revision, Phase D): appends \texttt{OperationKind}
\tablenums{28} (\texttt{CreateRepeatStructure},
$\mathrm{lp}$(\texttt{RepeatStructure}), born at v2 --- every block
carrying one stamps major~2 under minimal stamping) and \tablenums{29}
(\texttt{DeleteRepeatStructure}, bare identifier --- minimal stamping
over its major-0 payload layout gives major~0; the discriminant itself
a schema-\emph{minor} vocabulary append), with the
matching \texttt{OperationKindTag} \tablenums{28}/\tablenums{29}
(name-verbatim projection). No existing assignment changed;
Section~\ref{sec:evolution:major2} restates the per-payload stamping
with the pair. Semantics: Operation Catalog \sectionsc{Repeat
Structures}, 0.7.0; re-anchoring row (nearest-surviving-anchor across
every anchor site, cascade when none): core Chapter~6 rule table. \\
\bottomrule
\end{longtable}

Binary file not shown.

View File

@ -6159,6 +6159,10 @@ pub enum OperationKind {
DeleteCrossCutting(DeleteCrossCuttingPayload),
ModifyCrossCutting(ModifyCrossCuttingPayload),
// Repeat-structure operations
CreateRepeatStructure(CreateRepeatStructureOp),
DeleteRepeatStructure(DeleteRepeatStructureOp),
// Region and structure operations
ChangeRegionTimeModel(ChangeRegionTimeModelOp),
InsertRegion(InsertRegionOp),
@ -7421,6 +7425,16 @@ table is normative.
as for slurs (surviving-endpoint collapse); per-spanner-kind
proximity bounds are a deferred refinement \\
Repeat structure & Anchor &
Re-anchor to the nearest surviving anchor; cascade-delete only
when no anchor survives &
as for spanners; the rule spans \emph{every} event-referencing
anchor site of the structure --- \texttt{start}/\texttt{end},
the kind's jump targets (\texttt{DaCapo.end\_target},
\texttt{DalSegno.segno}/\texttt{end\_target}), and each
volta's span (ratified with the repeat-authoring pair,
schema-major-2 revision) \\
Marker & Anchor &
Re-anchor to nearest event in same staff instance &
proximity max: same staff instance; orphan on failure \\
@ -7962,6 +7976,17 @@ pub enum CrossCuttingStructure {
}
\end{lstlisting}
The enum above is the data model's full cross-cutting family; the
\emph{wire} vocabulary the cross-cutting operations admit at this
revision (\texttt{CrossCuttingValue}, Binary Format companion) is the
four-kind subset \texttt{Tie}/\texttt{Slur}/\texttt{Beam}/%
\texttt{Spanner}. A \texttt{RepeatStructure} is authored by the
dedicated \texttt{CreateRepeatStructure}/%
\texttt{DeleteRepeatStructure} pair (Operation Catalog
\sectionsc{Repeat Structures}; ratified schema-major-2 revision), not
through \texttt{CreateCrossCutting}; the remaining variants await
their own authoring primitives.
\textbf{Invariant preconditions} (Slur case):
\begin{itemize}
\item The slur's id is unique within the cross-cutting registry.
@ -10810,6 +10835,10 @@ pub enum OperationKindTag {
SetTimeSignature,
SetTempoSegment,
SetStaffLayout,
// Schema-major-2 revision (repeat authoring). The pair keeps
// its kind names verbatim, as the cross-cutting tags do.
CreateRepeatStructure,
DeleteRepeatStructure,
}
pub enum BarrierScope {
@ -11085,11 +11114,16 @@ truncated bodies of the cross-cutting structures (\texttt{Slur},
Chapter~5 definitions. The same per-payload-type rules apply: the
canonical-base \texttt{MaterializedState} embeds none of these values and
stays major~0; the filled values reach the acceleration snapshot
\emph{and}, through the seven operation payloads that embed them
\emph{and}, through the eight operation payloads that embed them
(\texttt{CreateCrossCutting}, \texttt{ModifyCrossCutting},
\texttt{InsertStaff} and \texttt{InsertStaffInstance} (the Operation
Catalog's \texttt{CreateStaff} / \texttt{CreateStaffInstance}),
\texttt{SetStaffLayout}, \texttt{SetMetadata}, and --- transitively,
\texttt{SetStaffLayout}, \texttt{SetMetadata},
\texttt{CreateRepeatStructure} (the repeat-authoring revision --- it
embeds the filled \texttt{RepeatStructure} unconditionally, so it is
\emph{born at v2} and every block carrying one stamps major~2; its
\texttt{DeleteRepeatStructure} sibling carries a bare identifier, a
major-0 layout, and stamps major~0), and --- transitively,
because an embedded \texttt{Region} may carry a \texttt{StaffInstance}
whose \texttt{staff\_lines\_override} embeds the filled
\texttt{StaffLineConfiguration} --- \texttt{InsertRegion}
@ -15339,6 +15373,22 @@ layouts they own versus inherit:
total default-filling migration: Binary Format companion
0.4.0~$\rightarrow$~0.5.0.
\\
\today & Schema major 2 (repeat authoring, Phase D) &
The dedicated \texttt{CreateRepeatStructure}/%
\texttt{DeleteRepeatStructure} pair enters the operation set:
Chapter~6's \texttt{OperationKind} enum and Chapter~8's
\texttt{OperationKindTag} listing gain the two variants (repeats are not
\texttt{CrossCuttingValue} kinds on the wire --- the reconciliation
note follows the \texttt{CrossCuttingStructure} listing), and the
re-anchoring rule table gains the Repeat-structure~/ Anchor row
(re-anchor to the nearest surviving anchor across \emph{every}
event-referencing anchor site --- \texttt{start}/\texttt{end}, jump
targets, volta spans --- cascade-delete only when none survives).
Six-part schemas: Operation Catalog \sectionsc{Repeat Structures},
0.6.0~$\rightarrow$~0.7.0. Wire discriminants 28/29 and the
per-payload stamping (create born at v2; delete a minor kind append
at major~0): Binary Format companion 0.5.0~$\rightarrow$~0.6.0.
\\
\bottomrule
\end{longtable}

Binary file not shown.

View File

@ -226,7 +226,7 @@
{\Large\scshape\color{epiphanyslate}Operation Catalog}\\[6pt]
{\large\itshape\color{epiphanyslate}A companion to the Core Specification}\\[14pt]
{\color{epiphanygold}\rule{3in}{0.8pt}}\\[24pt]
{\normalsize\color{epiphanyink}Version 0.6.0 --- Pass-12 G-ratification (meta-operation edge semantics, system-derived immutability, recreate vocabulary, slot retirement)}\\[4pt]
{\normalsize\color{epiphanyink}Version 0.7.0 --- Schema-major-2 repeat authoring (the CreateRepeatStructure / DeleteRepeatStructure pair)}\\[4pt]
{\small\color{epiphanyslate}Normative for the operation kinds it defines}
\vfill
\end{titlepage}
@ -842,6 +842,73 @@ anchor; there is no \texttt{DeleteStaff} in this catalogue revision --- an
empty-only staff delete mirroring the container discipline is a later
schema-fill).
\section{Repeat Structures}
\label{sec:k0:repeat-structures}
Ratified with the schema-major-2 revision: the dedicated authoring pair for
\texttt{RepeatStructure} (core specification Chapter~5
\sectionsc{Repeat Structures}). Repeats live in the cross-cutting registry
but are \emph{not} \texttt{CrossCuttingValue} kinds on the wire --- the
cross-cutting operations admit only
\texttt{Tie}/\texttt{Slur}/\texttt{Beam}/\texttt{Spanner}
(Section~\ref{sec:k0:create-cross-cutting}) --- so the pair is a
first-class primitive mirroring the cross-cutting disciplines.
\textbf{Payload schema.} \texttt{CreateRepeatStructureOp \{ repeat:
RepeatStructure \}} --- the full value (schema major 2): identity, the
\texttt{start}/\texttt{end} anchors, the \texttt{RepeatKind}, and the
volta list. \texttt{DeleteRepeatStructureOp \{ repeat: RepeatStructureId
\}}.
\textbf{Canonical encoding.} Create: the length-framed canonical bytes of
\texttt{repeat} (the schema-major-2 layout). Delete: the bare identifier.
The create's payload embeds the v2 \texttt{RepeatStructure} layout
unconditionally (\texttt{kind} and \texttt{voltas} are not optional
fields), so under minimal stamping a block carrying one stamps schema
major~2 --- the create is \emph{born at v2}. The delete's payload is an
identifier --- a major-0 layout --- so minimal stamping gives its blocks
major~0; the kind discriminant itself is an append-only schema-\emph{minor}
vocabulary event (the same append mechanism as the Phase-3 tranche; the
stamp itself always follows minimal stamping over the payload, per the
Binary Format companion \sectionsc{Schema Major 2}).
\textbf{Reduction rule.} Set-union creation and a delete-wins tombstone,
mirroring the cross-cutting family. A create mints the repeat live if its
id is fresh and \emph{every} event-referencing anchor site resolves to a
live event --- \texttt{start}/\texttt{end}, the kind's jump targets
(\texttt{DaCapo.end\_target},
\texttt{DalSegno.segno}/\texttt{end\_target}), and each volta's
\texttt{start}/\texttt{end} --- since the mint must leave the graph
satisfying the reference-resolution invariants; a dead anchor is a
precondition no-op (\texttt{TargetMissing}). A repeat create of a live id
reads \texttt{AlreadyApplied} without value comparison (the cross-cutting
discipline; the \texttt{RecreateContentMismatch} scope of
Section~\ref{sec:k0:create-staff} is unchanged). A delete tombstones the
repeat (idempotent on re-delete, delete-wins); deleting a missing id is a
no-op precondition failure. Graph-aware reduction adds or removes the
structure from the cross-cutting registry.
\textbf{Conflict cases.} None at reduction time (set-union creation;
delete-wins is idempotent).
\textbf{Undo semantics.} Undo of a create tombstones the minted repeat
(Section~\ref{sec:k0:undo}). A delete mints nothing, so the prototype's
minted-object undo does not re-introduce the tombstoned structure
(P11-C8).
\textbf{Re-anchoring.} The structure participates in the re-anchoring rule
table when a referenced event is later tombstoned: re-anchor to the
nearest surviving anchor, cascade-delete only when none survives --- as
for spanners, spanning \emph{every} anchor site
(\texttt{start}/\texttt{end}, jump targets, volta spans). The rule row is
the core specification's (Chapter~6 re-anchoring rule table, ratified with
this pair).
\textbf{Authoring advisory.} The volta well-formedness constraints of
core Chapter~5 (endings non-empty, 1-based, ascending) are
\emph{advisory}: surfaced at authoring time under interactive validation,
never enforced under reduction.
\section{SetUserSystemBreak}
\label{sec:k0:set-user-system-break}
@ -1246,6 +1313,16 @@ a fresh design.
creation, LWW structural overwrite, and LWW advisory respectively.
\end{description}
\section*{Added in the schema-major-2 revision (Chapter~\ref{ch:k0})}
\begin{description}
\item[Create / delete repeat structure]
Section~\ref{sec:k0:repeat-structures} --- net-new primitives (never
drafted as framework slots). Set-union creation with the
all-anchors-live precondition and a delete-wins tombstone; the create
is born at v2, the delete stamps major~0.
\end{description}
\section*{Retired slots (ratified Pass~12: outside the operation set)}
\begin{description}