Schema major 2 Phase A: ratify the v2 data-model wire form (spec only)
Push 2's spec-first phase. core_spec (schema-major-2 revision): defines
the nineteen leaf types Ch5's ratified shapes referenced but never
pinned (SlurKind, CurveDirection, CurvatureOverride, the shared
SpanStyle record consolidating the identical SlurStyle/TieStyle/
SpannerStyle triplet, SubBeam, BeamGeometryOverride, SpannerKind's five
payload types + a leading Generic migration default, Volta,
MetadataValue, Timestamp, SoundConfiguration, TranspositionInterval
(structural, advisory until Ch4 per the P12-K2 discipline),
UnpitchedMember + member-resolution semantics (first-match, no-match
tolerated; StaffPosition vertical convention explicitly deferred),
SpaceUnit, LineStyle, StaffBracketKind); ratifies the visible-slice
clef/key content model into Ch5 (Clef/ClefShape/KeySignature/
ClefChange/KeySignatureChange) and retires the ClefId sketch;
strictly-authored metadata timestamps (req:graph:metadata-timestamps);
metadata `additional` = ordered list, duplicates permitted; Ch8 gains
the major-2 paragraph; Ch6 OperationKind listing gains its seven
missing variants (staleness fix).
binary_format 0.4.0 -> 0.5.0: new "Schema Major 2" section — per-
payload-type major assignment (snapshot-only Instrument/
RepeatStructure; SEVEN canonical embedding payloads incl. CreateRegion
transitively and SetStaffLayout's direct staff_lines_override field);
the MINIMAL-STAMPING rule (a block stamps the lowest major whose
layouts decode its bytes — deterministic, per-payload table given;
extends the major-1 no-restamp principle); append-after-prior-major
wire layouts with field-order divergences called out; new leaf layouts
with framing pinned (SubBeam EventIds = framed leaves; UnpitchedMember
fields = bare primitives; SpaceUnit = framed 12); total default-fill
v1->v2 migration table (complete StaffLineConfiguration defaults at
all four embed sites; RepeatKind default SimpleRepeat{count:2});
accept-set {0,1,2} with per-role staging note; CanonicalValue seam
list corrected 18 -> 22 (staleness fix).
Two review rounds (8 + 9 findings, all fixed pre-commit — the
stamping-rule determinism contradiction, the CreateRegion transitive
embedding, SubBeam leaf framing, and the SetStaffLayout direct-field
site being the load-bearing ones). Both PDFs build clean, zero
undefined references. No code changes; Phase B (snapshot side) next.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NEs4aYiu8MXjdYdMxw8PTd
This commit is contained in:
parent
93f3dfde93
commit
7c9d1c40aa
Binary file not shown.
|
|
@ -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.4.0 --- Pass-12 G-ratification (appended effect-vocabulary discriminants; unsafe-edit tombstone encoding open question)}\\[4pt]
|
||||
{\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]
|
||||
{\small\color{epiphanyslate}Normative for the byte layouts it defines}
|
||||
\vfill
|
||||
\end{titlepage}
|
||||
|
|
@ -1132,7 +1132,7 @@ 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
|
||||
eighteen types:
|
||||
twenty-two types (the Phase-3 operation tranche added the last four):
|
||||
|
||||
\begin{quote}
|
||||
\texttt{Event}, \texttt{Rest}, \texttt{Pitch}, \texttt{IdentifiedPitch},
|
||||
|
|
@ -1140,7 +1140,9 @@ eighteen types:
|
|||
\texttt{Spanner}, \texttt{RegionTimeModel}, \texttt{TimeAnchor},
|
||||
\texttt{Region}, \texttt{StaffInstance}, \texttt{Voice},
|
||||
\texttt{DecompositionAttachment}, \texttt{SpellingSourceKind},
|
||||
\texttt{ScoreMetadata}, \texttt{MetricGrid}.
|
||||
\texttt{ScoreMetadata}, \texttt{MetricGrid}, \texttt{Staff},
|
||||
\texttt{TimeSignature}, \texttt{TempoSegment},
|
||||
\texttt{StaffLineConfiguration}.
|
||||
\end{quote}
|
||||
|
||||
The seam introduces \textbf{no new bytes}: a value's stand-alone canonical
|
||||
|
|
@ -2237,7 +2239,9 @@ governed by the Binary Format companion specification, which defines the
|
|||
wire encoding for each schema version''}). This chapter defines the wire
|
||||
rules for schema evolution. Chapters~\ref{ch:values}--\ref{ch:barriers}
|
||||
specify the schema-major-0 layouts; Section~\ref{sec:evolution:major1}
|
||||
specifies the schema-major-1 delta and the migration between them.
|
||||
specifies the schema-major-1 delta and the migration between them, and
|
||||
Section~\ref{sec:evolution:major2} the schema-major-2 delta and its
|
||||
migration from major~1.
|
||||
|
||||
\section{The Chunk-Level Gate}
|
||||
\label{sec:evolution:gate}
|
||||
|
|
@ -2251,9 +2255,11 @@ Every chunk declares a \texttt{SchemaVersion} (major, minor) in its
|
|||
$[\textsc{min}, \textsc{max}]$ of majors and rejects any chunk whose major
|
||||
falls \emph{outside} $[\textsc{min}, \textsc{max}]$ --- too new (above
|
||||
\textsc{max}) or, once \textsc{min} rises past a retired major, too old
|
||||
(Section~\ref{sec:evolution:major1}). Two majors are defined:
|
||||
\tablenums{0} and \tablenums{1}; the reference implementation's accept-set
|
||||
is $\{0, 1\}$ ($\textsc{min} = 0$, $\textsc{max} = 1$).
|
||||
(Section~\ref{sec:evolution:major1}). Three majors are defined:
|
||||
\tablenums{0}, \tablenums{1} (Section~\ref{sec:evolution:major1}), and
|
||||
\tablenums{2} (Section~\ref{sec:evolution:major2}); the reference
|
||||
implementation's accept-set is $\{0, 1, 2\}$ ($\textsc{min} = 0$,
|
||||
$\textsc{max} = 2$).
|
||||
\item \textbf{Minor} = additive. v0 readers verify the major only; the
|
||||
minor is a \emph{record}, not a gate --- but it is a mandatory record:
|
||||
a writer \MUST{} raise the chunk schema minor when it emits any
|
||||
|
|
@ -2402,9 +2408,10 @@ discards the higher-major non-canonical caches.
|
|||
|
||||
\subsection{The accept-set gate}
|
||||
A reader supports a contiguous set of majors $[\textsc{min}, \textsc{max}]$
|
||||
(the reference implementation: $\{0, 1\}$, i.e. $\textsc{min} = 0$,
|
||||
$\textsc{max} = 1$). The chunk-level gate
|
||||
(Section~\ref{sec:evolution:gate}) rejects a chunk whose major falls outside
|
||||
(at the major-1 revision the reference implementation's set was $\{0, 1\}$;
|
||||
the \emph{current} set is stated once, in
|
||||
Section~\ref{sec:evolution:gate}, and is not repeated here). The
|
||||
chunk-level gate rejects a chunk whose major falls outside
|
||||
$[\textsc{min}, \textsc{max}]$ --- too new above \textsc{max}, or too old
|
||||
below \textsc{min} once a reader drops support for a retired major; it no
|
||||
longer rejects on inequality with a single supported major.
|
||||
|
|
@ -2499,6 +2506,295 @@ A reader migrates a major-0 acceleration \texttt{Score} snapshot on read
|
|||
(cheaper than replaying the operation log); a writer emits only major-1 forms
|
||||
for the changed payloads and leaves the canonical base at major~0.
|
||||
|
||||
\section{Schema Major 2}
|
||||
\label{sec:evolution:major2}
|
||||
|
||||
Schema major~2 is the second data-model expansion major: it fills the
|
||||
truncated bodies the v0 baseline deliberately staged to this companion ---
|
||||
the cross-cutting structures (\texttt{Slur}, \texttt{Tie}, \texttt{Beam},
|
||||
\texttt{Spanner}), \texttt{RepeatStructure}, \texttt{Staff} and
|
||||
\texttt{StaffLineConfiguration}, \texttt{Instrument}, and
|
||||
\texttt{ScoreMetadata} --- to the shapes the core specification's Chapter~5
|
||||
ratifies (schema-major-2 revision). The leaf types those shapes reference
|
||||
are defined in the same core revision; their wire layouts are below.
|
||||
|
||||
\subsection{Where the changed fields reach}
|
||||
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 ---
|
||||
\texttt{CreateCrossCutting} and \texttt{ModifyCrossCutting} (a
|
||||
\texttt{CrossCuttingValue} embedding \texttt{Slur}, \texttt{Tie},
|
||||
\texttt{Beam}, or \texttt{Spanner}); \texttt{CreateStaff} (a
|
||||
\texttt{Staff}, which also embeds the filled
|
||||
\texttt{StaffLineConfiguration}); \texttt{CreateStaffInstance} (a
|
||||
\texttt{StaffInstance}, whose \texttt{staff\_lines\_override} embeds
|
||||
it); \texttt{SetStaffLayout} (whose \emph{own}
|
||||
\texttt{staff\_lines\_override} field --- an op-payload field, not
|
||||
part of a \texttt{StaffInstance} --- embeds it); \texttt{SetMetadata}
|
||||
(a \texttt{ScoreMetadata}); and \texttt{CreateRegion}
|
||||
\emph{transitively} --- its embedded \texttt{Region} may carry
|
||||
\texttt{StaffInstance}s (\texttt{content.staff\_instances}), each
|
||||
embedding the filled \texttt{StaffLineConfiguration}. (Reduction
|
||||
preconditions a \emph{carried} region to be empty of typed children,
|
||||
but the byte form is representable and preserved in the canonical
|
||||
set, so the wire must define it.)
|
||||
|
||||
\textbf{Minimal stamping.} A writer \MUST{} stamp each
|
||||
operation-envelope block with the \emph{lowest} schema major whose
|
||||
layouts decode the block's bytes to the encoded values. The stamp
|
||||
is therefore a pure function of the block's values --- two
|
||||
conforming writers stamp identical content identically, which the
|
||||
content hash requires (the schema version is in the chunk-hash
|
||||
preimage). This is the same principle the major-1 section applies
|
||||
to the canonical base: byte-identical content \MUSTNOT{} be
|
||||
re-stamped at a higher major. A payload whose higher-major encoding
|
||||
coincides byte-for-byte with its lower-major form takes the lower
|
||||
major; a hidden embedding site (an \texttt{Option} that is
|
||||
\texttt{None}, an empty \texttt{Vec}) contributes nothing.
|
||||
Concretely, the per-payload minimal majors at this revision:
|
||||
\texttt{CreateCrossCutting} / \texttt{ModifyCrossCutting} /
|
||||
\texttt{CreateStaff} / \texttt{SetMetadata} $\Rightarrow$ always
|
||||
\textbf{2} (their v2 fills are mandatory appended fields);
|
||||
\texttt{CreateRegion} $\Rightarrow$ \textbf{2} iff a carried staff
|
||||
instance's \texttt{staff\_lines\_override} is \texttt{Some}, else
|
||||
\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.
|
||||
(Operation names are the Operation Catalog's; core Chapter~6's
|
||||
enum spells the creates \texttt{InsertStaff} /
|
||||
\texttt{InsertStaffInstance} / \texttt{InsertRegion}.)
|
||||
\item \textbf{The canonical base is unchanged.} The
|
||||
\texttt{MaterializedState} embeds none of the filled types (its
|
||||
values are effects, conflicts, anomalies, object states, pitch
|
||||
spellings, break keys, and pending records), so it remains major~0,
|
||||
byte-identical across the bump --- the same keystone as major~1, and
|
||||
a conformance test \SHOULD{} assert it again.
|
||||
\item The manifest stays major~0 (nothing here touches it).
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Cross-major reader behaviour}
|
||||
The major-1 rules extend unchanged: non-canonical chunks at a foreign
|
||||
major are discarded and regenerated (or migrated on read, for the
|
||||
acceleration snapshot); canonical chunks parse or the bundle opens
|
||||
read-only. Migration \emph{composes}: a major-2 reader migrates a major-0
|
||||
snapshot v0${\to}$v1${\to}$v2 in one read, each step total and
|
||||
default-filling. A major-1-only reader opens a bundle read-only iff it
|
||||
carries an op block bearing a v2 value; a major-0-only reader
|
||||
additionally on v1 \texttt{CreateRegion} blocks, as before.
|
||||
|
||||
\emph{Staging note.} As with major~1, the reference implementation
|
||||
raises chunk admission \emph{per role} as the implementation phases of
|
||||
this revision's push land (snapshot decode, then the canonical
|
||||
operation layer); the accept-set stated in
|
||||
Section~\ref{sec:evolution:gate} is the ratified end-state, not a claim
|
||||
that every intermediate commit already admits it.
|
||||
|
||||
\subsection{Changed value layouts}
|
||||
As in major~1, \textbf{the wire form ratifies the code, not the model's
|
||||
presentational field order}: a struct's v2 layout appends its new fields
|
||||
\emph{after its existing major-0/major-1 fields}, even where Chapter~5's
|
||||
listing interleaves them. Concretely (every leaf under
|
||||
Chapter~\ref{ch:values} regime~(a) rules: LE integers, one discriminant
|
||||
byte per union, \texttt{u32} counts and length prefixes, one presence
|
||||
byte per \texttt{Option}, one bare byte per bool):
|
||||
|
||||
\begin{itemize}
|
||||
\item \texttt{Slur} $=$ \texttt{id} \cat{} \texttt{start\_event} \cat{}
|
||||
\texttt{end\_event} \cat{} \textbf{\texttt{kind}} \cat{}
|
||||
\textbf{\texttt{curvature\_override}} \cat{} \textbf{\texttt{style}}.
|
||||
\item \texttt{Tie} $=$ (major-0 fields) \cat{} \textbf{\texttt{style}}.
|
||||
\item \texttt{Beam} $=$ \texttt{id} \cat{} \texttt{events} \cat{}
|
||||
\texttt{level} \cat{} \textbf{\texttt{sub\_beams}} \cat{}
|
||||
\textbf{\texttt{geometry\_override}}.
|
||||
\item \texttt{Spanner} $=$ \texttt{id} \cat{} \texttt{start} \cat{}
|
||||
\texttt{end} \cat{} \texttt{staves} \cat{} \textbf{\texttt{kind}}
|
||||
\cat{} \textbf{\texttt{style}} (the kind appends \emph{after}
|
||||
\texttt{staves}; Chapter~5 lists it second, presentationally).
|
||||
\item \texttt{RepeatStructure} $=$ \texttt{id} \cat{} \texttt{start}
|
||||
\cat{} \texttt{end} \cat{} \textbf{\texttt{kind}} \cat{}
|
||||
\textbf{\texttt{voltas}}.
|
||||
\item \texttt{Staff} $=$ \texttt{id} \cat{} \texttt{name} \cat{}
|
||||
\texttt{abbreviation} \cat{} \texttt{instrument} \cat{}
|
||||
\texttt{default\_staff\_lines} \cat{} \texttt{group} \cat{}
|
||||
\textbf{\texttt{default\_clef}} (appended last; Chapter~5 lists it
|
||||
mid-struct).
|
||||
\item \texttt{StaffLineConfiguration} $=$ \texttt{line\_count} \cat{}
|
||||
\textbf{\texttt{line\_spacing}} \cat{} \textbf{\texttt{line\_style}}
|
||||
\cat{} \textbf{\texttt{bracket}}. This value is embedded by
|
||||
\texttt{Staff} \emph{and} by
|
||||
\texttt{StaffInstance.staff\_lines\_override}, which is how
|
||||
\texttt{CreateStaffInstance}, \texttt{SetStaffLayout}, and
|
||||
(transitively, through a carried region's staff instances)
|
||||
\texttt{CreateRegion} become v2 payloads without gaining fields of
|
||||
their own (the \texttt{CreateRegion}-in-major-1 pattern).
|
||||
\item \texttt{Instrument} $=$ \texttt{id} \cat{} \texttt{name} \cat{}
|
||||
\texttt{range} \cat{} \textbf{\texttt{abbreviation}} \cat{}
|
||||
\textbf{\texttt{sound\_config}} \cat{}
|
||||
\textbf{\texttt{transposition}} \cat{}
|
||||
\textbf{\texttt{default\_clef}} \cat{}
|
||||
\textbf{\texttt{default\_staff\_lines}} \cat{}
|
||||
\textbf{\texttt{unpitched\_members}} (appended after the major-1
|
||||
order \texttt{id}/\texttt{name}/\texttt{range}; Chapter~5's listing
|
||||
order is presentational).
|
||||
\item \texttt{ScoreMetadata} $=$ \texttt{title} \cat{}
|
||||
\texttt{composer} \cat{} \texttt{copyright} \cat{}
|
||||
\textbf{\texttt{subtitle}} \cat{} \textbf{\texttt{lyricist}} \cat{}
|
||||
\textbf{\texttt{arranger}} \cat{}
|
||||
\textbf{\texttt{creation\_timestamp}} \cat{}
|
||||
\textbf{\texttt{modification\_timestamp}} \cat{}
|
||||
\textbf{\texttt{additional}} (appended after the major-0 order).
|
||||
\end{itemize}
|
||||
|
||||
\subsection{New leaf-type layouts}
|
||||
\begin{itemize}
|
||||
\item \texttt{SlurKind}: one byte --- \tablenums{0} Legato,
|
||||
\tablenums{1} Phrase, \tablenums{2} Articulation,
|
||||
\tablenums{3} Editorial.
|
||||
\item \texttt{CurveDirection}: one byte --- \tablenums{0} Above,
|
||||
\tablenums{1} Below.
|
||||
\item \texttt{CurvatureOverride} $=$ \texttt{direction}
|
||||
(\texttt{Option<CurveDirection>}) \cat{} \texttt{height}
|
||||
(\texttt{Option<SpaceUnit>}).
|
||||
\item \texttt{LineStyle}: one byte --- \tablenums{0} Solid,
|
||||
\tablenums{1} Dashed, \tablenums{2} Dotted.
|
||||
\item \texttt{SpanStyle} (one shared record: \texttt{Slur.style},
|
||||
\texttt{Tie.style}, \texttt{Spanner.style}) $=$ \texttt{line}
|
||||
(\texttt{LineStyle}) \cat{} \texttt{thickness}
|
||||
(\texttt{Option<SpaceUnit>}).
|
||||
\item \texttt{SubBeam} $=$ \texttt{level} (one byte) \cat{}
|
||||
\texttt{events} (\texttt{u32} count \cat{} \texttt{EventId}
|
||||
\emph{leaves}, each \texttt{u32}-length-framed 16 canonical bytes
|
||||
$= 20$ bytes --- this chapter's leaf framing, exactly as
|
||||
\texttt{Beam.events} encodes today).
|
||||
\item \texttt{BeamGeometryOverride} $=$ \texttt{slope}
|
||||
(\texttt{Option<CanonicalF64>}; dimensionless) \cat{}
|
||||
\texttt{offset} (\texttt{Option<SpaceUnit>}).
|
||||
\item \texttt{SpannerKind}: discriminant byte \cat{} payload ---
|
||||
\tablenums{0} Generic; \tablenums{1} Hairpin \cat{}
|
||||
\texttt{HairpinDirection} (one byte: \tablenums{0} Crescendo,
|
||||
\tablenums{1} Diminuendo); \tablenums{2} OctaveLine \cat{}
|
||||
\texttt{OctaveOffset} (one \texttt{i8}); \tablenums{3} PedalLine
|
||||
\cat{} \texttt{PedalKind} (one byte: \tablenums{0} Sustain,
|
||||
\tablenums{1} Sostenuto, \tablenums{2} UnaCorda);
|
||||
\tablenums{4} TrillExtension; \tablenums{5} Glissando;
|
||||
\tablenums{6} Portamento; \tablenums{7} TextLine \cat{}
|
||||
\texttt{TextLineDefinition} ($=$ one length-prefixed raw-UTF-8
|
||||
string); \tablenums{8} Bracket \cat{} \texttt{BracketKind} (one
|
||||
byte: \tablenums{0} Square).
|
||||
\item \texttt{RepeatKind}: discriminant byte \cat{} payload ---
|
||||
\tablenums{0} SimpleRepeat \cat{} \texttt{count} (\texttt{u32} LE);
|
||||
\tablenums{1} DaCapo \cat{} \texttt{end\_target}
|
||||
(\texttt{TimeAnchor}); \tablenums{2} DalSegno \cat{} \texttt{segno}
|
||||
\cat{} \texttt{end\_target}; \tablenums{3} Volta.
|
||||
\item \texttt{Volta} $=$ \texttt{endings} (\texttt{u32} count \cat{}
|
||||
bare \texttt{u32} LE values --- fixed-width primitives are
|
||||
unframed) \cat{} \texttt{start} \cat{} \texttt{end}
|
||||
(\texttt{TimeAnchor}s).
|
||||
\item \texttt{SpaceUnit} $=$ one \texttt{CanonicalF64}, leaf-framed
|
||||
($12$ bytes) --- byte-identical to how \texttt{CanonicalF64} itself
|
||||
encodes; the newtype adds no bytes.
|
||||
\item \texttt{StaffBracketKind}: one byte --- \tablenums{0} Brace,
|
||||
\tablenums{1} Bracket.
|
||||
\item \texttt{SoundConfiguration} $=$ \texttt{u32} length \cat{} raw
|
||||
bytes (opaque; never interpreted by the core).
|
||||
\item \texttt{TranspositionInterval} $=$ \texttt{diatonic\_steps}
|
||||
(\texttt{i32} LE) \cat{} \texttt{chromatic\_steps} (\texttt{i32} LE).
|
||||
\item \texttt{UnpitchedMember} $=$ \texttt{member} (bare \texttt{u32}
|
||||
LE --- \texttt{UnpitchedMemberId} is an instrument-scoped small
|
||||
value, \emph{not} a 128-bit object identifier, so the
|
||||
identifier-leaf framing does not apply; this matches how
|
||||
\texttt{UnpitchedEvent.instrument\_member} has encoded since
|
||||
major~0) \cat{} \texttt{name} (string) \cat{}
|
||||
\texttt{staff\_position} (bare \texttt{i16} LE, likewise).
|
||||
\item \texttt{Timestamp} $=$ one \texttt{i64} LE (nanoseconds since
|
||||
the Unix epoch, UTC).
|
||||
\item \texttt{MetadataEntry} $=$ \texttt{key} (string) \cat{}
|
||||
\texttt{value}; \texttt{MetadataValue}: discriminant byte \cat{}
|
||||
payload --- \tablenums{0} Text \cat{} string; \tablenums{1} Integer
|
||||
\cat{} \texttt{i64} LE; \tablenums{2} Flag \cat{} bool.
|
||||
\item \texttt{Clef}, \texttt{ClefShape}, \texttt{KeySignature},
|
||||
\texttt{ClefChange}, \texttt{KeySignatureChange} are \emph{not new
|
||||
wire forms}: they have carried major-0 layouts since the
|
||||
visible-slice revision (empty sequences left \texttt{Score} bytes
|
||||
unchanged). Major~2 only \emph{embeds} \texttt{Clef} in two more
|
||||
places (\texttt{Staff.default\_clef},
|
||||
\texttt{Instrument.default\_clef}). Its layout, for the record:
|
||||
\texttt{shape} (one byte: \tablenums{0} G, \tablenums{1} F,
|
||||
\tablenums{2} C, \tablenums{3} Percussion) \cat{} \texttt{line}
|
||||
(\texttt{i8}) \cat{} \texttt{octave\_shift} (\texttt{i8});
|
||||
\texttt{KeySignature} $=$ \texttt{fifths} (\texttt{i8}; decoders
|
||||
\MUST{} reject $|\texttt{fifths}| > 7$).
|
||||
\end{itemize}
|
||||
|
||||
As in major~1: every embedded \emph{leaf} keeps this chapter's framing
|
||||
(an identifier is a \texttt{u32} LE length \cat{} its 16 canonical
|
||||
bytes $= 20$; a \texttt{CanonicalF64} is a \texttt{u32} LE length
|
||||
\cat{} 8 bytes $= 12$); fixed-width primitive integers and bools inside
|
||||
structs are bare; every \texttt{Option} is one presence byte then the
|
||||
payload when present.
|
||||
|
||||
\subsection{Migration from major 1}
|
||||
Total and default-filling, needing no score context; composes after the
|
||||
major-1 migration for major-0 input. The defaults reproduce today's
|
||||
rendering exactly: a migrated document draws byte-identically.
|
||||
|
||||
\begin{center}
|
||||
\begin{tabular}{p{1.9in} p{3.4in}}
|
||||
\toprule
|
||||
\textbf{major-1 form} & \textbf{major-2 form} \\
|
||||
\midrule
|
||||
\texttt{Slur} & append \texttt{kind} $=$ Legato,
|
||||
\texttt{curvature\_override} $=$ \texttt{None}, \texttt{style} $=$
|
||||
(Solid, \texttt{None}) \\
|
||||
\texttt{Tie} & append \texttt{style} $=$ (Solid, \texttt{None}) \\
|
||||
\texttt{Beam} & append \texttt{sub\_beams} $=$ empty,
|
||||
\texttt{geometry\_override} $=$ \texttt{None} \\
|
||||
\texttt{Spanner} & append \texttt{kind} $=$ Generic, \texttt{style}
|
||||
$=$ (Solid, \texttt{None}) \\
|
||||
\texttt{RepeatStructure} & append \texttt{kind} $=$ SimpleRepeat
|
||||
\{count $=$ 2\} (a v1 repeat \emph{meant} a repeat), \texttt{voltas}
|
||||
$=$ empty \\
|
||||
\texttt{Staff} & append \texttt{default\_clef} $=$ treble
|
||||
(G, line 2, shift 0) \\
|
||||
\texttt{StaffLineConfiguration} & append \texttt{line\_spacing} $=$
|
||||
1.0, \texttt{line\_style} $=$ Solid, \texttt{bracket} $=$
|
||||
\texttt{None} --- at \emph{every} embedding site:
|
||||
\texttt{Staff.default\_staff\_lines},
|
||||
\texttt{Instrument.default\_staff\_lines} (v2-new),
|
||||
\texttt{StaffInstance.staff\_lines\_override}, and the
|
||||
\texttt{SetStaffLayout} op payload's own
|
||||
\texttt{staff\_lines\_override} field \\
|
||||
\texttt{Instrument} & append \texttt{abbreviation} $=$ \texttt{None},
|
||||
\texttt{sound\_config} $=$ empty, \texttt{transposition} $=$
|
||||
\texttt{None}, \texttt{default\_clef} $=$ treble,
|
||||
\texttt{default\_staff\_lines} $=$ the complete v2 default
|
||||
(\texttt{line\_count} $=$ 5, \texttt{line\_spacing} $=$ 1.0,
|
||||
\texttt{line\_style} $=$ Solid, \texttt{bracket} $=$ \texttt{None}),
|
||||
\texttt{unpitched\_members} $=$ empty \\
|
||||
\texttt{ScoreMetadata} & append \texttt{subtitle} / \texttt{lyricist}
|
||||
/ \texttt{arranger} $=$ \texttt{None}, both timestamps $=$
|
||||
\tablenums{0} (the unset convention), \texttt{additional} $=$
|
||||
empty \\
|
||||
the seven embedding op payloads (incl.\ \texttt{CreateRegion}'s
|
||||
transitively embedded staff instances) & default-fill the embedded
|
||||
value(s) as above; \emph{canonical} --- a v0/v1 op block migrates on
|
||||
read, and a block bearing any v2-dependent bytes is major~2 (a
|
||||
lower-major-only reader opens the bundle read-only) \\
|
||||
canonical-base \texttt{MaterializedState} & unchanged, byte-identical,
|
||||
stays major~0 \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
|
||||
% ===========================================================================
|
||||
\chapter{Non-Canonical Pinned Encodings}
|
||||
\label{ch:noncanon}
|
||||
|
|
@ -2803,6 +3099,29 @@ layouts of Section~\ref{sec:values:representative}.
|
|||
no existing assignment changed. Adds the unsafe-edit tombstone
|
||||
\emph{encoding} open question (from P12-E5; semantics ratified in core
|
||||
Chapter~8). Semantics: Operation Catalog 0.6.0. \\
|
||||
\today & Schema evolution / Graph value layouts & 0.5.0 --- Defines
|
||||
\textbf{schema major~2}, the second data-model expansion major
|
||||
(Section~\ref{sec:evolution:major2}): fills the staged truncations ---
|
||||
\texttt{Slur} (kind / curvature override / style), \texttt{Tie} (style),
|
||||
\texttt{Beam} (sub-beams / geometry override), \texttt{Spanner} (kind,
|
||||
with the leading \texttt{Generic} migration default / style),
|
||||
\texttt{RepeatStructure} (kind / voltas), \texttt{Staff}
|
||||
(\texttt{default\_clef}), \texttt{StaffLineConfiguration} (spacing /
|
||||
line style / bracket), \texttt{Instrument} (six appended fields), and
|
||||
\texttt{ScoreMetadata} (six appended fields incl.\ the
|
||||
strictly-authored timestamps) --- with layouts for the new leaf types
|
||||
and the total default-filling v1${\to}$v2 migration table. Assigns the
|
||||
major per payload type: snapshot-only for \texttt{Instrument} /
|
||||
\texttt{RepeatStructure}; \emph{canonical} for the seven embedding op
|
||||
payloads (\texttt{Create}/\texttt{ModifyCrossCutting},
|
||||
\texttt{CreateStaff}, \texttt{CreateStaffInstance},
|
||||
\texttt{SetStaffLayout}, \texttt{SetMetadata}, and
|
||||
\texttt{CreateRegion} transitively through carried staff instances);
|
||||
the canonical base and manifest stay major~0, byte-identical.
|
||||
Accept-set widens to $\{0, 1, 2\}$ (staged per role as the
|
||||
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). \\
|
||||
\bottomrule
|
||||
\end{longtable}
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -2606,8 +2606,11 @@ only the static time structure of the score.
|
|||
trajectory) is defined in Chapter~\ref{ch:graph}.
|
||||
\item Re-anchoring rules for time anchors when their targets are
|
||||
deleted are defined per-operation in Chapter~\ref{ch:semops}.
|
||||
\item \texttt{SpaceUnit}, \texttt{TupletDisplay}, and other purely
|
||||
display-oriented types are defined in Chapter~\ref{ch:layout-ir}.
|
||||
\item \texttt{SpaceUnit} is defined normatively in
|
||||
Chapter~\ref{ch:graph} as of schema major~2 (it entered canonical
|
||||
state through \texttt{StaffLineConfiguration}).
|
||||
\texttt{TupletDisplay} and other purely display-oriented types are
|
||||
defined in Chapter~\ref{ch:layout-ir}.
|
||||
\end{itemize}
|
||||
|
||||
% ===========================================================================
|
||||
|
|
@ -3531,11 +3534,47 @@ pub struct MetadataEntry {
|
|||
pub key: String,
|
||||
pub value: MetadataValue,
|
||||
}
|
||||
|
||||
/// The value of an additional metadata entry (defined schema major 2).
|
||||
/// Closed small union; growth is by appended variant.
|
||||
pub enum MetadataValue {
|
||||
Text(String),
|
||||
Integer(i64),
|
||||
Flag(bool),
|
||||
}
|
||||
|
||||
/// A calendar timestamp (defined schema major 2): nanoseconds since the
|
||||
/// Unix epoch, UTC, no zone. Distinct from WallClockTime, which is
|
||||
/// *performance* time within a score. The zero value is the "unset"
|
||||
/// convention (genesis without a declared creation time).
|
||||
pub struct Timestamp(pub i64);
|
||||
\end{lstlisting}
|
||||
|
||||
The metadata structure is deliberately small. Extended bibliographic,
|
||||
catalog, and editorial-apparatus metadata is the province of foreign-
|
||||
format mappings and analytical layers, not the core.
|
||||
\texttt{additional} is an \emph{ordered authored list}, not a map
|
||||
(defined schema major 2): entry order is preserved verbatim in
|
||||
canonical bytes, and duplicate keys are permitted --- foreign formats
|
||||
legitimately carry repeated keys (multiple contributors, multiple
|
||||
identifiers of one scheme). Consumers wanting map semantics take the
|
||||
first entry per key.
|
||||
|
||||
\begin{requirement}
|
||||
\label{req:graph:metadata-timestamps}
|
||||
\textbf{Timestamps are strictly authored (ratified with schema
|
||||
major 2).} \texttt{creation\_timestamp} and
|
||||
\texttt{modification\_timestamp} are stored, \emph{authored} values:
|
||||
genesis takes the creation timestamp explicitly (the empty-document
|
||||
constructor defaults it to the epoch-zero unset convention), and a
|
||||
\texttt{SetMetadata} operation carries both verbatim as part of the
|
||||
metadata value. Implementations \MUSTNOT{} write either field
|
||||
implicitly --- an automatic modification-time update would rewrite
|
||||
canonical bytes on every edit, churning content addresses and breaking
|
||||
replica byte-agreement for identical operation histories. A client
|
||||
that wants a live modification time surfaces one from non-canonical
|
||||
state (the operation log's stamps); it does not store it here.
|
||||
\end{requirement}
|
||||
|
||||
\section{Identifiers}
|
||||
\label{sec:graph:ids}
|
||||
|
|
@ -4552,6 +4591,48 @@ pub struct StaffInstance {
|
|||
pub visible: bool,
|
||||
}
|
||||
|
||||
/// The clef content model (ratified schema major 2; the value types
|
||||
/// landed with the visible slice and supersede the earlier ClefId
|
||||
/// identifier sketch). A clef is a value, not a registry reference.
|
||||
pub enum ClefShape {
|
||||
/// G clef (treble family) -- reference pitch G4.
|
||||
G,
|
||||
/// F clef (bass family) -- reference pitch F3.
|
||||
F,
|
||||
/// C clef (alto / tenor family) -- reference pitch middle C (C4).
|
||||
C,
|
||||
/// Unpitched percussion clef -- no diatonic reference.
|
||||
Percussion,
|
||||
}
|
||||
|
||||
pub struct Clef {
|
||||
pub shape: ClefShape,
|
||||
/// The staff line (1 = bottom) the shape's reference pitch sits on.
|
||||
pub line: i8,
|
||||
/// Signed octave displacement (e.g., -1 for the vocal tenor G clef).
|
||||
pub octave_shift: i8,
|
||||
}
|
||||
|
||||
/// A key signature on the circle of fifths, validated to the
|
||||
/// conventional CMN range -7 (seven flats) ..= +7 (seven sharps).
|
||||
/// Constructed only through a checked constructor; decoders reject
|
||||
/// out-of-range values.
|
||||
pub struct KeySignature {
|
||||
fifths: i8, // private; KeySignature::new rejects |fifths| > 7
|
||||
}
|
||||
|
||||
/// A clef change at a point in a staff instance.
|
||||
pub struct ClefChange {
|
||||
pub anchor: TimeAnchor,
|
||||
pub clef: Clef,
|
||||
}
|
||||
|
||||
/// A key-signature change at a point in a staff instance.
|
||||
pub struct KeySignatureChange {
|
||||
pub anchor: TimeAnchor,
|
||||
pub key: KeySignature,
|
||||
}
|
||||
|
||||
/// A per-staff (or per-region-default) metric organization.
|
||||
pub struct MetricGrid {
|
||||
/// Sequence of meter changes within the scope of this grid.
|
||||
|
|
@ -4631,18 +4712,70 @@ pub struct Instrument {
|
|||
/// pitches; not a hard constraint.
|
||||
pub range: Option<PitchRange>,
|
||||
|
||||
/// Default clef and staff line count for staves of this
|
||||
/// instrument.
|
||||
pub default_clef: ClefId,
|
||||
pub default_staff_lines: u8,
|
||||
/// Default clef and staff line configuration for staves of this
|
||||
/// instrument. The clef is the content-bearing Clef value defined
|
||||
/// in this chapter (shape, line, octave shift) -- the value model
|
||||
/// ratified with the visible slice supersedes the earlier ClefId
|
||||
/// identifier sketch (reconciled schema major 2).
|
||||
pub default_clef: Clef,
|
||||
pub default_staff_lines: StaffLineConfiguration,
|
||||
|
||||
/// For unpitched instruments: definitions of each playable
|
||||
/// member (snare, kick, ride bell, etc.) and their staff
|
||||
/// positions.
|
||||
pub unpitched_members: Vec<UnpitchedMember>,
|
||||
}
|
||||
|
||||
/// Opaque sound configuration (defined schema major 2). The audio
|
||||
/// engine specification owns the structure; the core stores the bytes
|
||||
/// verbatim and never interprets them. Empty is the default.
|
||||
pub struct SoundConfiguration(pub Vec<u8>);
|
||||
|
||||
/// A written-versus-sounding transposition (defined schema major 2).
|
||||
/// Structural only: the diatonic and chromatic step counts of the
|
||||
/// interval (e.g., B-flat clarinet = -1 diatonic, -2 chromatic).
|
||||
/// Semantically ADVISORY until the Chapter 4 tuning catalog pins
|
||||
/// interval algebra (the same P12-K2 pinning discipline as the
|
||||
/// Transpose operation); nothing in the core resolves it to
|
||||
/// frequencies or respells through it yet.
|
||||
pub struct TranspositionInterval {
|
||||
pub diatonic_steps: i32,
|
||||
pub chromatic_steps: i32,
|
||||
}
|
||||
|
||||
/// One playable member of an unpitched instrument (defined schema
|
||||
/// major 2): the identifier UnpitchedEvent.instrument_member
|
||||
/// references, its display name, and its default staff position.
|
||||
pub struct UnpitchedMember {
|
||||
pub member: UnpitchedMemberId,
|
||||
pub name: String,
|
||||
pub staff_position: StaffPosition,
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\texttt{UnpitchedMemberId} is an \emph{instrument-scoped small value}
|
||||
(a plain 32-bit integer), not a member of the 128-bit typed-identifier
|
||||
family --- it is minted by the author of the instrument definition, not
|
||||
by replicas, and participates in no content derivation. Member values
|
||||
\emph{should} be unique within one instrument's
|
||||
\texttt{unpitched\_members}; the authoring advisory layer flags a
|
||||
duplicate, and resolution is by first match in list order (canonical
|
||||
bytes preserve the authored order), so a duplicate is deterministic,
|
||||
merely shadowed. An \texttt{UnpitchedEvent.instrument\_member} with no
|
||||
matching entry resolves to \emph{no member definition}: the event still
|
||||
renders (its own \texttt{staff\_position} field governs placement ---
|
||||
the member's \texttt{staff\_position} is the \emph{authoring default}
|
||||
copied onto new events, not a render-time override), and sound mapping
|
||||
falls back to the instrument's \texttt{sound\_config}. This
|
||||
no-match tolerance is load-bearing: every pre-major-2 instrument has an
|
||||
empty member list while its events carry member values.
|
||||
\texttt{StaffPosition}'s vertical convention (which integer is which
|
||||
line, and its orientation) remains \emph{deliberately deferred} to the
|
||||
Chapter~\ref{ch:layout-ir} vertical model, with the unpitched-rendering
|
||||
tranche as its landing site; until then the field is preserved and
|
||||
compared verbatim, and no implementation may claim conformant unpitched
|
||||
\emph{rendering}.
|
||||
|
||||
\subsection{Staves: Identity Versus Instance}
|
||||
\label{sec:graph:staff-identity}
|
||||
|
||||
|
|
@ -4676,8 +4809,10 @@ pub struct Staff {
|
|||
/// overridden per-instance.
|
||||
pub instrument: InstrumentId,
|
||||
|
||||
/// Default clef for new instances of this staff.
|
||||
pub default_clef: ClefId,
|
||||
/// Default clef for new instances of this staff (the
|
||||
/// content-bearing Clef value defined in this chapter; reconciled
|
||||
/// schema major 2).
|
||||
pub default_clef: Clef,
|
||||
|
||||
/// Default staff line configuration.
|
||||
pub default_staff_lines: StaffLineConfiguration,
|
||||
|
|
@ -4693,6 +4828,26 @@ pub struct StaffLineConfiguration {
|
|||
pub line_style: LineStyle,
|
||||
pub bracket: Option<StaffBracketKind>,
|
||||
}
|
||||
|
||||
/// A dimension in staff spaces (defined schema major 2). Staff line
|
||||
/// spacing is relative to the global staff space; 1.0 is a
|
||||
/// normal-size staff, smaller values yield cue/ossia staves.
|
||||
pub struct SpaceUnit(pub CanonicalF64);
|
||||
|
||||
/// A line drawing style (defined schema major 2). Shared by staff
|
||||
/// lines and the slur/tie/spanner style records below.
|
||||
pub enum LineStyle {
|
||||
Solid,
|
||||
Dashed,
|
||||
Dotted,
|
||||
}
|
||||
|
||||
/// A per-staff bracket adornment (defined schema major 2), distinct
|
||||
/// from StaffGroup-level bracketing.
|
||||
pub enum StaffBracketKind {
|
||||
Brace,
|
||||
Bracket,
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
The score's top-level structure carries a list of \texttt{Staff}
|
||||
|
|
@ -4929,7 +5084,46 @@ pub struct Slur {
|
|||
pub curvature_override: Option<CurvatureOverride>,
|
||||
|
||||
/// Visual style: solid, dashed, dotted; line thickness curve.
|
||||
pub style: SlurStyle,
|
||||
pub style: SpanStyle,
|
||||
}
|
||||
|
||||
/// The class of a slur (defined schema major 2). The v1-to-v2
|
||||
/// migration default is Legato.
|
||||
pub enum SlurKind {
|
||||
/// An ordinary legato slur.
|
||||
Legato,
|
||||
/// A phrase mark (typically longer, over sub-phrases).
|
||||
Phrase,
|
||||
/// An articulation slur (e.g., over a two-note sigh figure).
|
||||
Articulation,
|
||||
/// An editorial slur (rendered distinctly, e.g., dashed).
|
||||
Editorial,
|
||||
}
|
||||
|
||||
/// Which side of the notes a curve arcs toward (defined schema
|
||||
/// major 2).
|
||||
pub enum CurveDirection {
|
||||
Above,
|
||||
Below,
|
||||
}
|
||||
|
||||
/// An authored curvature override (defined schema major 2). The
|
||||
/// engraver computes default curvature; each present field overrides
|
||||
/// that component of it. Consumed by the Standard engraving tier;
|
||||
/// stored and preserved at every tier.
|
||||
pub struct CurvatureOverride {
|
||||
pub direction: Option<CurveDirection>,
|
||||
/// Arc height at the apex.
|
||||
pub height: Option<SpaceUnit>,
|
||||
}
|
||||
|
||||
/// The visual style of a spanning mark (defined schema major 2): one
|
||||
/// shared record for Slur.style, Tie.style, and Spanner.style.
|
||||
/// Defaults: solid, engraver-chosen thickness.
|
||||
pub struct SpanStyle {
|
||||
pub line: LineStyle,
|
||||
/// Line thickness; None = the engraver's default.
|
||||
pub thickness: Option<SpaceUnit>,
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
|
|
@ -4957,7 +5151,8 @@ pub struct Tie {
|
|||
/// cross-voice, or notation-specific use.
|
||||
pub class: TieClass,
|
||||
|
||||
pub style: TieStyle,
|
||||
/// Visual style (the shared SpanStyle record, schema major 2).
|
||||
pub style: SpanStyle,
|
||||
}
|
||||
|
||||
pub enum TieClass {
|
||||
|
|
@ -5042,6 +5237,27 @@ pub struct Beam {
|
|||
/// Beam angle and stem-length overrides.
|
||||
pub geometry_override: Option<BeamGeometryOverride>,
|
||||
}
|
||||
|
||||
/// A beam segment at a deeper subdivision level (defined schema
|
||||
/// major 2): a contiguous subset of the owning beam's events beamed
|
||||
/// together at `level` (strictly deeper than the owning beam's
|
||||
/// primary level).
|
||||
pub struct SubBeam {
|
||||
pub level: u8,
|
||||
pub events: Vec<EventId>,
|
||||
}
|
||||
|
||||
/// An authored beam-geometry override (defined schema major 2). Each
|
||||
/// present field overrides the engraver's computed geometry. Consumed
|
||||
/// by the Standard engraving tier; stored and preserved at every tier.
|
||||
pub struct BeamGeometryOverride {
|
||||
/// Beam slope: staff spaces of rise per staff space of run
|
||||
/// (dimensionless, hence not a SpaceUnit).
|
||||
pub slope: Option<CanonicalF64>,
|
||||
/// Vertical displacement of the beam from its default placement
|
||||
/// (positive = up).
|
||||
pub offset: Option<SpaceUnit>,
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\subsection{Spanners}
|
||||
|
|
@ -5061,10 +5277,16 @@ pub struct Spanner {
|
|||
/// lines spanning grand staff) target multiple.
|
||||
pub staves: Vec<StaffId>,
|
||||
|
||||
pub style: SpannerStyle,
|
||||
/// Visual style (the shared SpanStyle record, schema major 2).
|
||||
pub style: SpanStyle,
|
||||
}
|
||||
|
||||
pub enum SpannerKind {
|
||||
/// An unclassified spanning mark: renders as a plain line or
|
||||
/// bracket. First variant deliberately (schema major 2): it is
|
||||
/// the v1-to-v2 migration default -- a v1 spanner carried no
|
||||
/// kind, and Generic is the honest translation of that absence.
|
||||
Generic,
|
||||
Hairpin(HairpinDirection),
|
||||
OctaveLine(OctaveOffset),
|
||||
PedalLine(PedalKind),
|
||||
|
|
@ -5074,6 +5296,37 @@ pub enum SpannerKind {
|
|||
TextLine(TextLineDefinition),
|
||||
Bracket(BracketKind),
|
||||
}
|
||||
|
||||
/// Hairpin orientation (defined schema major 2).
|
||||
pub enum HairpinDirection {
|
||||
Crescendo,
|
||||
Diminuendo,
|
||||
}
|
||||
|
||||
/// Octave-line displacement in signed octaves (defined schema
|
||||
/// major 2): +1 = 8va, -1 = 8vb, +2 = 15ma, -2 = 15mb. Zero is
|
||||
/// representable but degenerate; the authoring advisory layer flags
|
||||
/// it, reduction does not.
|
||||
pub struct OctaveOffset(pub i8);
|
||||
|
||||
/// Pedal-line kind (defined schema major 2).
|
||||
pub enum PedalKind {
|
||||
Sustain,
|
||||
Sostenuto,
|
||||
UnaCorda,
|
||||
}
|
||||
|
||||
/// A text line's content (defined schema major 2); the dash pattern
|
||||
/// comes from the spanner's style.
|
||||
pub struct TextLineDefinition {
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
/// A bracket spanner's shape (defined schema major 2). Growth is by
|
||||
/// appended variant.
|
||||
pub enum BracketKind {
|
||||
Square,
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\subsection{Markers}
|
||||
|
|
@ -5122,8 +5375,31 @@ pub enum RepeatKind {
|
|||
DalSegno { segno: TimeAnchor, end_target: TimeAnchor },
|
||||
Volta,
|
||||
}
|
||||
|
||||
/// One volta bracket (defined schema major 2): the passes it applies
|
||||
/// on and the time span it covers. A RepeatStructure of kind Volta
|
||||
/// carries one entry per ending (e.g., a first ending Volta with
|
||||
/// endings = [1] and a second with endings = [2]).
|
||||
pub struct Volta {
|
||||
/// The pass numbers this ending plays on (1-based), ascending.
|
||||
pub endings: Vec<u32>,
|
||||
pub start: TimeAnchor,
|
||||
pub end: TimeAnchor,
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
The \texttt{endings} constraints (non-empty, 1-based, strictly
|
||||
ascending) are \emph{advisory}, on the \texttt{OctaveOffset} pattern:
|
||||
a violating value is representable, decoders and reduction accept it,
|
||||
and the authoring validation layer flags it. Rendering treats an
|
||||
unlistable ending set as a plain bracket.
|
||||
|
||||
The v1-to-v2 migration default for a kindless v1 repeat structure is
|
||||
\texttt{SimpleRepeat} with \texttt{count}~$=$~2: a v1
|
||||
\texttt{RepeatStructure} \emph{meant} a repeat, and playing the span
|
||||
twice is the conventional semantics of an unadorned repeat sign.
|
||||
Voltas default empty.
|
||||
|
||||
\subsection{Analytical Annotations}
|
||||
|
||||
Analytical annotations record analyses of the music: Roman numerals,
|
||||
|
|
@ -5625,12 +5901,15 @@ construct additional indexes provided they are kept consistent.
|
|||
representation is defined in Chapter~\ref{ch:layout-ir}.
|
||||
\item The on-disk serialization of every type introduced in this
|
||||
chapter is defined in Chapter~\ref{ch:format}.
|
||||
\item Engraving-specific types (\texttt{StemConfiguration},
|
||||
\texttt{ClefId}, \texttt{ArticulationMark}, \texttt{ClefChange},
|
||||
\texttt{KeySignatureChange}, \texttt{LineStyle}, and similar)
|
||||
are introduced informally here and fully defined in
|
||||
Chapter~\ref{ch:layout-ir} where their interaction with the
|
||||
engraver is specified.
|
||||
\item Some engraving-specific types (\texttt{StemConfiguration},
|
||||
\texttt{ArticulationMark}, and similar) are introduced informally
|
||||
here and fully defined in Chapter~\ref{ch:layout-ir} where their
|
||||
interaction with the engraver is specified. The clef/key content
|
||||
model (\texttt{Clef}, \texttt{ClefShape}, \texttt{KeySignature},
|
||||
\texttt{ClefChange}, \texttt{KeySignatureChange}) and
|
||||
\texttt{LineStyle} are defined normatively \emph{in this chapter}
|
||||
as of schema major~2; the former \texttt{ClefId} identifier sketch
|
||||
is retired in favour of embedded \texttt{Clef} values.
|
||||
\end{itemize}
|
||||
|
||||
% ===========================================================================
|
||||
|
|
@ -5871,6 +6150,9 @@ pub enum OperationKind {
|
|||
// Pitch and tuning operations
|
||||
RespellPitch(RespellPitchOp),
|
||||
Transpose(TransposeOp),
|
||||
InsertIdentifiedPitch(InsertIdentifiedPitchOp),
|
||||
DeleteIdentifiedPitch(DeleteIdentifiedPitchOp),
|
||||
ModifyIdentifiedPitch(ModifyIdentifiedPitchOp),
|
||||
|
||||
// Cross-cutting operations
|
||||
CreateCrossCutting(CreateCrossCuttingPayload),
|
||||
|
|
@ -5884,10 +6166,16 @@ pub enum OperationKind {
|
|||
InsertStaffInstance(InsertStaffInstanceOp),
|
||||
DeleteStaffInstance(DeleteStaffInstanceOp),
|
||||
InsertStaff(InsertStaffOp),
|
||||
CreateVoice(CreateVoiceOp),
|
||||
DeleteVoice(DeleteVoiceOp),
|
||||
|
||||
// Metric-model operations
|
||||
SetTimeSignature(SetTimeSignatureOp),
|
||||
SetTempoSegment(SetTempoSegmentOp),
|
||||
SetMetricGrid(SetMetricGridOp),
|
||||
|
||||
// Score settings
|
||||
SetMetadata(SetMetadataOp),
|
||||
|
||||
// Layout-semantic operations
|
||||
SetUserSystemBreak(SetUserSystemBreakOp),
|
||||
|
|
@ -10789,6 +11077,30 @@ above. It always discards the higher-major non-canonical caches. A major-1
|
|||
reader migrates a major-0 acceleration snapshot and a major-0
|
||||
\texttt{CreateRegion} payload on read (default-filling the new fields).
|
||||
|
||||
Schema major~2 is the second data-model expansion major: it fills the
|
||||
truncated bodies of the cross-cutting structures (\texttt{Slur},
|
||||
\texttt{Tie}, \texttt{Beam}, \texttt{Spanner}), \texttt{RepeatStructure}
|
||||
(kind and voltas), \texttt{Staff} and \texttt{StaffLineConfiguration},
|
||||
\texttt{Instrument}, and \texttt{ScoreMetadata}, per this revision's
|
||||
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
|
||||
(\texttt{CreateCrossCutting}, \texttt{ModifyCrossCutting},
|
||||
\texttt{InsertStaff} and \texttt{InsertStaffInstance} (the Operation
|
||||
Catalog's \texttt{CreateStaff} / \texttt{CreateStaffInstance}),
|
||||
\texttt{SetStaffLayout}, \texttt{SetMetadata}, and --- transitively,
|
||||
because an embedded \texttt{Region} may carry a \texttt{StaffInstance}
|
||||
whose \texttt{staff\_lines\_override} embeds the filled
|
||||
\texttt{StaffLineConfiguration} --- \texttt{InsertRegion}
|
||||
(\texttt{CreateRegion})), the canonical operation layer. A block is
|
||||
stamped with the \emph{lowest} schema major whose layouts decode its
|
||||
bytes (the companion's minimal-stamping rule --- deterministic, so
|
||||
identical content hashes identically): any v2-dependent bytes make it
|
||||
major~2, and a lower-major-only reader opens such a bundle read-only. The wire form
|
||||
and the total default-filling v1${\to}$v2 migration are defined in the
|
||||
Binary Format companion.
|
||||
|
||||
\section{Format Profiles}
|
||||
\label{sec:format:profiles}
|
||||
|
||||
|
|
@ -14997,6 +15309,36 @@ layouts they own versus inherit:
|
|||
movements: Operation Catalog 0.5.0~$\rightarrow$~0.6.0, Binary Format
|
||||
0.3.0~$\rightarrow$~0.4.0.
|
||||
\\
|
||||
\today & Schema major 2 (data-model expansion, Phase A) &
|
||||
Defines the leaf types Chapter~5's ratified shapes referenced but never
|
||||
pinned: \texttt{SlurKind}, \texttt{CurveDirection},
|
||||
\texttt{CurvatureOverride}, the shared \texttt{SpanStyle} record
|
||||
(consolidating the formerly-sketched identical
|
||||
\texttt{SlurStyle}/\texttt{TieStyle}/\texttt{SpannerStyle} triplet),
|
||||
\texttt{SubBeam}, \texttt{BeamGeometryOverride}, the
|
||||
\texttt{SpannerKind} payload types (\texttt{HairpinDirection},
|
||||
\texttt{OctaveOffset}, \texttt{PedalKind}, \texttt{TextLineDefinition},
|
||||
\texttt{BracketKind}) --- \texttt{SpannerKind}
|
||||
gains a leading \texttt{Generic} variant as the honest migration default
|
||||
--- \texttt{Volta}, \texttt{MetadataValue}, \texttt{Timestamp},
|
||||
\texttt{SoundConfiguration}, \texttt{TranspositionInterval} (structural,
|
||||
advisory until the Chapter~4 tuning catalog per the P12-K2 discipline),
|
||||
\texttt{UnpitchedMember}, \texttt{SpaceUnit}, \texttt{LineStyle}, and
|
||||
\texttt{StaffBracketKind}. Ratifies the clef/key content model into
|
||||
Chapter~5 (\texttt{Clef}, \texttt{ClefShape}, \texttt{KeySignature},
|
||||
\texttt{ClefChange}, \texttt{KeySignatureChange} --- the visible-slice
|
||||
value types) and retires the \texttt{ClefId} identifier sketch:
|
||||
\texttt{Staff.default\_clef} and \texttt{Instrument.default\_clef} embed
|
||||
\texttt{Clef} values, and \texttt{Instrument.default\_staff\_lines} is
|
||||
reconciled from \texttt{u8} to \texttt{StaffLineConfiguration}. Metadata
|
||||
timestamps are pinned strictly authored
|
||||
(Requirement~\ref{req:graph:metadata-timestamps}: nothing writes them
|
||||
implicitly). Chapter~8 gains the schema-major-2 paragraph (canonical base
|
||||
stays major~0; the filled values reach the snapshot and the seven embedding
|
||||
operation payloads, \texttt{InsertRegion} transitively). Wire forms and the
|
||||
total default-filling migration: Binary Format companion
|
||||
0.4.0~$\rightarrow$~0.5.0.
|
||||
\\
|
||||
\bottomrule
|
||||
\end{longtable}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue