% !TEX program = xelatex
%
% Epiphany --- Binary Format (companion specification)
% Companion to the Core Specification. Compile with XeLaTeX.
%
% This document is versioned independently of the Core Specification
% (independent semver; see the Versioning note in the front matter). Its preamble
% is intentionally a self-contained copy of the core specification's preamble so
% the two documents build independently; factoring a shared preamble file is a
% later cleanup, not a v0.1 deliverable.

\documentclass[11pt,letterpaper]{report}

% ---------------------------------------------------------------------------
% Packages
% ---------------------------------------------------------------------------
\usepackage{fontspec}
\usepackage{geometry}
\geometry{
  letterpaper,
  top=1.05in,
  bottom=1.05in,
  left=1.15in,
  right=1.15in,
  headheight=15pt
}

\usepackage[english]{babel}
\usepackage{microtype}
\usepackage{parskip}
\usepackage{xcolor}
\usepackage{hyperref}
\usepackage{enumitem}
\usepackage{titlesec}
\usepackage{fancyhdr}
\usepackage{booktabs}
\usepackage{array}
\usepackage{longtable}
\usepackage{listings}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{tcolorbox}
\tcbuselibrary{breakable, skins}

% ---------------------------------------------------------------------------
% Color palette (shared with the core specification)
% ---------------------------------------------------------------------------
\definecolor{epiphanyteal}{HTML}{1A4044}
\definecolor{epiphanygold}{HTML}{8E6E2E}
\definecolor{epiphanyink}{HTML}{1F1B16}
\definecolor{epiphanyslate}{HTML}{6B6660}
\definecolor{epiphanycream}{HTML}{F8F4ED}
\definecolor{epiphanymist}{HTML}{ECE8E0}
\definecolor{epiphanycode}{HTML}{2A2520}
\definecolor{epiphanycrimson}{HTML}{7A2424}

\hypersetup{
  colorlinks=true,
  linkcolor=epiphanyteal,
  citecolor=epiphanyteal,
  urlcolor=epiphanygold,
  pdftitle={Epiphany --- Binary Format},
  pdfauthor={The Epiphany Project},
  pdfsubject={Binary Format companion for the Epiphany music notation platform},
  pdfkeywords={music notation, binary format, serialization, wire format, canonical encoding},
  bookmarksnumbered=true,
  bookmarksopen=true
}

% ---------------------------------------------------------------------------
% Typography (shared with the core specification)
% ---------------------------------------------------------------------------
\setmainfont{TeX Gyre Pagella}[Numbers={OldStyle, Proportional}, Ligatures={TeX, Common}]
\setsansfont{TeX Gyre Heros}[Scale=0.94, Ligatures={TeX, Common}]
\setmonofont{TeX Gyre Cursor}[Scale=0.88, Ligatures={TeX}]
\newfontfamily\titlefont{TeX Gyre Pagella}[Numbers={OldStyle}, Ligatures={TeX, Common}]
\newcommand{\tablenums}[1]{{\addfontfeatures{Numbers={Lining,Tabular}}#1}}
\newcommand{\sectionsc}[1]{{\addfontfeatures{Letters=SmallCaps}#1}}

% ---------------------------------------------------------------------------
% Section styling (shared with the core specification)
% ---------------------------------------------------------------------------
\titleformat{\chapter}[display]
  {\normalfont\filright}
  {\raggedright\color{epiphanygold}\fontsize{14pt}{16pt}\selectfont
    \scshape Chapter\ \thechapter}
  {16pt}
  {\raggedright\color{epiphanyteal}\fontsize{32pt}{36pt}\selectfont\bfseries}
  [\vspace{4pt}{\color{epiphanygold}\rule{2in}{0.6pt}}]
\titlespacing*{\chapter}{0pt}{-20pt}{30pt}
\titleformat{\section}
  {\normalfont\Large\bfseries\color{epiphanyteal}}
  {\color{epiphanygold}\thesection}{1em}{}
\titleformat{\subsection}
  {\normalfont\large\bfseries\color{epiphanyteal}}
  {\color{epiphanygold}\thesubsection}{1em}{}
\titleformat{\subsubsection}
  {\normalfont\normalsize\bfseries\color{epiphanyink}}
  {\thesubsubsection}{1em}{}

% ---------------------------------------------------------------------------
% Headers and footers (shared with the core specification)
% ---------------------------------------------------------------------------
\pagestyle{fancy}
\fancyhf{}
\renewcommand{\headrulewidth}{0pt}
\renewcommand{\footrulewidth}{0pt}
\fancyhead[L]{\small\scshape\color{epiphanyslate}Epiphany --- Binary Format}
\fancyhead[R]{\small\itshape\color{epiphanyslate}\leftmark}
\fancyfoot[C]{\small\color{epiphanyslate}\thepage}
\renewcommand{\headrule}{
  \color{epiphanygold!50}\hrule width\headwidth height 0.4pt
  \vspace{1pt}
  \color{epiphanygold!30}\hrule width\headwidth height 0.2pt
}

% ---------------------------------------------------------------------------
% Code listing style (shared with the core specification)
% ---------------------------------------------------------------------------
\lstdefinelanguage{Rust}{
  keywords={fn,let,mut,pub,struct,enum,impl,trait,for,in,if,else,match,return,
           use,mod,crate,self,Self,as,where,move,async,await,const,static,
           ref,type,unsafe,extern,dyn,box,break,continue,loop,while},
  keywordstyle=\color{epiphanyteal}\bfseries,
  ndkeywords={i8,i16,i32,i64,i128,u8,u16,u32,u64,u128,f32,f64,bool,char,str,
              String,Vec,Option,Result,Box,Rc,Arc,HashMap,BTreeMap,
              NonZeroU16,NonZeroU32,NonZeroU64,Duration,Timestamp},
  ndkeywordstyle=\color{epiphanygold}\bfseries,
  sensitive=true,
  comment=[l]{//},
  morecomment=[s]{/*}{*/},
  commentstyle=\color{epiphanyslate}\itshape,
  stringstyle=\color{epiphanycrimson},
  morestring=[b]",
  morestring=[b]'
}
\lstset{
  basicstyle=\ttfamily\small\color{epiphanycode},
  backgroundcolor=\color{epiphanycream},
  frame=leftline,
  rulecolor=\color{epiphanygold!60},
  framesep=8pt,
  framerule=1.5pt,
  xleftmargin=10pt,
  xrightmargin=4pt,
  breaklines=true,
  showstringspaces=false,
  numberstyle=\tiny\color{epiphanyslate},
  numbersep=10pt,
  captionpos=b,
  aboveskip=10pt,
  belowskip=10pt,
  language=Rust
}

% ---------------------------------------------------------------------------
% Custom environments (shared with the core specification)
% ---------------------------------------------------------------------------
\newtcolorbox{openquestion}[1][]{
  enhanced, breakable,
  colback=epiphanymist, colframe=epiphanycrimson,
  fonttitle=\bfseries\color{white}, title={\scshape\hspace{2pt}Open Question},
  coltitle=white, colbacktitle=epiphanycrimson,
  arc=1pt, boxrule=0pt, leftrule=2pt,
  left=10pt, right=10pt, top=8pt, bottom=8pt,
  attach boxed title to top left={xshift=0pt, yshift=0pt},
  boxed title style={arc=0pt, sharp corners, boxrule=0pt, left=6pt, right=8pt, top=2pt, bottom=2pt},
  #1
}
\newtcolorbox{rationale}[1][]{
  enhanced, breakable,
  colback=epiphanymist, colframe=epiphanyteal,
  fonttitle=\bfseries\color{white}, title={\scshape\hspace{2pt}Rationale},
  coltitle=white, colbacktitle=epiphanyteal,
  arc=1pt, boxrule=0pt, leftrule=2pt,
  left=10pt, right=10pt, top=8pt, bottom=8pt,
  attach boxed title to top left={xshift=0pt, yshift=0pt},
  boxed title style={arc=0pt, sharp corners, boxrule=0pt, left=6pt, right=8pt, top=2pt, bottom=2pt},
  #1
}
% Numbered within chapter (this document has chapters); see core_spec.tex's
% requirement box for why a plain counter + `code=` step is used instead of
% tcolorbox's own "auto counter, number within=..." keys.
\newcounter{requirement}[chapter]
\renewcommand{\therequirement}{\thechapter.\arabic{requirement}}
\newtcolorbox{requirement}[1][]{
  enhanced, breakable,
  colback=white, colframe=epiphanygold,
  fonttitle=\bfseries\color{white}, code={\refstepcounter{requirement}}, title={\scshape\hspace{2pt}Requirement~\therequirement},
  coltitle=white, colbacktitle=epiphanygold,
  arc=1pt, boxrule=0pt, leftrule=2pt,
  left=10pt, right=10pt, top=8pt, bottom=8pt,
  attach boxed title to top left={xshift=0pt, yshift=0pt},
  boxed title style={arc=0pt, sharp corners, boxrule=0pt, left=6pt, right=8pt, top=2pt, bottom=2pt},
  #1
}
\newtcolorbox{nongoal}[1][]{
  enhanced, breakable,
  colback=epiphanymist, colframe=epiphanyslate,
  fonttitle=\bfseries\color{white}, title={\scshape\hspace{2pt}Non-Goal},
  coltitle=white, colbacktitle=epiphanyslate,
  arc=1pt, boxrule=0pt, leftrule=2pt,
  left=10pt, right=10pt, top=8pt, bottom=8pt,
  attach boxed title to top left={xshift=0pt, yshift=0pt},
  boxed title style={arc=0pt, sharp corners, boxrule=0pt, left=6pt, right=8pt, top=2pt, bottom=2pt},
  #1
}

\newcommand{\MUST}{\textbf{MUST}}
\newcommand{\MUSTNOT}{\textbf{MUST}\nobreak\ \textbf{NOT}}
\newcommand{\SHOULD}{\textbf{SHOULD}}
\newcommand{\SHOULDNOT}{\textbf{SHOULD}\nobreak\ \textbf{NOT}}
\newcommand{\MAY}{\textbf{MAY}}

% Byte concatenation within a wire layout.
\newcommand{\cat}{\ensuremath{\,\Vert\,}}
% A breakable underscore for long monospace anchor names.
\newcommand{\ub}{\_\allowbreak}
% Long monospace tokens (requirement names, test paths) cannot hyphenate;
% allow loose lines instead of overfull ones.
\emergencystretch=3em
\tolerance=2000

\setlist[itemize]{topsep=2pt, itemsep=3pt, parsep=0pt}
\setlist[enumerate]{topsep=2pt, itemsep=3pt, parsep=0pt}
\setlist[description]{topsep=2pt, itemsep=5pt, parsep=0pt}
\AtBeginDocument{\color{epiphanyink}}

% ---------------------------------------------------------------------------
% Document
% ---------------------------------------------------------------------------
\begin{document}

\begin{titlepage}
  \thispagestyle{empty}
  \centering
  \vspace*{2.2in}
  {\color{epiphanygold}\rule{3in}{0.8pt}}\\[18pt]
  {\titlefont\fontsize{34pt}{38pt}\selectfont\color{epiphanyteal}\bfseries Epiphany}\\[10pt]
  {\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.17.0 --- The container format major becomes 1: the header carries an epoch}\\[4pt]
  {\small\color{epiphanyslate}Normative for the byte layouts it defines}
  \vfill
\end{titlepage}

\tableofcontents

% ===========================================================================
\chapter{About This Companion}
\label{ch:about}

The \emph{Binary Format} document is a companion to the Epiphany Core
Specification. It fulfils the core specification's delegation in Chapter~8,
\sectionsc{Binary Format Companion} (the \texttt{sec:format:binary} section):
the byte-level encoding --- integer conventions, exact field widths, record
alignment, endianness, string encoding details, struct layouts --- is delivered
here. In the core specification's words: \emph{``The Binary Format document is
normative; an implementation cannot conform to the file format specification
without conforming to the Binary Format specification.''}

This release (v0.1.0) delivers the full \textbf{K-independent} encoding
surface --- identifier and derivation layouts, primitive value encodings, the
whole-\texttt{Score} composite value codec, the operation-layer wire forms,
the bundle physical layout, and the extension-declaration blob forms ---
\emph{plus} the \textbf{K0/M2 operation-payload wire framing}. The Operation
Catalog's K0 set (the representative primitives and the M2 broad-K0 groups,
catalog version 0.4.0) now exists in ratified form, so the historical ``waits
for Agent~K'' clause in the Phase-2 charter is discharged: every operation
kind the catalog defines has its literal wire form pinned in
Chapter~\ref{ch:ops}.

This document does \emph{not} cover:

\begin{itemize}
  \item the canonical s-expression form --- that is the \emph{Text Projection}
    companion's (version~0.1.0, which now exists);
  \item per-profile feature lists --- the \emph{Profile Conformance}
    companion's;
  \item the Chapter-4 tuning-catalog values (pitch-space and tuning-system
    registries), which are undelivered Track-C work and have no wire form yet;
  \item the wire-format fuzzer, an \emph{implementation} deliverable tracked
    in the Phase-2 process documents rather than part of this document's
    normative text; Chapter~\ref{ch:goldens} records the golden anchors any
    such harness must reproduce.
\end{itemize}

It \emph{does} cover the cross-implementation decoder test, which is no longer
deferred: Section~\ref{sec:goldens:decode-vectors} ratifies the literal-byte
vector corpus and the accept/reject verdict a conforming decoder owes it.

\section{Relationship to the Core Specification and the Operation Catalog}
\label{sec:about:relationship}

This companion \emph{inherits} --- it never re-derives --- the core
specification's ratified convention baseline: core specification Chapter~8,
\sectionsc{Binary Format Companion}, requirement
\texttt{req:format:codec-conventions}, together with the
\sectionsc{Canonical Byte-Layout Reference} appendix (\texttt{app:bytes}).
That appendix consolidates every discriminant table, derivation preimage, and
primitive encoding Pass~11 and Pass~12 ratified, precisely so that this
document could import it as a starting point rather than recovering the
layouts from the crates. Chapter~\ref{ch:ids} therefore reproduces only
\emph{compact} normative tables, each with a citation back to the appendix
row and requirement that governs it; where this document and a ratified core
requirement disagree, \textbf{the core requirement governs} and the
discrepancy is a defect in this document.

What this document adds is the completion of the appendix's deferred list
(core specification, \sectionsc{Layouts deferred to the companions},
\texttt{sec:bytes:deferred}): the \texttt{OperationKind} and
\texttt{OperationKindTag} discriminants and full per-operation payload
encodings; the full composite struct layouts (whole-\texttt{Score}, operation
envelopes, the manifest body's field order); schema-version wire evolution;
and the varint question, which Chapter~\ref{ch:conventions} settles.

The division of labour with the \emph{Operation Catalog} is exact: the
catalog fixes each operation's \textbf{field set and order} (Operation
Catalog, \sectionsc{Per-Primitive Schema Template}) and its semantics; this
document pins the \textbf{bytes} of those fields. Chapter~\ref{ch:ops} cites
the catalog section for every payload rather than restating what the fields
mean. Likewise, graph \emph{types} are the core specification's Chapters 2--5,
and the structural layer of the bundle --- what a header, superblock, chunk
graph, or manifest \emph{is} and how it behaves --- is core Chapter~8; this
document specifies only how those structures' bits are laid out.

\begin{rationale}
\textbf{Versioning.} This companion is versioned independently of the core
specification (independent semver), like the Operation Catalog --- but tied
tighter to it: the binary-format \textsc{major} version tracks the core
specification's major version (both are pre-1.0 working drafts today, hence
v0.1.0), while \textsc{minor} versions diverge freely. Byte layouts change on
a slower, more deliberate cadence than prose; a core-spec minor revision that
touches no wire fact requires no revision here, and an additive discriminant
append here (Chapter~\ref{ch:evolution}) requires no core-spec revision.
\end{rationale}

\section{Conformance}
\label{sec:about:conformance}

The byte layouts in this document are \textbf{normative}. An implementation
conforms to the Epiphany binary format if and only if, for every layout this
document defines, it produces exactly the specified bytes when encoding and
accepts exactly the specified language of byte strings when decoding.

Decode discipline is \textbf{reject, never normalize} --- the workspace-wide
convention the core specification establishes in Appendix~D (canonical
serialization determinism and ordered iteration). Concretely, each of the
following is a \emph{decode error}, never an input to be repaired:

\begin{itemize}
  \item an unknown discriminant in any tagged union;
  \item a set- or map-valued field whose elements are not in strictly
    ascending canonical order, or which contains duplicates;
  \item text that is not in Unicode NFC where NFC is required (catalog
    identifiers, barrier pitch-space names, operation labels);
  \item trailing bytes after a complete top-level value
    (Requirement~\ref{req:binfmt:trailing-bytes});
  \item recursion beyond a normative depth bound
    (Requirement~\ref{req:binfmt:condition-depth}).
\end{itemize}

A decoder \MUSTNOT{} silently sort, deduplicate, NFC-fold, truncate, or
otherwise canonicalize non-canonical input: two implementations that disagree
on repair would disagree on canonical state.

The \textbf{golden anchor registry} (Chapter~\ref{ch:goldens}) is the
conformance contract binding this text to the reference implementation: every
layout in this document is anchored by at least one named test in the
reference crates, and a change that breaks an anchor is either a defect or a
deliberate, versioned format revision (Chapter~\ref{ch:evolution}).

% ===========================================================================
\chapter{Encoding Conventions}
\label{ch:conventions}

This chapter restates the ratified convention baseline (core specification,
requirement \texttt{req:format:codec-conventions}) as normative fact and
completes it: the three prefix/endianness regimes, the primitive composition
rules, the varint disposition, and the trailing-bytes rule.

\section{The Three Encoding Regimes}
\label{sec:conventions:regimes}

Three internally consistent regimes coexist in the format. Every layout in
this document belongs to exactly one of them, and each layout's chapter says
which.

\begin{longtable}{p{0.55in} p{2.25in} p{2.85in}}
  \toprule
  \textbf{Regime} & \textbf{Surfaces} & \textbf{Rules} \\
  \midrule
  \endhead
  (a) & Canonical document encodings: the core value codec
        (Chapter~\ref{ch:values}), the operation layer
        (Chapter~\ref{ch:ops}), the bundle codec
        (Chapter~\ref{ch:bundle}). &
        Little-endian fixed-width integers; \texttt{u32} little-endian counts
        and length prefixes on every variable-width field. \\
  (b) & Layout-side pinned encodings: the extension-declaration blobs and
        edit-barrier trees (Chapter~\ref{ch:barriers}) and the
        \texttt{ResolvedLayoutIR} canonical output
        (Chapter~\ref{ch:noncanon}). &
        Little-endian integers; \texttt{u64} little-endian counts and length
        prefixes --- a golden-locked divergence from regime (a). Schema major~1
        moves the \emph{resolved-layout} surface to \texttt{u32}; the
        manifest-embedded barrier blobs stay \texttt{u64}
        (Section~\ref{sec:evolution:major1}). \\
  (c) & Identifiers and hash-derived forms: the 128-bit identifier family,
        \texttt{ReplicaId}, \texttt{OperationId}, \texttt{ConflictId}, the
        \texttt{TypedObjectId} discriminant, digest truncations
        (Chapter~\ref{ch:ids}). &
        Big-endian fixed width. Numeric order equals canonical byte order,
        which is what Appendix~D's ordered iteration requires. \\
  \bottomrule
\end{longtable}

\begin{rationale}
In schema major~0, regimes (a) and (b) differ only in prefix width, and the
divergence was \emph{tolerated rather than repaired}: the two surfaces were
golden-locked independently (the barrier blobs and the resolved-layout output
carry their own literal-byte anchors), they never embed one another's framing,
and unifying the prefix width within major~0 would break locked bytes for zero
benefit. Once a major bump was scheduled for data-model reasons, part of the
unification became free to carry: schema major~1 moves the resolved-layout
surface (an independent non-canonical \texttt{LayoutCache}) to regime (a)'s
\texttt{u32} prefixes and re-locks its goldens. The barrier blobs cannot follow
in the same step --- they are carried opaquely inside the \emph{canonical}
manifest, which stays major~0 --- so they keep regime (b) until a manifest-
revising major (Chapter~\ref{ch:evolution}). Regime (c) is not a divergence at
all: an identifier's byte form \emph{is} its sort key, so big-endian is
load-bearing.
\end{rationale}

\section{Primitive Composition Rules}
\label{sec:conventions:primitives}

The following rules apply throughout regime (a); regimes (b) and (c) state
their deltas in their own chapters.

\begin{description}
  \item[Booleans.] A single byte: \texttt{0} = false, \texttt{1} = true. Any
    other value is a decode error.
  \item[Integers.] Fixed-width little-endian two's complement
    (\texttt{u8}/\texttt{i8} through \texttt{u128}), except within regime (c).
  \item[\texttt{Option<T>}.] A presence byte: \texttt{0} = absent (no further
    bytes), \texttt{1} = present, followed by \texttt{T}'s encoding. A
    presence byte greater than~1 is a decode error.
  \item[Sequences, sets, maps.] A \texttt{u32} little-endian element count,
    then each element (for maps: key then value). Set- and map-valued fields
    are emitted in canonical iteration order --- ascending by the key's
    canonical byte form --- and decoders reject out-of-order or duplicated
    elements wherever the field is a set or map (as opposed to an
    order-significant list).
  \item[Free text.] A \texttt{u32} little-endian byte length, then the raw
    UTF-8 bytes. Free-text fields (e.g.\ a score title) are \textbf{never}
    NFC-folded by the codec: $\mathrm{decode}(\mathrm{encode}(x)) = x$ is the
    round-trip identity, and folding would break it. By contrast,
    \emph{catalog identifiers} (pitch-space ids, tuning-system ids, and the
    other \texttt{catalog\_id} newtypes) are NFC-normalized \emph{at
    construction}, so their stored form is already NFC; the codec encodes the
    stored string verbatim. Operation-layer text fields (the transaction
    label, conflict field paths) are NFC-normalized at encode time
    (Chapter~\ref{ch:ops}).
  \item[Structs.] Positional, unframed concatenation of the fields' encodings
    in declaration order. No field tags, no per-field lengths, no padding, no
    alignment. (This is the layout the frozen-layout rule,
    Requirement~\ref{req:binfmt:frozen-layout}, freezes.)
  \item[Tagged unions.] A single discriminant byte, then the selected
    variant's payload encoded positionally. Two documented exceptions:
    \texttt{TypedObjectId} uses a \emph{16-bit big-endian} discriminant
    (core requirement \texttt{req:graph:typed-object-id-discriminants};
    Chapter~\ref{ch:ids}), and the bundle's \texttt{ProfileId} uses a
    \texttt{u32} little-endian discriminant (core requirement
    \texttt{req:format:profileid-discriminants}; Chapter~\ref{ch:bundle}).
  \item[Determinism-canonical leaves.] Where a composite codec embeds a value
    whose canonical byte form is owned by the determinism layer or the
    identifier layer (a graph identifier, \texttt{ContentHash},
    \texttt{CanonicalF64}, \texttt{RationalTime}, a wall-clock integer), the
    core value codec frames it as a \texttt{u32} little-endian length prefix
    followed by the leaf's own canonical bytes --- even when the leaf is
    fixed-width. The leaf's bytes are then self-describing under its own
    decoder. (The operation layer instead embeds fixed-width leaves
    \emph{raw}, unprefixed; Chapter~\ref{ch:ops} states this explicitly.)
\end{description}

\begin{requirement}
\label{req:binfmt:no-varint}
\textbf{No varint.} Schema major~0 defines \emph{no} variable-length integer
encoding. Every integer field in every layout in this document is
fixed-width. The core specification's ``varint conventions'' language
(Chapter~8, \sectionsc{Binary Format Companion}) is hereby discharged as
\emph{none}: an encoder \MUSTNOT{} emit, and a decoder \MUSTNOT{} accept, any
LEB128-style or otherwise variable-width integer under schema major~0.
Variable width in this format comes only from explicit \texttt{u32}/%
\texttt{u64} length prefixes and from \texttt{RationalTime}'s length-prefixed
big-integer magnitudes (Chapter~\ref{ch:primitives}).
\end{requirement}

\begin{requirement}
\label{req:binfmt:trailing-bytes}
\textbf{Trailing bytes.} Every top-level decode entry point --- a
whole-\texttt{Score} value, a per-value \texttt{CanonicalValue} decode, an
\texttt{OperationKindTag}, a \texttt{MaterializedState}, a manifest payload,
an operation-index payload, a block payload, an extension-declaration blob, a
fixed-width primitive --- \MUST{} reject input with bytes remaining after the
complete value has been decoded. Trailing bytes are a decode error, never
ignored padding.
\end{requirement}

% ===========================================================================
\chapter{Identifiers and Derivations}
\label{ch:ids}

This chapter is an \emph{import-by-citation} of the core specification's
\sectionsc{Canonical Byte-Layout Reference} appendix (\texttt{app:bytes}):
that appendix and its golden anchors govern every table in this chapter, and
the tables here are compact restatements for self-containedness, not a second
source of truth. All layouts in this chapter are regime (c): big-endian,
fixed width.

\section{The 128-Bit Identifier Family}
\label{sec:ids:family}

\begin{description}
  \item[\texttt{ReplicaId}.] 8 bytes, big-endian \texttt{u64}. The reserved
    system namespace is \texttt{ReplicaId::SYSTEM\ub DERIVED} =
    \texttt{0xFFFF\ub FFFF\ub FFFF\ub FFFF}; user-authored replicas
    \MUSTNOT{} use it.
  \item[Typed graph identifiers.] Every typed 128-bit graph identifier
    (\texttt{EventId}, \texttt{PitchId}, \texttt{VoiceId},
    \texttt{RegionId}, \texttt{StaffInstanceId}, \texttt{TransactionId},
    \ldots{} --- the \texttt{graph\_id} family) packs the 64-bit replica
    into the high half and the counter into the low half, and encodes as
    exactly 16~bytes: replica big-endian (8) \cat{} counter big-endian (8).
    Numeric order, canonical byte order, and Appendix-D iteration order
    coincide.
  \item[\texttt{OperationId}.] The same 16-byte form: replica big-endian (8)
    \cat{} counter big-endian (8). Ordering is $(\mathit{replica},
    \mathit{counter})$ lexicographic, which equals byte order.
  \item[Registry and author identifiers (operation layer).] The opaque
    128-bit registry newtypes (\texttt{OperationKind\allowbreak RegistryId},
    \texttt{ConflictKind\allowbreak RegistryId},
    \texttt{Resolution\allowbreak RegistryId},
    \texttt{RepairKind\allowbreak RegistryId},
    \texttt{ReanchorReason\allowbreak RegistryId},
    \texttt{ReplicaAnomaly\allowbreak RegistryId},
    \texttt{IntegrityAnomaly\allowbreak RegistryId},
    \texttt{Extension\allowbreak PreconditionId},
    \texttt{PreconditionFailure\allowbreak RegistryId}) and \texttt{AuthorId}
    all encode as 16 big-endian bytes.
\end{description}

\section{\texttt{TypedObjectId}}
\label{sec:ids:typed-object-id}

Canonical form: a \textbf{16-bit big-endian discriminant} \cat{} the variant
payload (core requirement \texttt{req:graph:typed-object-id-discriminants}).
Non-\texttt{Registered} variants carry one 16-byte identifier, for a total of
\textbf{18~bytes}; \texttt{Registered} carries the
\texttt{ObjectKindRegistryId} (16 big-endian bytes) \cat{} the extension's
own raw \texttt{u128} (16 big-endian bytes), for a total of \textbf{34~bytes}.
An unknown discriminant is a decode error.

\begingroup\small
\begin{longtable}{p{0.5in} p{1.6in} p{0.5in} p{1.6in}}
  \toprule
  \textbf{Disc} & \textbf{Variant} & \textbf{Disc} & \textbf{Variant} \\
  \midrule
  \endhead
  \tablenums{0} & \texttt{Event} & \tablenums{14} & \texttt{Spanner} \\
  \tablenums{1} & \texttt{Pitch} & \tablenums{15} & \texttt{Marker} \\
  \tablenums{2} & \texttt{Voice} & \tablenums{16} & \texttt{AnalyticalAnnotation} \\
  \tablenums{3} & \texttt{Staff} & \tablenums{17} & \texttt{Comment} \\
  \tablenums{4} & \texttt{StaffInstance} & \tablenums{18} & \texttt{GraphicObject} \\
  \tablenums{5} & \texttt{StaffGroup} & \tablenums{19} & \texttt{GraphicGesture} \\
  \tablenums{6} & \texttt{Region} & \tablenums{20} & \texttt{TimeSignature} \\
  \tablenums{7} & \texttt{Instrument} & \tablenums{21} & \texttt{AnalysisLayer} \\
  \tablenums{8} & \texttt{PartDefinition} & \tablenums{22} & \texttt{Tuplet} \\
  \tablenums{9} & \texttt{Measure} & \tablenums{23} & \texttt{RepeatStructure} \\
  \tablenums{10} & \texttt{BarlineAlignmentGroup} & \tablenums{24} & \texttt{LyricLine} \\
  \tablenums{11} & \texttt{Slur} & \tablenums{25} & \texttt{ChordSymbol} \\
  \tablenums{12} & \texttt{Tie} & \tablenums{26} & \texttt{View} \\
  \tablenums{13} & \texttt{Beam} & \tablenums{27} & \texttt{Registered} \\
  \bottomrule
\end{longtable}
\endgroup

\section{System-Derived Counters and Digest Truncations}
\label{sec:ids:derivations}

All content derivation uses BLAKE3-256 over a domain-separated preimage: the
8-byte domain tag is always the first bytes hashed. Two truncations recur,
both taking the digest's \emph{leading} bytes big-endian:

\begin{itemize}
  \item $\mathrm{trunc64}(d) = \mathtt{u64::from\_be\_bytes}(d[0..8])$ ---
    the counter of a system-derived identifier;
  \item $\mathrm{trunc128}(d) = \mathtt{u128::from\_be\_bytes}(d[0..16])$ ---
    content-derived 128-bit identifiers.
\end{itemize}

The system-derived counter function is
$\mathrm{trunc64}(\mathrm{BLAKE3}(\mathit{tag} \cat \mathit{inputs}))$; the
resulting identifier is
$\texttt{from\_parts}(\texttt{ReplicaId::SYSTEM\_DERIVED}, \mathit{counter})$.
Only a system domain tag (prefix \texttt{MUSCS}) may seed it. The ratified
instances (governed by \texttt{app:bytes} and the cited requirements):

\begingroup\small
\begin{longtable}{p{1.35in} p{0.7in} p{3.5in}}
  \toprule
  \textbf{Identifier} & \textbf{Tag} & \textbf{Canonical inputs} \\
  \midrule
  \endhead
  Promoted \texttt{VoiceId} & \texttt{MUSCSVCE} &
    64-byte preimage: \texttt{staff\_instance} (16 BE) \cat{}
    \texttt{original\_voice} (16 BE) \cat{} \texttt{winning\_op} (16 BE)
    \cat{} \texttt{losing\_op} (16 BE). Core \sectionsc{System-Promoted
    Voices}. \\
  System \texttt{PitchId} & \texttt{MUSCSPCH} &
    The pitch's intrinsic canonical bytes (core requirement
    \texttt{req:graph:system-derived-pitch-id}). \\
  \texttt{IntegrityAnomalyId} & \texttt{MUSCSANM} &
    The anomaly kind's canonical bytes (Chapter~\ref{ch:ops}; core
    requirement \texttt{req:graph:integrity-anomaly-id}). \\
  \bottomrule
\end{longtable}
\endgroup

The 128-bit content-derived identifiers:

\begingroup\small
\begin{longtable}{p{1.1in} p{0.75in} p{3.7in}}
  \toprule
  \textbf{Identifier} & \textbf{Tag} & \textbf{Preimage after the tag} \\
  \midrule
  \endhead
  \texttt{ConflictId} & \texttt{MUSCCONF} &
    \texttt{kind.canonical\_bytes()} \cat{} causing operations (each 16 BE,
    sorted by canonical bytes) \cat{} affected objects (each
    \texttt{TypedObjectId} canonical bytes, sorted); $\mathrm{trunc128}$.
    Wire form of the id itself: 16 big-endian bytes. \\
  \texttt{ManifestId} & \texttt{MUSCMNIF} &
    \texttt{document\_id} (16) \cat{} \texttt{generation} (\texttt{u64} LE)
    \cat{} manifest body bytes (body excludes the \texttt{manifest\_id}
    field); $\mathrm{trunc128}$. Restated normatively in
    Chapter~\ref{ch:bundle} (core requirement
    \texttt{req:format:manifest-id}). Note the \emph{on-disk} field encodes
    little-endian (Chapter~\ref{ch:bundle}). \\
  \texttt{EnvelopeHash} & \texttt{MUSCENVH} &
    The envelope's complete canonical bytes; the full 32-byte digest (no
    truncation). Chapter~\ref{ch:ops}. \\
  \texttt{LayoutObjectId} & \texttt{MUSCLOID} &
    Non-canonical; three preimage shapes, Chapter~\ref{ch:noncanon}
    (core requirement \texttt{req:layoutir:object-id-derivation}). \\
  \texttt{BlobId} & \texttt{MUSCBLOB} &
    The blob payload, bare (\texttt{req:format:blob-hash-shape}); full
    32-byte digest. Chapter~\ref{ch:primitives}. \\
  \bottomrule
\end{longtable}
\endgroup

\section{The Domain-Tag Registry}
\label{sec:ids:tags}

Every domain tag is exactly 8 printable-ASCII bytes beginning \texttt{MUSC};
the vocabulary is closed (governed by \texttt{app:bytes},
\sectionsc{Domain-tag registry}). Extension system tags \MUST{} begin
\texttt{MUSCS}, be exactly 8 bytes, and collide with neither the built-ins
nor the file magics.

\begingroup\small
\begin{longtable}{p{1.05in} p{1.55in} p{3.0in}}
  \toprule
  \textbf{Tag} & \textbf{Name} & \textbf{Use} \\
  \midrule
  \endhead
  \texttt{MUSCCHNK} & chunk & non-manifest chunk hash preimages \\
  \texttt{MUSCMANI} & manifest & manifest chunk hash preimages \\
  \texttt{MUSCBLOB} & blob & \texttt{BlobId} (bare $\mathit{tag} \cat \mathit{payload}$) \\
  \texttt{MUSCCONF} & conflict & \texttt{ConflictId} derivation \\
  \texttt{MUSCENVH} & envelope & \texttt{EnvelopeHash} \\
  \texttt{MUSCFNTM} & font metrics & glyph-catalog metrics hash (non-canonical) \\
  \texttt{MUSCMNIF} & manifest id & \texttt{ManifestId} derivation \\
  \texttt{MUSCSVCE} & system voice & promoted-voice counters \\
  \texttt{MUSCSPCH} & system pitch & system-derived pitch counters \\
  \texttt{MUSCSANM} & system anomaly & \texttt{IntegrityAnomalyId} \\
  \texttt{MUSCLOID} & layout object id & \texttt{LayoutObjectId} (non-canonical) \\
  \midrule
  \texttt{MUSCBND\textbackslash0} & bundle magic & file magic, \emph{not} a hash tag (note the trailing NUL) \\
  \texttt{MUSCSUPR} & superblock magic & slot magic, \emph{not} a hash tag \\
  \bottomrule
\end{longtable}
\endgroup

\section{\texttt{SnapshotId}}
\label{sec:ids:snapshot-id}

The core specification's support-type identity table says \emph{``the Binary
Format companion defines the exact derivation''} of \texttt{SnapshotId}. v0
has no snapshot producer --- pruning and canonical-base creation are deferred
--- so there is nothing to derive \emph{from} yet.

\begin{requirement}
\label{req:binfmt:snapshot-id-opaque}
In schema major~0, \texttt{SnapshotId} is an \textbf{opaque 16-byte
identifier}: 16 raw bytes on the wire (Chapter~\ref{ch:primitives}), with no
normative derivation function. Readers \MUST{} treat two
\texttt{SnapshotId}s as equal iff their 16 bytes are equal and \MUSTNOT{}
attempt to derive or verify a snapshot id from snapshot content.
\end{requirement}

\begin{openquestion}
The \texttt{SnapshotId} derivation (presumably a content derivation in the
\texttt{trunc128} family, over the snapshot's canonical payload and its
covering frontier) is deferred together with the pruning/garbage-collection
track that will produce the first snapshots. It must be pinned before any
writer emits a \texttt{canonical\_base}; until then the opaque reading above
is complete.
\end{openquestion}

% ===========================================================================
\chapter{Primitive Value Encodings}
\label{ch:primitives}

The leaf encodings owned by the determinism layer and the small fixed
identifier types. These byte forms are what the framings of
Chapters~\ref{ch:values}--\ref{ch:bundle} embed.

\begingroup\small
\begin{longtable}{>{\raggedright\arraybackslash}p{1.7in} p{0.5in} p{3.45in}}
  \toprule
  \textbf{Type} & \textbf{Width} & \textbf{Encoding} \\
  \midrule
  \endhead
  \texttt{CanonicalF64} & 8 &
    IEEE-754 binary64, little-endian. $-0.0$ is canonicalized to $+0.0$ at
    construction, so the negative-zero bit pattern never appears in canonical
    bytes. Decode rejects NaN and $\pm\infty$ (non-finite floats are
    corruption). \\
  \texttt{QuantizedCoord} & 8 &
    \texttt{i64} little-endian, in units of $1/1024$ staff space
    (\texttt{STAFF\_SPACE\_GRID} = 1024). Construction from a float rounds
    ties-to-even and rejects non-finite or out-of-range input. \\
  \texttt{ContentHash} & 32 & Raw BLAKE3-256 digest bytes. \\
  \texttt{ChunkId} & 32 & Raw digest bytes (a \texttt{ContentHash} newtype). \\
  \texttt{DomainTag} & 8 &
    The raw ASCII tag bytes. Decode validates against the closed vocabulary
    of Section~\ref{sec:ids:tags}; foreign bytes are a decode error. \\
  \texttt{WallClockTime} & 8 &
    \texttt{i64} little-endian, nanoseconds. Floating-point wall-clock time
    is forbidden in stored data. \\
  \texttt{WallClockDuration} & 8 & \texttt{i64} little-endian, nanoseconds. \\
  \texttt{SchemaVersion} & 4 &
    \texttt{major} \texttt{u16} LE \cat{} \texttt{minor} \texttt{u16} LE. \\
  \texttt{SemVer} & 12 &
    \texttt{major} \texttt{u32} LE \cat{} \texttt{minor} \texttt{u32} LE
    \cat{} \texttt{patch} \texttt{u32} LE. Canonical \emph{ordering} of
    \texttt{SemVer}-keyed collections is \textbf{numeric} on
    $(\mathit{major},\mathit{minor},\mathit{patch})$, never byte-lexicographic
    on the little-endian encoding (which would order 256.0.0 before 1.0.0). \\
  \texttt{Reduction\allowbreak AlgorithmVersion} & 4 & \texttt{u32}
    little-endian. \\
  \texttt{FileUuid}, \texttt{DocumentId}, \texttt{LineageId},
  \texttt{SnapshotId}, \texttt{ExtensionId}, \texttt{ProfileRegistryId} & 16 &
    16 raw opaque bytes each. No internal structure is interpreted;
    equality is byte equality. \\
  \texttt{BlobId} & 32 &
    Raw digest bytes: $\mathrm{BLAKE3}(\texttt{MUSCBLOB} \cat
    \mathit{payload})$, the only bare $\mathit{tag} \cat \mathit{payload}$
    content hash in the format (core requirement
    \texttt{req:format:blob-hash-shape}). \\
  \texttt{FrontierBytes} & var &
    \texttt{u32} LE length \cat{} opaque bytes (an ops-computed causal
    frontier the bundle carries verbatim). \\
  \bottomrule
\end{longtable}
\endgroup

\section{\texttt{RationalTime}}
\label{sec:primitives:rationaltime}

Restating core requirement \texttt{req:format:rationaltime-encoding}, which
governs. \texttt{RationalTime} is an arbitrary-precision rational, always
stored \emph{reduced} (equal rationals encode identically; the sign lives on
the numerator; the denominator is strictly positive). Its canonical byte
form:

\begin{center}
\begin{tabular}{l l}
  \toprule
  \textbf{Field} & \textbf{Encoding} \\
  \midrule
  sign & 1 byte: \tablenums{0} = zero, \tablenums{1} = positive,
    \tablenums{2} = negative \\
  numerator & \texttt{u32} LE magnitude byte length \cat{} big-endian
    magnitude bytes \\
  denominator & \texttt{u32} LE magnitude byte length \cat{} big-endian
    magnitude bytes \\
  \bottomrule
\end{tabular}
\end{center}

Decode rejects a sign byte greater than~2, a zero denominator, and trailing
bytes. \texttt{MusicalPosition} and \texttt{MusicalDuration} are newtypes
whose canonical bytes are exactly their inner \texttt{RationalTime}'s.
Wall-clock integers deliberately do \emph{not} use this form: they are the
fixed-width little-endian integers of the table above, matching
\texttt{QuantizedCoord}'s convention.

% ===========================================================================
\chapter{Graph Value Layouts}
\label{ch:values}

This chapter defines the schema-major-0 wire form of every value reachable
from a \texttt{Score} --- the whole-document composite codec. The core
specification's \texttt{DECISIONS} record (P11-4) held this codec
\emph{provisional} pending this companion;
Requirement~\ref{req:binfmt:score-envelope} and
Requirement~\ref{req:binfmt:frozen-layout} \textbf{ratify} it: the reference
implementation's layout, as specified here, \emph{is} the schema-major-0 wire
form, and P11-4's provisional status is discharged.

All layouts in this chapter are regime (a): little-endian, \texttt{u32}
prefixes.

\section{The \texttt{Score} Envelope}
\label{sec:values:score}

\begin{requirement}
\label{req:binfmt:score-envelope}
The canonical bytes of a \texttt{Score} are the bare positional
concatenation of its nineteen fields' encodings, in exactly this order:

\begin{enumerate}
  \item \texttt{metadata}
  \item \texttt{canvas}
  \item \texttt{instruments}
  \item \texttt{staves}
  \item \texttt{staff\_groups}
  \item \texttt{parts}
  \item \texttt{cross\_cutting}
  \item \texttt{time\_signatures}
  \item \texttt{tuning\_context}
  \item \texttt{tempo\_map}
  \item \texttt{events}
  \item \texttt{spelling\_attachments}
  \item \texttt{decomposition\_attachments}
  \item \texttt{spelling\_precedence}
  \item \texttt{analysis\_layers}
  \item \texttt{views}
  \item \texttt{identity}
  \item \texttt{tombstoned\_pitches}
  \item \texttt{tombstoned\_events}
\end{enumerate}

There is \textbf{no magic} and \textbf{no version prefix} at the value
level: format identification lives in the bundle's fixed header
(Chapter~\ref{ch:bundle}) and versioning lives at the chunk layer
(\texttt{SchemaVersion} in every \texttt{ChunkRef} and superblock;
Chapter~\ref{ch:evolution}). Decoders \MUST{} reject trailing bytes after
the nineteenth field.
\end{requirement}

\section{Composition Rules as Normative Encoding Facts}
\label{sec:values:composition}

The reference codec is built from a small set of conventions; each is a
normative statement about the bytes, not an implementation detail:

\begin{description}
  \item[Positional structs.] Every struct in this chapter encodes as its
    fields in declaration order, unframed
    (Section~\ref{sec:conventions:primitives}). Zero-field structs encode as
    zero bytes.
  \item[C-style enums.] A fieldless enum is a single discriminant byte
    (tables in Section~\ref{sec:values:discriminants}).
  \item[Tagged unions.] A discriminant byte, then the variant's fields
    positionally.
  \item[Leaf framing.] The determinism-canonical leaf types ---
    \texttt{ReplicaId}, \texttt{OperationId}, every embedded typed graph
    identifier (\texttt{EventId}, \texttt{PitchId}, \texttt{VoiceId},
    \texttt{StaffId}, \texttt{StaffInstanceId}, \texttt{StaffGroupId},
    \texttt{RegionId}, \texttt{InstrumentId}, \texttt{PartDefinitionId},
    \texttt{MeasureId}, \texttt{BarlineAlignmentGroupId}, \texttt{SlurId},
    \texttt{TieId}, \texttt{BeamId}, \texttt{SpannerId}, \texttt{TupletId},
    \texttt{MarkerId}, \texttt{AnalyticalAnnotationId}, \texttt{CommentId},
    \texttt{RepeatStructureId}, \texttt{LyricLineId}, \texttt{ChordSymbolId},
    \texttt{GraphicObjectId}, \texttt{GraphicGestureId},
    \texttt{TimeSignatureId}, \texttt{AnalysisLayerId}, \texttt{ViewId}) ---
    plus \texttt{ContentHash}, \texttt{CanonicalF64}, \texttt{RationalTime},
    \texttt{MusicalPosition}, \texttt{MusicalDuration},
    \texttt{WallClockTime}, and \texttt{WallClockDuration}, are each emitted
    as \texttt{u32} LE length \cat{} the leaf's canonical bytes
    (Chapters~\ref{ch:ids} and \ref{ch:primitives}). An embedded 16-byte
    identifier therefore occupies 20 bytes inside a \texttt{Score}. Decode
    runs the leaf's own validating decoder over the framed region.
  \item[Catalog identifiers.] The \texttt{catalog\_id} newtypes
    (\texttt{PitchSpaceId}, \texttt{TuningSystemId}, \texttt{AccidentalId},
    registry-name ids, \ldots) encode as their stored NFC string under the
    String rule (\texttt{u32} LE length \cat{} UTF-8).
  \item[\texttt{EventArena}.] \texttt{u32} LE event count, then each
    \texttt{Event} in ascending-\texttt{EventId} order (identity travels
    inside each event; the arena adds no per-event framing).
  \item[Validated reconstruction.] Types with checked constructors decode
    through them: \texttt{TupletRatio} rejects degenerate ratios,
    \texttt{KeySignature} encodes its \texttt{fifths()} as \texttt{i8} and
    rejects out-of-range values, \texttt{TimeSignature} re-validates that
    beat groups sum to the measure duration, \texttt{NonZeroU16} rejects
    zero, \texttt{EventOrderingDAG} rejects cyclic edge maps,
    \texttt{ReferencePitch}, \texttt{Tempo}, and
    \texttt{SpellingPrecedence} re-validate their invariants. Structurally
    well-formed bytes that fail a type invariant are a decode error
    (reject-never-normalize).
\end{description}

\section{Discriminant Tables}
\label{sec:values:discriminants}

The complete discriminant assignment for schema major~0. Every table is
governed by Requirement~\ref{req:binfmt:frozen-layout}: an unknown
discriminant is a decode error; changes are gated by
Chapter~\ref{ch:evolution}.

\subsection{C-style enums (one byte, no payload)}

\begingroup\small
\begin{longtable}{p{1.9in} p{3.7in}}
  \toprule
  \textbf{Type} & \textbf{Discriminants} \\
  \midrule
  \endhead
  \texttt{MeasurePosition} & \tablenums{0} Start, \tablenums{1} End \\
  \texttt{RegionEdge} & \tablenums{0} Start, \tablenums{1} End \\
  \texttt{CmnNominal} & \tablenums{0} C, \tablenums{1} D, \tablenums{2} E,
    \tablenums{3} F, \tablenums{4} G, \tablenums{5} A, \tablenums{6} B \\
  \texttt{SpellingSourceKind} & \tablenums{0} UserChosen,
    \tablenums{1} Imported, \tablenums{2} Propagated, \tablenums{3} Inferred,
    \tablenums{4} Analytical \\
  \texttt{TempoShape} & \tablenums{0} Constant, \tablenums{1} Linear,
    \tablenums{2} Exponential, \tablenums{3} Curve \\
  \texttt{StemDirection} & \tablenums{0} Up, \tablenums{1} Down \\
  \texttt{MeasureNumberVisibility} & \tablenums{0} Auto,
    \tablenums{1} Always, \tablenums{2} Never \\
  \texttt{Aleatoric\allowbreak AnchoringDiscipline} & \tablenums{0} Musical,
    \tablenums{1} WallClock, \tablenums{2} EitherPerEvent,
    \tablenums{3} FreelyMixed \\
  \texttt{NoteValue} & \tablenums{0} Whole, \tablenums{1} Half,
    \tablenums{2} Quarter, \tablenums{3} Eighth, \tablenums{4} Sixteenth,
    \tablenums{5} ThirtySecond, \tablenums{6} SixtyFourth \\
  \texttt{ClefShape} & \tablenums{0} G, \tablenums{1} F, \tablenums{2} C,
    \tablenums{3} Percussion \\
  \bottomrule
\end{longtable}
\endgroup

\subsection{Tagged unions (one byte, then the variant payload)}

\begingroup\small
\begin{longtable}{p{1.9in} p{3.7in}}
  \toprule
  \textbf{Type} & \textbf{Discriminants} \\
  \midrule
  \endhead
  \texttt{AnchorOffset} & \tablenums{0} Musical, \tablenums{1} WallClock,
    \tablenums{2} Zero \\
  \texttt{TimeAnchor} & \tablenums{0} Event, \tablenums{1} Measure,
    \tablenums{2} Region, \tablenums{3} WallClock
    (Section~\ref{sec:values:representative}) \\
  \texttt{EventPosition} & \tablenums{0} Musical, \tablenums{1} WallClock \\
  \texttt{ConcreteDuration} & \tablenums{0} Musical, \tablenums{1} WallClock \\
  \texttt{EventDuration} & \tablenums{0} Musical, \tablenums{1} WallClock,
    \tablenums{2} Indeterminate \\
  \texttt{TimeBounds} & \tablenums{0} MusicalRange,
    \tablenums{1} WallClockRange, \tablenums{2} Unbounded \\
  \texttt{PitchSpacePosition} & \tablenums{0} Cmn, \tablenums{1} Integer,
    \tablenums{2} JiVector, \tablenums{3} Registered \\
  \texttt{TuningReference} & \tablenums{0} Inherit, \tablenums{1} Explicit \\
  \texttt{AcousticRealization} & \tablenums{0} Implicit,
    \tablenums{1} CentsOffset, \tablenums{2} AbsoluteHz \\
  \texttt{SpellingNominal} & \tablenums{0} Cmn, \tablenums{1} Integer,
    \tablenums{2} Registered \\
  \texttt{SpellingSource} & \tablenums{0} UserChosen, \tablenums{1} Inferred,
    \tablenums{2} Imported, \tablenums{3} Propagated,
    \tablenums{4} Analytical \\
  \texttt{SpellingScope} & \tablenums{0} Pitch, \tablenums{1} Range \\
  \texttt{SpellingDirective} & \tablenums{0} Explicit, \tablenums{1} Rule \\
  \texttt{VoiceSelector} & \tablenums{0} All, \tablenums{1} Voices \\
  \texttt{GraceKind} & \tablenums{0} Acciaccatura, \tablenums{1} Appoggiatura,
    \tablenums{2} Unmeasured, \tablenums{3} MeasuredFraction \\
  \texttt{IndeterminacyKind} & \tablenums{0} Pitch, \tablenums{1} Duration,
    \tablenums{2} Choice, \tablenums{3} Compound \\
  \texttt{TrajectoryEndpoint} & \tablenums{0} EventPitch,
    \tablenums{1} ExplicitPitch \\
  \texttt{TrajectoryShape} & \tablenums{0} Linear, \tablenums{1} Exponential,
    \tablenums{2} Curve, \tablenums{3} Stepwise \\
  \texttt{Event} & \tablenums{0} Pitched, \tablenums{1} Unpitched,
    \tablenums{2} Rest, \tablenums{3} Indeterminate, \tablenums{4} Trajectory,
    \tablenums{5} Graphic, \tablenums{6} Cue
    (Section~\ref{sec:values:representative}) \\
  \texttt{RegionTimeModel} & \tablenums{0} Metric, \tablenums{1} Proportional,
    \tablenums{2} Aleatoric \\
  \texttt{RegionContent} & \tablenums{0} StaffBased, \tablenums{1} FreeGraphic,
    \tablenums{2} Hybrid \\
  \texttt{VoiceOrigin} & \tablenums{0} UserDeclared, \tablenums{1} Imported,
    \tablenums{2} SystemPromoted \\
  \texttt{StaffGroupKind} & \tablenums{0} GrandStaff, \tablenums{1} Bracket,
    \tablenums{2} SubBracket, \tablenums{3} Choral, \tablenums{4} Registered \\
  \texttt{TieClass} & \tablenums{0} Standard, \tablenums{1} Editorial,
    \tablenums{2} CrossVoice, \tablenums{3} LaissezVibrer,
    \tablenums{4} Registered \\
  \texttt{AnnotationAnchor} & \tablenums{0} Event, \tablenums{1} Range,
    \tablenums{2} Region \\
  \texttt{GestureAnchoring} & \tablenums{0} Events, \tablenums{1} Range,
    \tablenums{2} Free \\
  \texttt{DecompositionSource} & \tablenums{0} UserChosen,
    \tablenums{1} Inferred, \tablenums{2} Imported, \tablenums{3} Propagated \\
  \texttt{TimeSignatureDisplay} & \tablenums{0} Standard,
    \tablenums{1} Compound, \tablenums{2} Irrational,
    \tablenums{3} MixedDenominators, \tablenums{4} None,
    \tablenums{5} Symbolic \\
  \bottomrule
\end{longtable}
\endgroup

\begin{requirement}
\label{req:binfmt:spelling-source-order}
\textbf{The \texttt{SpellingSource} / \texttt{SpellingSourceKind} trap.}
These two vocabularies name the same five provenance concepts but assign
them \emph{different} discriminants: \texttt{SpellingSourceKind} (the
C-style precedence-list element) is \tablenums{0}~UserChosen,
\tablenums{1}~Imported, \tablenums{2}~Propagated, \tablenums{3}~Inferred,
\tablenums{4}~Analytical, while \texttt{SpellingSource} (the payload-carrying
attachment provenance) is \tablenums{0}~UserChosen, \tablenums{1}~Inferred,
\tablenums{2}~Imported, \tablenums{3}~Propagated, \tablenums{4}~Analytical.
The orders differ (\texttt{Inferred} is 3 in one and 1 in the other), both
are golden-locked, and an implementation \MUSTNOT{} share one discriminant
function between them.
\end{requirement}

\section{Representative Complete Layouts}
\label{sec:values:representative}

The following layouts are spelled byte-by-byte both as worked examples of the
composition rules and as normative fact. Recall that inside this chapter's
codec every leaf is framed (\texttt{u32} LE length \cat{} bytes), so an
embedded 16-byte identifier occupies $4+16=20$ bytes.

\subsection{\texttt{RationalTime}}
As a leaf inside a composite: \texttt{u32} LE length \cat{} the canonical
form of Section~\ref{sec:primitives:rationaltime} (sign \cat{}
length-prefixed big-endian numerator magnitude \cat{} length-prefixed
big-endian denominator magnitude).

\subsection{\texttt{TimeAnchor}}
One discriminant byte, then:
\begin{description}
  \item[\tablenums{0} Event] \texttt{id} (\texttt{EventId} leaf, 20) \cat{}
    \texttt{offset} (\texttt{AnchorOffset}: tag byte, then for Musical a
    \texttt{MusicalDuration} leaf, for WallClock a
    \texttt{WallClockDuration} leaf ($4+8=12$), for Zero nothing).
  \item[\tablenums{1} Measure] \texttt{id} (\texttt{MeasureId} leaf, 20)
    \cat{} \texttt{position} (\texttt{MeasurePosition}, 1) \cat{}
    \texttt{offset} (\texttt{AnchorOffset}).
  \item[\tablenums{2} Region] \texttt{id} (\texttt{RegionId} leaf, 20) \cat{}
    \texttt{edge} (\texttt{RegionEdge}, 1) \cat{} \texttt{offset}
    (\texttt{AnchorOffset}).
  \item[\tablenums{3} WallClock] \texttt{time} (\texttt{WallClockTime} leaf,
    12).
\end{description}

\subsection{\texttt{Pitch}}
Positional struct: \texttt{scale\_position} \cat{} \texttt{acoustic}.
\begin{itemize}
  \item \texttt{ScalePosition} = \texttt{space} (\texttt{PitchSpaceId}: NFC
    string, \texttt{u32} LE length \cat{} UTF-8) \cat{} \texttt{position}
    (\texttt{PitchSpacePosition}: tag byte, then Cmn = \texttt{nominal}
    (\texttt{CmnNominal}, 1) \cat{} \texttt{alteration} (\texttt{i8}, 1)
    \cat{} \texttt{octave} (\texttt{i8}, 1); Integer =
    \texttt{space\_size} (\texttt{u16} LE, 2) \cat{} \texttt{index}
    (\texttt{i32} LE, 4); JiVector = \texttt{u32} LE count \cat{} that many
    \texttt{i32} LE components; Registered = a catalog-id string).
  \item \texttt{AcousticPitch} = \texttt{tuning} (\texttt{TuningReference}:
    tag byte; Explicit carries a \texttt{TuningSystemId} catalog-id string)
    \cat{} \texttt{realization} (\texttt{AcousticRealization}: tag byte;
    CentsOffset and AbsoluteHz each carry a \texttt{CanonicalF64} leaf,
    $4+8=12$).
\end{itemize}

\subsection{\texttt{Event}}
One discriminant byte (\tablenums{0}--\tablenums{6}), then the variant struct
positionally. All seven variants share the prefix \texttt{id}
(\texttt{EventId} leaf) \cat{} \texttt{voice} (\texttt{VoiceId} leaf) \cat{}
\texttt{position} (\texttt{EventPosition}) \cat{} \texttt{duration}
(\texttt{EventDuration}); the remaining fields, in order:

\begingroup\small
\begin{longtable}{p{0.35in} p{1.35in} p{3.8in}}
  \toprule
  \textbf{Disc} & \textbf{Variant} & \textbf{Fields after the common prefix} \\
  \midrule
  \endhead
  \tablenums{0} & \texttt{Pitched} &
    \texttt{pitches} \cat{} \texttt{articulations} \cat{} \texttt{dynamic}
    \cat{} \texttt{ornaments} \cat{} \texttt{stem} \cat{} \texttt{grace} \\
  \tablenums{1} & \texttt{Unpitched} &
    \texttt{staff\_position} \cat{} \texttt{instrument\_member} \cat{}
    \texttt{articulations} \cat{} \texttt{dynamic} \cat{} \texttt{stem}
    \cat{} \texttt{grace} \\
  \tablenums{2} & \texttt{Rest} &
    \texttt{vertical\_position} \cat{} \texttt{visible} \\
  \tablenums{3} & \texttt{Indeterminate} &
    \texttt{indeterminacy} \cat{} \texttt{hints} \\
  \tablenums{4} & \texttt{Trajectory} &
    \texttt{start} \cat{} \texttt{end} \cat{} \texttt{shape} \cat{}
    \texttt{display} \\
  \tablenums{5} & \texttt{Graphic} &
    \texttt{graphics} \cat{} \texttt{playback\_bindings} \\
  \tablenums{6} & \texttt{Cue} &
    \texttt{source} \cat{} \texttt{rendering} \\
  \bottomrule
\end{longtable}
\endgroup

Each field encodes under this chapter's rules for its type (vectors are
\texttt{u32}-counted, options carry a presence byte, embedded identifiers are
leaves, unions carry their tag byte).

\subsection{\texttt{Slur}}
Positional struct of three leaves: \texttt{id} (\texttt{SlurId} leaf, 20)
\cat{} \texttt{start\_event} (\texttt{EventId} leaf, 20) \cat{}
\texttt{end\_event} (\texttt{EventId} leaf, 20) --- 60 bytes total.

\section{The \texttt{CanonicalValue} Seam}
\label{sec:values:canonical-value}

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-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},
\texttt{PitchSpelling}, \texttt{Tie}, \texttt{Slur}, \texttt{Beam},
\texttt{Spanner}, \texttt{RegionTimeModel}, \texttt{TimeAnchor},
\texttt{Region}, \texttt{StaffInstance}, \texttt{Voice},
\texttt{DecompositionAttachment}, \texttt{SpellingSourceKind},
\texttt{ScoreMetadata}, \texttt{MetricGrid}, \texttt{Staff},
\texttt{TimeSignature}, \texttt{TempoSegment},
\texttt{StaffLineConfiguration}, \texttt{RepeatStructure}.
\end{quote}

The seam introduces \textbf{no new bytes}: a value's stand-alone canonical
bytes are byte-for-byte the bytes the whole-\texttt{Score} codec embeds for
that value. Stand-alone decode applies the same validation and rejects
trailing bytes.

\section{The Frozen-Layout Rule}
\label{sec:values:frozen}

\begin{requirement}
\label{req:binfmt:frozen-layout}
\textbf{Frozen positional layouts (the schema-evolution keystone).} Within
schema major~0, every positional struct layout in this chapter is
\textbf{frozen}: there is no field-addition mechanism at the value level ---
no per-field framing, no optional-field encoding, no trailing-field
tolerance. Any change to any struct's field \emph{set} or field \emph{order}
is a schema-\textsc{major} change and requires a documented migration in this
document's revision history (Chapter~\ref{ch:evolution}).

Appending a \emph{new variant} to an \textbf{open} discriminant vocabulary is
a schema-\textsc{minor} change under the rules of
Chapter~\ref{ch:evolution}. At the value layer, the open vocabularies are
those with a \texttt{Registered} escape variant ---
\texttt{PitchSpacePosition}, \texttt{SpellingNominal},
\texttt{StaffGroupKind}, \texttt{TieClass} --- through which extensions
attach without any wire change at all; every \emph{other} union in
Section~\ref{sec:values:discriminants} (including \texttt{Event},
\texttt{TimeAnchor}, \texttt{TimeSignatureDisplay}) is closed in v0 and may
grow only by an append ratified in a revision of this document.

This rule ratifies the project's staging decision that data-model payload
expansion --- \texttt{SlurKind}, beam geometry, voltas, instrument bodies,
score-metadata growth, and their kin --- lands as a coordinated
schema-\textsc{major} revision of this document, not as ad-hoc field
insertion.
\end{requirement}

% ===========================================================================
\chapter{Operation Wire Forms}
\label{ch:ops}

This chapter pins the operation layer: envelopes, payloads, stamps, causal
contexts, effects, and materialized state. It \textbf{ratifies} the
encodings the ops crate's \texttt{DECISIONS} record held as ``provisional
canonical encoding'' (mirroring core P11-4); that provisional status is
discharged.

Regime (a) applies, with one composition difference from
Chapter~\ref{ch:values}: the operation layer embeds \emph{fixed-width}
canonical leaves (identifiers, hashes, \texttt{ConflictId}) \textbf{raw},
without a length prefix (\texttt{push\_canon}); only variable-width parts
carry \texttt{u32} LE length prefixes (\texttt{push\_lp\_bytes}). Sequences
(\texttt{push\_seq}) are a \texttt{u32} LE count, then each element
individually length-prefixed (\texttt{u32} LE), regardless of element width.
Text (\texttt{push\_str}) is NFC-normalized at encode time, then
length-prefixed UTF-8. Embedded graph values are the
\texttt{CanonicalValue} bytes of Section~\ref{sec:values:canonical-value},
framed by a \texttt{u32} LE length prefix (Operation Catalog requirement
\texttt{req:catalog:value-encoding}).

\section{The Operation Envelope}
\label{sec:ops:envelope}

\begin{requirement}
\label{req:binfmt:envelope}
An \texttt{OperationEnvelope}'s canonical bytes are, in order:

\begin{center}
\begin{tabular}{p{1.35in} p{3.9in}}
  \toprule
  \textbf{Field} & \textbf{Encoding} \\
  \midrule
  \texttt{id} & \texttt{OperationId}, 16 big-endian bytes, raw \\
  \texttt{author} & \texttt{AuthorId}, 16 big-endian bytes, raw \\
  \texttt{stamp} & \texttt{OperationStamp}, 28 bytes
    (Section~\ref{sec:ops:stamp}) \\
  \texttt{causal\_context} & \texttt{CausalContext}
    (Section~\ref{sec:ops:causal}) \\
  \texttt{transaction} & option tag byte (\tablenums{0} absent /
    \tablenums{1} present), then \texttt{TransactionId} 16 BE if present \\
  \texttt{payload} & \texttt{OperationPayload}
    (Section~\ref{sec:ops:payload}) \\
  \bottomrule
\end{tabular}
\end{center}

\textbf{Id-leads property.} The envelope's first 16 bytes \emph{are} the
\texttt{OperationId}'s canonical bytes. This is load-bearing: the operation
index (Chapter~\ref{ch:bundle}, Section~\ref{sec:bundle:opindex}) keys its
entries on those leading 16 bytes without decoding envelopes, and the
sanctioned partial read (\emph{peek}) of an envelope is exactly its leading
16 bytes. Any future envelope revision \MUST{} preserve id-leads or revise
the operation index in the same schema-major step.
\end{requirement}

$\texttt{EnvelopeHash} = \mathrm{BLAKE3}(\texttt{MUSCENVH} \cat
\mathit{envelope\ canonical\ bytes})$ --- the full 32-byte digest.

Envelopes are \textbf{encode-only} at this layer, deliberately: once
committed, an envelope is stored and transported as opaque bytes and is
never reconstructed into typed form by the storage layer; the peek above is
the only sanctioned partial read. (Reducers decode payloads they authored or
received through the ops layer's own typed surface; the wire contract is
that stored envelope bytes are preserved verbatim, since
\texttt{EnvelopeHash} commits to them.)

\section{\texttt{OperationPayload} and the Meta-Operations}
\label{sec:ops:payload}

\texttt{OperationPayload}: one discriminant byte, then the variant.

\begin{center}
\small
\begin{tabular}{p{0.35in} p{1.55in} p{3.3in}}
  \toprule
  \textbf{Disc} & \textbf{Variant} & \textbf{Payload} \\
  \midrule
  \tablenums{0} & \texttt{Primitive} & an \texttt{OperationKind}
    (Section~\ref{sec:ops:kinds}) \\
  \tablenums{1} & \texttt{ResolveConflict} & \texttt{target}
    (\texttt{ConflictId}, 16 BE) \cat{} \texttt{action}
    (\texttt{ResolutionAction}) \\
  \tablenums{2} & \texttt{UndoTransaction} & \texttt{target}
    (\texttt{TransactionId}, 16 BE) \cat{} \texttt{policy}
    (\texttt{UndoPolicy}, 1 byte) \\
  \tablenums{3} & \texttt{ResolveEquivocation} & \texttt{target}
    (\texttt{OperationId}, 16 BE) \cat{} \texttt{chosen}
    (\texttt{EnvelopeHash}, 32) \\
  \bottomrule
\end{tabular}
\end{center}

Discriminants \tablenums{0}--\tablenums{2} are the ratified v1 values;
\tablenums{3} was appended by the catalog's \sectionsc{ResolveEquivocation
(meta-operation)} entry. The vocabulary is append-only: new meta-operations
take $\geq 4$.

\texttt{UndoPolicy} is one byte: \tablenums{0} StrictInverse,
\tablenums{1} BestEffort, \tablenums{2} Cascade.
\texttt{ResolutionAction} is one byte then an optional payload
(\texttt{app:bytes}, core requirement
\texttt{req:semops:\allowbreak resolution-action-discriminants}): \tablenums{0}
AcceptLoser, \tablenums{1} KeepWinner, \tablenums{2} Override
(\cat{} \texttt{OperationId} 16 BE), \tablenums{3} Reanchor (\cat{}
\texttt{TypedObjectId}), \tablenums{4} Dismiss, \tablenums{5} Registered
(\cat{} \texttt{ResolutionRegistryId} 16 BE).

\section{\texttt{OperationKind}: the Primitive Wire Discriminants}
\label{sec:ops:kinds}

\begin{requirement}
\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{29}; the assignments below never change.
\end{requirement}

Each row also pins the payload's byte layout; the field \emph{set and order}
is the Operation Catalog's (the cited section governs semantics).
``$\mathrm{lp}(T)$'' means the \texttt{u32}-LE-length-prefixed
\texttt{CanonicalValue} bytes of a \texttt{T}
(Section~\ref{sec:values:canonical-value}); bare identifiers are raw 16
big-endian bytes; ``$\mathrm{seq}^{\uparrow}$'' is a \texttt{push\_seq}
sequence sorted ascending by canonical bytes, and
``$\mathrm{seq}^{\Uparrow}$'' is the same sequence constrained to be
\emph{strictly} increasing --- a set, not a multiset. A decoder \MUST{}
reject a $\mathrm{seq}^{\Uparrow}$ containing a duplicate rather than
normalize it away, since the duplicate is the only evidence that the writer
and the reader disagree about the field's type.

\begingroup\footnotesize
\begin{longtable}{p{0.32in} >{\raggedright\arraybackslash}p{1.5in} >{\raggedright\arraybackslash}p{2.35in} >{\raggedright\arraybackslash}p{1.35in}}
  \toprule
  \textbf{Disc} & \textbf{Kind} & \textbf{Payload layout} &
    \textbf{Catalog section} \\
  \midrule
  \endhead
  \tablenums{0} & \texttt{InsertEvent} &
    \texttt{staff\_instance} (16) \cat{} $\mathrm{lp}$(\texttt{Event}) &
    \sectionsc{InsertEvent} \\
  \tablenums{1} & \texttt{DeleteEvent} &
    \texttt{event} (16) \cat{} \texttt{TupletCompensation} &
    \sectionsc{DeleteEvent} \\
  \tablenums{2} & \texttt{RespellPitch} &
    \texttt{pitch} (16) \cat{} $\mathrm{lp}$(\texttt{PitchSpelling}) &
    \sectionsc{RespellPitch} \\
  \tablenums{3} & \texttt{CreateCrossCutting} &
    \texttt{CrossCuttingValue} &
    \sectionsc{CreateCrossCutting} \\
  \tablenums{4} & \texttt{ChangeRegionTimeModel} &
    \texttt{region} (16) \cat{} $\mathrm{lp}$(\texttt{RegionTimeModel})
    \cat{} $\mathrm{seq}^{\uparrow}$(\texttt{EventId}) \cat{}
    \texttt{PositionRemapping} &
    \sectionsc{ChangeRegion\allowbreak TimeModel} \\
  \tablenums{5} & \texttt{SetUserSystemBreak} &
    \texttt{region} (16) \cat{} $\mathrm{lp}$(\texttt{TimeAnchor}) \cat{}
    \texttt{present} (bool, 1) &
    \sectionsc{SetUserSystemBreak} \\
  \tablenums{6} & \texttt{DeclareTransaction} &
    \texttt{id} (16) \cat{} \texttt{label} (NFC string) \cat{} option tag
    \cat{} \texttt{TransactionCategory} if present &
    \sectionsc{DeclareTransaction} \\
  \tablenums{7} & \texttt{Registered} &
    \texttt{OperationKindRegistryId} (16) \cat{}
    $\mathrm{lp}$(opaque bytes) &
    \sectionsc{K1 --- Framework Slots} \\
  \tablenums{8} & \texttt{ModifyEvent} &
    $\mathrm{lp}$(\texttt{Event}) &
    \sectionsc{ModifyEvent} \\
  \tablenums{9} & \texttt{Transpose} &
    $\mathrm{seq}^{\uparrow}$(\texttt{PitchId}) \cat{}
    \texttt{chromatic\_steps} (\texttt{i32} LE, 4). Frozen: the sequence is a
    multiset, \emph{not} $\mathrm{seq}^{\Uparrow}$ &
    \sectionsc{Transpose} \\
  \tablenums{10} & \texttt{InsertIdentifiedPitch} &
    \texttt{event} (16) \cat{} $\mathrm{lp}$(\texttt{IdentifiedPitch}) &
    \sectionsc{Identified-Pitch Operations} \\
  \tablenums{11} & \texttt{DeleteIdentifiedPitch} &
    \texttt{pitch} (16) &
    \sectionsc{Identified-Pitch Operations} \\
  \tablenums{12} & \texttt{ModifyIdentifiedPitch} &
    \texttt{pitch} (16) \cat{} $\mathrm{lp}$(\texttt{Pitch}) &
    \sectionsc{Identified-Pitch Operations} \\
  \tablenums{13} & \texttt{DeleteCrossCutting} &
    \texttt{structure} (\texttt{TypedObjectId}, 18/34) &
    \sectionsc{DeleteCrossCutting} \\
  \tablenums{14} & \texttt{ModifyCrossCutting} &
    \texttt{CrossCuttingValue} &
    \sectionsc{ModifyCrossCutting} \\
  \tablenums{15} & \texttt{CreateRegion} &
    $\mathrm{lp}$(\texttt{Region}) &
    \sectionsc{Structural Containers} \\
  \tablenums{16} & \texttt{DeleteRegion} &
    \texttt{region} (16) &
    \sectionsc{Structural Containers} \\
  \tablenums{17} & \texttt{CreateStaffInstance} &
    \texttt{region} (16) \cat{} $\mathrm{lp}$(\texttt{StaffInstance}) &
    \sectionsc{Structural Containers} \\
  \tablenums{18} & \texttt{DeleteStaffInstance} &
    \texttt{staff\_instance} (16) &
    \sectionsc{Structural Containers} \\
  \tablenums{19} & \texttt{CreateVoice} &
    \texttt{staff\_instance} (16) \cat{} $\mathrm{lp}$(\texttt{Voice}) &
    \sectionsc{Structural Containers} \\
  \tablenums{20} & \texttt{DeleteVoice} &
    \texttt{voice} (16) &
    \sectionsc{Structural Containers} \\
  \tablenums{21} & \texttt{SetMetadata} &
    $\mathrm{lp}$(\texttt{ScoreMetadata}) &
    \sectionsc{Score Settings} \\
  \tablenums{22} & \texttt{SetMetricGrid} &
    \texttt{region} (16) \cat{} option tag (\tablenums{0}/\tablenums{1})
    \cat{} $\mathrm{lp}$(\texttt{MetricGrid}) if present &
    \sectionsc{Score Settings} \\
  \tablenums{23} & \texttt{SetUserPageBreak} &
    \texttt{region} (16) \cat{} $\mathrm{lp}$(\texttt{TimeAnchor}) \cat{}
    \texttt{present} (bool, 1) &
    \sectionsc{Score Settings} \\
  \tablenums{24} & \texttt{CreateStaff} &
    $\mathrm{lp}$(\texttt{Staff}) &
    \sectionsc{CreateStaff} \\
  \tablenums{25} & \texttt{SetTimeSignature} &
    \texttt{region} (16) \cat{} $\mathrm{lp}$(\texttt{TimeAnchor}) \cat{}
    option tag (\tablenums{0}/\tablenums{1}) \cat{}
    $\mathrm{lp}$(\texttt{TimeSignature}) if present &
    \sectionsc{Meter and Tempo Overwrites} \\
  \tablenums{26} & \texttt{SetTempoSegment} &
    option tag \cat{} \texttt{region} (16) if present \cat{}
    $\mathrm{lp}$(\texttt{TimeAnchor}) \cat{} option tag \cat{}
    $\mathrm{lp}$(\texttt{TempoSegment}) if present &
    \sectionsc{Meter and Tempo Overwrites} \\
  \tablenums{27} & \texttt{SetStaffLayout} &
    \texttt{staff\_instance} (16) \cat{} option tag \cat{}
    \texttt{instrument\_override} (16) if present \cat{} option tag \cat{}
    $\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} \\
  \tablenums{30} & \texttt{TransposeInterval} &
    $\mathrm{seq}^{\Uparrow}$(\texttt{PitchId}) \cat{}
    \texttt{diatonic\_steps} (\texttt{i32} LE, 4) \cat{}
    \texttt{chromatic\_steps} (\texttt{i32} LE, 4) &
    \sectionsc{TransposeInterval} \\
  \tablenums{31} & \texttt{CreateInstrument} &
    $\mathrm{lp}$(\texttt{Instrument}) --- the schema-major-2 layout,
    unconditionally (born at v2; Section~\ref{sec:evolution:major2}) &
    \sectionsc{CreateInstrument} \\
  \tablenums{32} & \texttt{SetCanvasLayoutDefaults} &
    $\mathrm{lp}$(\texttt{CanvasLayoutDefaults}) &
    \sectionsc{SetCanvasLayoutDefaults} \\
  \tablenums{33} & \texttt{SetSpellingPrecedence} &
    $\mathrm{lp}$(\texttt{SpellingPrecedence}) &
    \sectionsc{SetSpellingPrecedence} \\
  \tablenums{34} & \texttt{SetTuningContext} &
    $\mathrm{lp}$(\texttt{TuningContextSettings}) --- the \textbf{authored
    subset} of \texttt{ScoreTuningContext}: exactly its five wire-bearing
    fields, in the same order, byte-identical to the schema-major-3
    \texttt{ScoreTuningContext} layout (Section~\ref{sec:evolution:major3});
    born at v3 unconditionally &
    \sectionsc{SetTuningContext} \\
  \tablenums{35} & \texttt{CreateStaffGroup} &
    $\mathrm{lp}$(\texttt{StaffGroup}) &
    \sectionsc{CreateStaffGroup} \\
  \tablenums{36} & \texttt{CreatePartDefinition} &
    $\mathrm{lp}$(\texttt{PartDefinition}) &
    \sectionsc{CreatePartDefinition} \\
  \tablenums{37} & \texttt{CreateAnalysisLayer} &
    $\mathrm{lp}$(\texttt{AnalysisLayer}) &
    \sectionsc{CreateAnalysisLayer} \\
  \tablenums{38} & \texttt{CreateView} &
    $\mathrm{lp}$(\texttt{ViewDefinition}) &
    \sectionsc{CreateView} \\
  \tablenums{39} & \texttt{CreateMeasure} &
    \texttt{instance} (16) \cat{} $\mathrm{lp}$(\texttt{Measure}) &
    \sectionsc{CreateMeasure} \\
  \bottomrule
\end{longtable}
\endgroup

Sub-vocabularies used above (one discriminant byte, then the listed
payload):

\begin{description}
  \item[\texttt{TupletCompensation}.] \tablenums{0} NotInTuplet (empty);
    \tablenums{1} ReplaceWithRest \cat{} $\mathrm{lp}$(\texttt{Rest});
    \tablenums{2} RewriteTuplets \cat{}
    $\mathrm{seq}^{\uparrow}$(\texttt{TupletId});
    \tablenums{3} CascadeDeleteTuplets \cat{}
    $\mathrm{seq}^{\uparrow}$(\texttt{TupletId}).
  \item[\texttt{CrossCuttingValue}.] \tablenums{0} Tie, \tablenums{1} Slur,
    \tablenums{2} Beam, \tablenums{3} Spanner; in every case the tag is
    followed by $\mathrm{lp}$(the typed structure's \texttt{CanonicalValue}
    bytes).
  \item[\texttt{PositionRemapping}.] \tablenums{0} PreserveTime (empty);
    \tablenums{1} Reassign \cat{} \texttt{u32} LE entry count \cat{}
    entries, each \texttt{EventId} (16, raw) \cat{}
    $\mathrm{lp}$(\texttt{MusicalPosition}), ascending by \texttt{EventId}.
  \item[\texttt{TransactionCategory}.] \tablenums{0} NoteEntry,
    \tablenums{1} Structural, \tablenums{2} Layout, \tablenums{3} Import,
    \tablenums{4} Registered \cat{} \texttt{OperationKindRegistryId} (16 BE)
    --- governed by \texttt{app:bytes} (core requirement
    \texttt{req:semops:transaction-category}).
\end{description}

\texttt{OperationKind} is encode-only at the storage boundary, like the
envelope that carries it.

\section{\texttt{OperationKindTag}: a Separate Discriminant Space}
\label{sec:ops:kind-tag}

\begin{requirement}
\label{req:binfmt:kind-tag}
\texttt{OperationKindTag} --- the payload-free projection of an operation
kind, stored by edit barriers
(Chapter~\ref{ch:barriers}) --- has its \textbf{own} discriminant space,
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{29}.
\end{requirement}

\begingroup\small
\begin{longtable}{p{0.5in} p{2.0in} p{0.5in} p{2.0in}}
  \toprule
  \textbf{Disc} & \textbf{Tag} & \textbf{Disc} & \textbf{Tag} \\
  \midrule
  \endhead
  \tablenums{0} & \texttt{InsertEvent} & \tablenums{12} & \texttt{DeleteStaffInstance} \\
  \tablenums{1} & \texttt{DeleteEvent} & \tablenums{13} & \texttt{SetUserSystemBreak} \\
  \tablenums{2} & \texttt{ModifyEvent} & \tablenums{14} & \texttt{SetUserPageBreak} \\
  \tablenums{3} & \texttt{RespellPitch} & \tablenums{15} & \texttt{DeclareTransaction} \\
  \tablenums{4} & \texttt{Transpose} & \tablenums{16} & \texttt{Registered} \\
  \tablenums{5} & \texttt{CreateCrossCutting} & \tablenums{17} & \texttt{InsertIdentifiedPitch} \\
  \tablenums{6} & \texttt{DeleteCrossCutting} & \tablenums{18} & \texttt{DeleteIdentifiedPitch} \\
  \tablenums{7} & \texttt{ModifyCrossCutting} & \tablenums{19} & \texttt{ModifyIdentifiedPitch} \\
  \tablenums{8} & \texttt{ChangeRegionTimeModel} & \tablenums{20} & \texttt{CreateVoice} \\
  \tablenums{9} & \texttt{InsertRegion} & \tablenums{21} & \texttt{DeleteVoice} \\
  \tablenums{10} & \texttt{DeleteRegion} & \tablenums{22} & \texttt{SetMetadata} \\
  \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} \\
  \tablenums{30} & \texttt{TransposeInterval} & \tablenums{31} & \texttt{CreateInstrument} \\
  \tablenums{32} & \texttt{SetCanvasLayoutDefaults} & \tablenums{33} & \texttt{SetSpellingPrecedence} \\
  \tablenums{34} & \texttt{SetTuningContext} & \tablenums{35} & \texttt{CreateStaffGroup} \\
  \tablenums{36} & \texttt{CreatePartDefinition} & \tablenums{37} & \texttt{CreateAnalysisLayer} \\
  \tablenums{38} & \texttt{CreateView} & \tablenums{39} & \texttt{CreateMeasure} \\
  \bottomrule
\end{longtable}
\endgroup

\textbf{Naming mapping.} The kind-to-tag projection renames three pairs:
\texttt{OperationKind::\allowbreak CreateRegion} projects to
\texttt{OperationKindTag::\allowbreak InsertRegion}, and
\texttt{OperationKind::\allowbreak CreateStaffInstance} projects to
\texttt{OperationKindTag::\allowbreak InsertStaffInstance}, and
\texttt{OperationKind::\allowbreak CreateStaff} projects to
\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. 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}

\texttt{HybridLogicalClock}: \texttt{physical\_time} (\texttt{WallClockTime},
\texttt{i64} LE, 8) \cat{} \texttt{logical\_counter} (\texttt{u32} LE, 4).
\texttt{OperationStamp}: \texttt{hlc} (12) \cat{} \texttt{id}
(\texttt{OperationId}, 16 BE) --- \textbf{28 bytes} total, fixed width. The
canonical reduction tuple orders stamps as $(\mathit{physical\_time},
\mathit{logical\_counter}, \mathit{replica}, \mathit{counter})$, ascending;
the replica comparison equals big-endian byte order.

\label{sec:ops:causal}
\texttt{CausalContext} (dotted version vector):

\begin{center}
\begin{tabular}{p{0.7in} p{4.55in}}
  \toprule
  \textbf{Field} & \textbf{Encoding} \\
  \midrule
  vector & \texttt{u32} LE entry count \cat{} entries, each
    \texttt{replica} (8 BE) \cat{} \texttt{counter} (\texttt{u64} LE, 8),
    ascending by replica \\
  dots & \texttt{u32} LE count \cat{} \texttt{OperationId}s (16 BE each),
    ascending \\
  \bottomrule
\end{tabular}
\end{center}

The vector is \emph{zero-based-floor} (P11-C7): an entry $(r, c)$ covers
counters $0..=c$ of replica $r$; absence of a replica covers nothing.

\section{Effects, Conflicts, Anomalies, and Materialized State}
\label{sec:ops:effects}

These types are canonical \emph{materialized} facts: they appear in
\texttt{MaterializedState}'s canonical bytes, so their discriminants and
layouts are normative wire facts even though they are never stored inside
envelopes. All decode validation is performed by the ops layer's validating
decoder; unknown discriminants, bad lengths, non-canonical orders, and
trailing bytes are decode errors.

\begingroup\footnotesize
\begin{longtable}{>{\raggedright\arraybackslash}p{1.6in} p{4.1in}}
  \toprule
  \textbf{Type} & \textbf{Layout (tag byte, then payload)} \\
  \midrule
  \endhead
  \texttt{OperationEffect} &
    \tablenums{0} Applied (empty);
    \tablenums{1} AppliedWithRepair \cat{} seq(\texttt{RepairRecord});
    \tablenums{2} Conflicted \cat{} \texttt{ConflictId} (16 BE);
    \tablenums{3} TombstonedTarget \cat{} \texttt{TypedObjectId};
    \tablenums{4} NoOp \cat{} \texttt{NoOpReason}. \\
  \texttt{NoOpReason} &
    \tablenums{0} TargetTombstoned; \tablenums{1} AlreadyApplied;
    \tablenums{2} SupersededByLaterOperation \cat{} \texttt{OperationId}
    (16 BE); \tablenums{3} PreconditionFailedUnderReduction \cat{}
    \texttt{PreconditionFailureReason}; \tablenums{4} TransactionConflict. \\
  \texttt{Precondition\allowbreak FailureReason} &
    \tablenums{0} TargetMissing; \tablenums{1} TargetTombstoned;
    \tablenums{2} WrongRegionTimeModel;
    \tablenums{3} TupletCompensationInvalid;
    \tablenums{4} EventDurationInvalid; \tablenums{5} PositionOutsideRegion;
    \tablenums{6} PitchSpaceMismatch; \tablenums{7} VoiceMissing;
    \tablenums{8} ExtensionPrecondition \cat{} id (16 BE);
    \tablenums{9} Registered \cat{} id (16 BE);
    \tablenums{10} ContainerNotEmpty;
    \tablenums{11} TempoMapMalformed;
    \tablenums{12} SystemDerivedContentImmutable (Pass~12, P12-K3);
    \tablenums{13} RecreateContentMismatch (Pass~12, P12-K9);
    \tablenums{14} AcousticRealizationPinned;
    \tablenums{15} TranspositionOutOfRange (both Push~4a);
    \tablenums{16} MeasureMeterMismatch, \tablenums{17} MeasureOutOfOrder,
    \tablenums{18} MeasureOrderUnverifiable (genesis tranche G3b). \\
  \texttt{RepairRecord} &
    (struct) \texttt{kind} (\texttt{RepairKind}) \cat{} \texttt{target}
    (\texttt{TypedObjectId}). \\
  \texttt{RepairKind} &
    \tablenums{0} Reanchored \cat{} \texttt{from} (\texttt{TypedObjectId})
    \cat{} \texttt{to} (\texttt{TypedObjectId}) \cat{}
    \texttt{ReanchorReason};
    \tablenums{1} SpannerTruncated \cat{} seq(\texttt{TypedObjectId});
    \tablenums{2} Orphaned; \tablenums{3} CascadeDeleted;
    \tablenums{4} AttachmentTombstoned;
    \tablenums{5} VoicePromoted \cat{} \texttt{from} (\texttt{VoiceId},
    16 BE) \cat{} \texttt{to} (\texttt{VoiceId}, 16 BE);
    \tablenums{6} TupletCompensated \cat{} \texttt{TupletCompensationKind};
    \tablenums{7} Registered \cat{} id (16 BE). \\
  \texttt{ReanchorReason} &
    \tablenums{0} SameVoiceNearer; \tablenums{1} SameStaffInstanceNearer;
    \tablenums{2} SameStaffNearer; \tablenums{3} SameRegionNearer;
    \tablenums{4} ExplicitFallback;
    \tablenums{5} DeclaredByExtension \cat{} id (16 BE);
    \tablenums{6} SameCanvasNearer (Pass~12, P12-C4: semantically the
    rank-4 proximity variant; appended at 6 because 5 was already
    owned by DeclaredByExtension). \\
  \texttt{TupletCompensationKind} &
    \tablenums{0} ReplaceWithRest; \tablenums{1} RewriteTuplets;
    \tablenums{2} CascadeDeleteTuplets. (No payload; distinct from the
    payload-carrying \texttt{TupletCompensation} of
    Section~\ref{sec:ops:kinds}.) \\
  \texttt{PendingReason} &
    tag \cat{} blocker (\texttt{OperationId}, 16 BE) in every variant:
    \tablenums{0} MissingCausalPredecessor; \tablenums{1}
    DependsOnEquivocated; \tablenums{2} DependsOnExcluded;
    \tablenums{3} DependsOnPending; \tablenums{4} HaltedBySystemCollision. \\
  \texttt{ConflictKind} &
    \tablenums{0} StructuralFieldCollision \cat{} \texttt{winner} (16 BE)
    \cat{} \texttt{loser} (16 BE) \cat{} \texttt{FieldPath} (NFC string);
    \tablenums{1} TransactionConflict \cat{} \texttt{transaction} (16 BE)
    \cat{} $\mathrm{seq}^{\uparrow}$(\texttt{OperationId});
    \tablenums{2} TombstonedTarget \cat{} \texttt{TypedObjectId} \cat{}
    \texttt{OperationId} (16 BE);
    \tablenums{3} ReanchorFailure \cat{} \texttt{original\_referent}
    (\texttt{TypedObjectId}) \cat{} \texttt{referencing\_object}
    (\texttt{TypedObjectId});
    \tablenums{4} TimeModelMigrationFailure \cat{} \texttt{region} (16 BE)
    \cat{} $\mathrm{seq}^{\uparrow}$(\texttt{TypedObjectId});
    \tablenums{5} ExtensionConflict \cat{} \texttt{kind\_id} (16 BE) \cat{}
    $\mathrm{lp}$(opaque details). \\
  \texttt{ConflictResolutionState} &
    \tablenums{0} Unresolved; \tablenums{1} Resolved \cat{} \texttt{by}
    (16 BE) \cat{} \texttt{ResolutionAction}; \tablenums{2} Dismissed \cat{}
    \texttt{by} (16 BE). \\
  \texttt{ConflictRecord} &
    (struct) \texttt{id} (\texttt{ConflictId}, 16 BE) \cat{}
    seq(\texttt{caused\_by}: \texttt{OperationId}, stored sorted) \cat{}
    \texttt{kind} \cat{} seq(\texttt{affected\_objects}:
    \texttt{TypedObjectId}, stored sorted) \cat{}
    \texttt{resolution\_state}. \\
  \texttt{IntegrityAnomaly} &
    (struct) \texttt{id} (\texttt{IntegrityAnomalyId}, 16 BE) \cat{}
    \texttt{kind}. \\
  \texttt{IntegrityAnomalyKind} &
    \tablenums{0} SystemIdentifierCollision \cat{} \texttt{ObjectKind}
    \cat{} \texttt{colliding\_counter} (\texttt{u64} LE) \cat{} the two
    input-set blobs, each $\mathrm{lp}$(bytes), emitted lo${}\leq{}$hi by
    byte comparison;
    \tablenums{1} OperationSlotEquivocated \cat{} \texttt{OperationId}
    (16 BE);
    \tablenums{2} ReplicaStreamQuarantined \cat{} \texttt{replica} (8 BE)
    \cat{} \texttt{first\_bad\_counter} (\texttt{u64} LE);
    \tablenums{3} Registered \cat{} id (16 BE). \\
  \texttt{AnomalousReplicaSegment} &
    (struct) \texttt{replica} (8 BE) \cat{} \texttt{first\_bad\_counter}
    (\texttt{u64} LE) \cat{} \texttt{ReplicaAnomalyReason}
    (\tablenums{0} HlcMonotonicityViolation \cat{} two
    \texttt{OperationId}s; \tablenums{1} Registered \cat{} id 16 BE)
    \cat{} seq(\texttt{excluded}: \texttt{OperationId}, ascending counter). \\
  \texttt{FieldPath} &
    an NFC string (\texttt{u32} LE length \cat{} UTF-8). \\
  \texttt{ObjectState} &
    \tablenums{0} Live (empty); \tablenums{1} Tombstoned \cat{}
    \texttt{deleted\_by} (\texttt{OperationId}, 16 BE) \cat{}
    \texttt{minted\_by} (\texttt{OperationId}, 16 BE). \\
  \texttt{ObjectKind} (ops) &
    \tablenums{0} Voice; \tablenums{1} Pitch; \tablenums{2} Registered
    \cat{} \texttt{OperationKindRegistryId} (16 BE) --- governed by
    \texttt{app:bytes} (core requirement
    \texttt{req:graph:object-kind-vocab}). Distinct from the barrier layer's
    2-byte \texttt{ObjectKind} (Chapter~\ref{ch:barriers}). \\
  \bottomrule
\end{longtable}
\endgroup

\subsection{\texttt{MaterializedState}}
\label{sec:ops:materialized}

The canonical bytes of a reduction's materialized state are eight sections,
concatenated; every section is \texttt{u32}-LE-counted (the conflict
registry carries its own count) and in the stated normative order, so the
bytes are identical across any permutation of the input operation set:

\begin{enumerate}
  \item \textbf{effects} --- count, then per entry \texttt{OperationId}
    (16 BE, raw) \cat{} $\mathrm{lp}$(\texttt{OperationEffect}); in
    canonical reduction order;
  \item \textbf{conflict registry} --- a seq of
    $\mathrm{lp}$(\texttt{ConflictRecord}), ascending \texttt{ConflictId};
  \item \textbf{anomalies} --- count, then each
    $\mathrm{lp}$(\texttt{IntegrityAnomaly}), ascending
    \texttt{IntegrityAnomalyId};
  \item \textbf{objects} --- count, then per entry \texttt{TypedObjectId}
    (raw) \cat{} \texttt{ObjectState}, ascending \texttt{TypedObjectId};
  \item \textbf{spellings} --- count, then per entry \texttt{PitchId}
    (16 BE, raw) \cat{} $\mathrm{lp}$(\texttt{PitchSpelling}), ascending
    \texttt{PitchId};
  \item \textbf{breaks} --- count, then per entry \texttt{RegionId}
    (16 BE, raw) \cat{} \texttt{MusicalPosition} (raw \texttt{RationalTime}
    form, self-describing, \emph{not} leaf-framed) \cat{} \texttt{present}
    (bool, 1); ascending $(\mathit{region}, \mathit{position})$;
  \item \textbf{page breaks} --- same shape and order as breaks;
  \item \textbf{pending} --- count, then per entry \texttt{OperationId}
    (16 BE, raw) \cat{} \texttt{PendingReason}, ascending
    \texttt{OperationId}.
\end{enumerate}

Decode is fully validating (orders, tags, lengths, trailing bytes) and
rejects non-canonical input.

\section{v0 Payloads Have No Wire Form}
\label{sec:ops:v0}

The prototype's v0 identifier-projection payload types are an
\textbf{in-memory migration guard only}: they carry no canonical encoding,
and no v0 wire form was ever shipped. The v0${\to}$v1 migration is
\emph{semantic} --- typed value reconstruction, specified in the Operation
Catalog's \sectionsc{v0 $\rightarrow$ v1 Payload Migration} chapter --- not a
byte-level translation, and nothing in this document defines bytes for a v0
payload.

% ===========================================================================
\chapter{Bundle Physical Layout}
\label{ch:bundle}

The physical file: the fixed prelude, chunks, blocks, the manifest, and the
operation index. This chapter \textbf{ratifies} the bundle crate's
provisional encodings (its \texttt{DECISIONS} entries P11-D2, P11-D4, and
P11-D5 pending-companion status is discharged) and the operation-index
byte form (P12-D1). Structural \emph{semantics} --- superblock selection,
commit protocol, recovery, retention --- are core specification Chapter~8;
this chapter pins bytes only. Regime (a) applies except where a table says
otherwise.

\section{The Fixed Header (64 bytes)}
\label{sec:bundle:header}

Offset 0 of every bundle. Written at creation, never rewritten within a
format major version. All integers little-endian.

\begingroup\small
\begin{longtable}{p{0.8in} p{1.7in} p{3.1in}}
  \toprule
  \textbf{Range} & \textbf{Field} & \textbf{Value / rule} \\
  \midrule
  \endhead
  \tablenums{0..8} & magic & \texttt{MUSCBND\textbackslash0} (8 bytes, ASCII,
    trailing NUL) \\
  \tablenums{8..10} & \texttt{format\_major} (\texttt{u16}) & \tablenums{1}
    written in this version. The container \emph{epoch}: a major-1
    container is one whose every base-bearing commit was validated
    against a supplied reduction authority. \tablenums{0} is
    \emph{legacy} and \MUST{} be decoded deliberately as such, not
    rejected; any other value is rejected. A legacy container \MAY{}
    be opened only while it carries no canonical base, and \MUSTNOT{}
    acquire one --- the epoch is fixed at creation and cannot be
    inherited by a later commit (Core Specification,
    \sectionsc{The Container Epoch}) \\
  \tablenums{10..12} & \texttt{format\_minor} (\texttt{u16}) & \tablenums{0}
    written in this version; minor numbering restarts at a new major \\
  \tablenums{12..16} & \texttt{header\_length} (\texttt{u32}) &
    \tablenums{64}; readers reject other values \\
  \tablenums{16..24} & \texttt{superblock\_a\_offset} (\texttt{u64}) &
    \tablenums{64}; readers reject other values \\
  \tablenums{24..32} & \texttt{superblock\_b\_offset} (\texttt{u64}) &
    \tablenums{320}; readers reject other values \\
  \tablenums{32..48} & \texttt{file\_uuid} & 16 opaque bytes \\
  \tablenums{48..60} & reserved & written zero; ignored on read \\
  \tablenums{60..64} & \texttt{header\_crc} & CRC-32C of bytes
    \tablenums{0..60}, \texttt{u32} LE \\
  \bottomrule
\end{longtable}
\endgroup

Readers \MUST{} verify the magic and the CRC before consulting any other part
of the file.

\section{The Superblock Slots (256 bytes each)}
\label{sec:bundle:superblock}

Two slots, at offsets 64 (A) and 320 (B); the only mutable on-disk objects.
Selection \emph{semantics} (highest valid committed generation, the
equal-generation rule, torn-write fallback) are core Chapter~8,
\sectionsc{Superblock Selection}; the bytes:

\begingroup\small
\begin{longtable}{p{0.9in} p{2.15in} p{2.55in}}
  \toprule
  \textbf{Range} & \textbf{Field} & \textbf{Encoding} \\
  \midrule
  \endhead
  \tablenums{0..8} & magic & \texttt{MUSCSUPR} (8 ASCII bytes) \\
  \tablenums{8..16} & \texttt{generation} & \texttt{u64} LE \\
  \tablenums{16..24} & \texttt{manifest\_offset} & \texttt{u64} LE \\
  \tablenums{24..32} & \texttt{manifest\_length} & \texttt{u64} LE (also the
    uncompressed length; the manifest is mandatorily uncompressed) \\
  \tablenums{32..64} & \texttt{manifest\_hash} & 32 raw digest bytes \\
  \tablenums{64..68} & \texttt{manifest\_schema\_version} &
    \texttt{SchemaVersion} (\texttt{u16} LE \cat{} \texttt{u16} LE) \\
  \tablenums{68..72} & \texttt{reduction\_algorithm\_version} &
    \texttt{u32} LE \\
  \tablenums{72..92} & \texttt{profile\_id} & 20 bytes: \texttt{u32} LE
    discriminant (\tablenums{0} Full, \tablenums{1} ReadOnly,
    \tablenums{2} Lite, \tablenums{3} Custom) \cat{}
    \texttt{ProfileRegistryId} (16 raw bytes; writers \MUST{} emit zero
    unless Custom, readers ignore it unless Custom). Core requirement
    \texttt{req:format:profileid-discriminants}. \\
  \tablenums{92..100} & \texttt{commit\_state} & two \texttt{u32} LE words:
    Committed $= (\tablenums{0}, \tablenums{0})$; any tag
    ${}\neq \tablenums{0}$ decodes as Reserved(value) and the slot is
    invalid for ordinary selection. Writers in this version \MUST{} produce
    only Committed. \\
  \tablenums{100..108} & \texttt{commit\_timestamp} & \texttt{i64} LE
    nanoseconds; advisory --- selection never consults it \\
  \tablenums{108..252} & reserved & written zero; ignored on read \\
  \tablenums{252..256} & \texttt{superblock\_crc} & CRC-32C of bytes
    \tablenums{0..252}, \texttt{u32} LE \\
  \bottomrule
\end{longtable}
\endgroup

\section{Chunks}
\label{sec:bundle:chunks}

The bundle body begins at
$\texttt{BODY\_START} = 320 + 256 = \tablenums{576}$. A chunk's on-disk form
is its raw (possibly compressed) payload bytes at a byte offset ---
\textbf{no per-chunk length prefix, magic, or trailer on disk}; the offset,
lengths, compression, and hash live in the referencing \texttt{ChunkRef}. A
chunk reference whose offset is below \texttt{BODY\_START} is malformed.

\textbf{Content hash preimage} (core Chapter~8, \sectionsc{Domain-Separated
Preimages}; governs identity):
\[
  \mathrm{BLAKE3}\bigl(\mathit{domain} \cat \mathit{kind}\,(1) \cat
  \mathit{schema}\,(4) \cat \mathit{uncompressed\_length}\,
  (\texttt{u64}\ \mathrm{LE}) \cat \mathit{payload}\bigr)
\]
where $\mathit{domain}$ is \texttt{MUSCMANI} for \texttt{Manifest} chunks and
\texttt{MUSCCHNK} otherwise. Compression is \emph{not} in the preimage.
Blob chunks are addressed by the bare \texttt{BlobId} form instead
(Chapter~\ref{ch:primitives}).

\textbf{\texttt{ChunkKind}} is a single byte, a \textbf{closed} vocabulary
(no \texttt{Registered} variant; core requirement
\texttt{req:format:chunkkind-discriminants}): \tablenums{0}
OperationEnvelopeBlock, \tablenums{1} OperationIndex, \tablenums{2}
Snapshot, \tablenums{3} Blob, \tablenums{4} ExtensionData, \tablenums{5}
TextProjection, \tablenums{6} LayoutCache, \tablenums{7} IntegrityIndex,
\tablenums{8} Manifest.

\textbf{\texttt{CompressionAlgorithm}} is a fixed two bytes, discriminant
\cat{} parameter: None $= (\tablenums{0},\tablenums{0})$;
Zstd$\{$level$\}$ $= (\tablenums{1}, \mathit{level})$; Reserved$(v)$ $=
(\tablenums{2}, v)$. \texttt{None} is \emph{not} a bare tag --- its zero
parameter byte is always present.

\begin{requirement}
  \label{req:binfmt:compression-none-parameter}
  A decoder \MUST{} reject a \texttt{CompressionAlgorithm} whose discriminant
  is \tablenums{0} (\texttt{None}) and whose parameter byte is non-zero. It
  \MUSTNOT{} ignore the byte, and \MUSTNOT{} normalize it to zero.
\end{requirement}

\begin{rationale}
  Ignoring it made the codec \emph{lenient}, and therefore non-injective:
  $(\tablenums{0}, \tablenums{255})$ and $(\tablenums{0}, \tablenums{0})$
  decoded to one value, which re-encodes to the latter. Every structure
  embedding a \texttt{ChunkRef} inherited that. A whole-value
  re-encode-and-compare guard hides it --- the manifest has one --- but the
  operation index does not, and so accepted two distinct payloads for one index
  while its own contract promised to reject non-canonical bytes rather than
  normalize them. Content-addressing rests on distinct bytes meaning distinct
  values.

  No conforming writer emits a non-zero parameter for \texttt{None}, so this
  rejects only corrupt or adversarial input; no existing file changes meaning.
  Found by the wire-decode fuzzer (Push~5, P3); supersedes the core
  specification's earlier ``present but zero, and ignored on read''.
\end{rationale}

\textbf{Read rules.} Writers in this format version emit \texttt{None} only;
\emph{reading} zstd at any level is a conformance \MUST{}. A zstd payload is
decompressed into a buffer sized \emph{exactly} by the declared
\texttt{uncompressed\_length} (checked against the reader's resource policy
before allocation): a stream that would exceed the declaration, ends short of
it, or carries trailing garbage is corruption. After decompression the
content hash is verified over the uncompressed bytes, and
$\mathit{id} = \mathit{hash}$ is checked. A chunk whose declared schema
major differs from the reader's supported major is rejected
(Chapter~\ref{ch:evolution}). \texttt{Reserved} compression is rejected.
The \textbf{manifest chunk is mandatorily uncompressed}: a compressed
manifest reference is rejected before any bytes are read. The reference
reader bounds any single chunk at 256\,MiB
(\texttt{MAX\_CHUNK\_BYTES}); the bound is reader policy, not a wire fact.

\subsection{\texttt{ChunkRef} (95 bytes)}
\label{sec:bundle:chunkref}

\begingroup\small
\begin{longtable}{p{0.9in} p{1.9in} p{2.8in}}
  \toprule
  \textbf{Range} & \textbf{Field} & \textbf{Encoding} \\
  \midrule
  \endhead
  \tablenums{0..32} & \texttt{id} & 32 raw digest bytes \\
  \tablenums{32..33} & \texttt{kind} & \texttt{ChunkKind} byte \\
  \tablenums{33..37} & \texttt{schema\_version} & \texttt{u16} LE \cat{}
    \texttt{u16} LE \\
  \tablenums{37..45} & \texttt{offset} & \texttt{u64} LE \\
  \tablenums{45..53} & \texttt{compressed\_length} & \texttt{u64} LE \\
  \tablenums{53..61} & \texttt{uncompressed\_length} & \texttt{u64} LE \\
  \tablenums{61..63} & \texttt{compression} & 2 bytes \\
  \tablenums{63..95} & \texttt{hash} & 32 raw digest bytes (restates
    \texttt{id}) \\
  \bottomrule
\end{longtable}
\endgroup

The canonical sort key for chunk-reference collections is
$(\mathit{kind\ discriminant}, \mathit{hash}, \mathit{offset})$, ascending
--- the Appendix-D chunk-reference order. Every set-valued
\texttt{ChunkRef} field in this chapter is sorted by it and deduplicated
before encoding.

\section{Operation-Envelope Block Payloads}
\label{sec:bundle:blocks}

The uncompressed payload of an \texttt{OperationEnvelopeBlock} chunk:

\begin{center}
\texttt{u32} LE envelope count \cat{} per envelope
\{\texttt{u32} LE byte length \cat{} envelope bytes\}
\end{center}

Envelope bytes are opaque to the bundle (their internal form is
Chapter~\ref{ch:ops}). Each envelope's offset --- the byte offset of its
\emph{first content byte} within the uncompressed block payload, with its
length prefix at $\mathit{offset}-4$ --- is deterministically recoverable
from this framing alone; it is the coordinate the operation index records.
Writers \SHOULD{} begin a new block rather than let an uncompressed payload
exceed 1\,MiB (an individual envelope larger than that occupies its own
block); readers \MUST{} accept blocks up to the active profile's bound
(default 64\,MiB). Block boundaries are storage artifacts: the envelope set
is the union across blocks.

\section{The Manifest}
\label{sec:bundle:manifest}

On-disk manifest chunk payload:

\begin{center}
\texttt{manifest\_id} (16 bytes, \texttt{u128} \emph{little-endian}) \cat{}
\emph{body}
\end{center}

(The little-endian on-disk field is a deliberate, golden-locked quirk: the
\emph{derivation} truncates big-endian like every content-derived id, but
the bundle codec serializes the resulting \texttt{u128} under its
little-endian integer rule.)

\begin{requirement}
\label{req:binfmt:manifest-id}
Restating core requirement \texttt{req:format:manifest-id}, which governs:
\[
  \texttt{ManifestId} = \mathrm{trunc128}\bigl(\mathrm{BLAKE3}(
  \texttt{MUSCMNIF} \cat \mathit{document\_id} \cat
  \mathit{generation} \cat \mathit{body}\bigr)\bigr)
\]
with $\mathit{document\_id}$ as its 16 raw bytes, $\mathit{generation}$ as
\texttt{u64} little-endian, and $\mathit{body}$ the complete manifest body
below (which itself opens with \texttt{document\_id} and
\texttt{generation} --- the double commitment is intentional and locked).
Writers re-derive the id from the body at encode time; decoders verify it.
\end{requirement}

\textbf{The body} is a positional struct of thirteen fields:

\begingroup\small
\begin{longtable}{p{0.3in} p{1.9in} p{3.45in}}
  \toprule
  \textbf{\#} & \textbf{Field} & \textbf{Encoding and canonical order} \\
  \midrule
  \endhead
  \tablenums{1} & \texttt{document\_id} & 16 raw bytes \\
  \tablenums{2} & \texttt{lineage\_id} & option tag \cat{} 16 raw bytes if
    present \\
  \tablenums{3} & \texttt{generation} & \texttt{u64} LE \\
  \tablenums{4} & \texttt{operation\_roots} & \texttt{u32} LE count \cat{}
    \texttt{ChunkRef}s, sorted by the canonical chunk-reference key,
    deduplicated \\
  \tablenums{5} & \texttt{operation\_block\_summaries} & \texttt{u32} LE
    count \cat{} entries \{\texttt{chunk\_id} (32) \cat{}
    \texttt{OperationBlockSummary}\}, ascending \texttt{chunk\_id} \\
  \tablenums{6} & \texttt{operation\_index\_root} & option tag \cat{}
    \texttt{ChunkRef} \\
  \tablenums{7} & \texttt{canonical\_base} & option tag \cat{}
    \texttt{SnapshotRef} \\
  \tablenums{8} & \texttt{acceleration\_snapshots} & \texttt{u32} LE count
    \cat{} \texttt{SnapshotRef}s, sorted ascending by their full encoded
    bytes, deduplicated \\
  \tablenums{9} & \texttt{blob\_roots} & \texttt{u32} LE count \cat{}
    \texttt{BlobRef}s, sorted ascending by encoded bytes, deduplicated \\
  \tablenums{10} & \texttt{profile\_declarations} & \texttt{u32} LE count
    \cat{} \texttt{ProfileDeclaration}s, sorted by the key
    $(\texttt{profile\_id}, \texttt{version})$ with \texttt{SemVer} compared
    \emph{numerically}, deduplicated \\
  \tablenums{11} & \texttt{extension\_declarations} & \texttt{u32} LE count
    \cat{} \texttt{ExtensionDeclaration}s, sorted by
    $(\texttt{extension\_id}, \texttt{version})$, \texttt{SemVer} numeric,
    deduplicated \\
  \tablenums{12} & \texttt{text\_projection\_root} & option tag \cat{}
    \texttt{ChunkRef} \\
  \tablenums{13} & \texttt{integrity\_root} & option tag \cat{}
    \texttt{ChunkRef} \\
  \bottomrule
\end{longtable}
\endgroup

Sub-records, positionally:

\begin{description}
  \item[\texttt{OperationBlockSummary}] = \texttt{dvv\_summary}
    (\texttt{FrontierBytes}: \texttt{u32}-LE-prefixed opaque bytes) \cat{}
    \texttt{min\_stamp} (\texttt{u32}-LE-prefixed opaque stamp bytes) \cat{}
    \texttt{max\_stamp} (same). The contents are ops-computed
    (Chapter~\ref{ch:ops}); the bundle carries them verbatim.
  \item[\texttt{SnapshotRef}] = \texttt{snapshot\_id} (16 raw) \cat{}
    \texttt{covers\_causal\_frontier} (\texttt{FrontierBytes}) \cat{}
    \texttt{reduction\_algorithm\_version} (\texttt{u32} LE) \cat{}
    \texttt{profile\_id} (20 bytes, as in the superblock) \cat{}
    \texttt{root} (\texttt{ChunkRef}, 95) \cat{} \texttt{hash} (32 raw).
  \item[\texttt{BlobRef}] = \texttt{blob\_id} (32 raw) \cat{}
    \texttt{media\_type} (\texttt{u32}-LE-prefixed ASCII; decode validates a
    well-formed RFC~6838 \texttt{type/subtype} restricted name) \cat{}
    \texttt{offset} (\texttt{u64} LE) \cat{} \texttt{compressed\_length}
    (\texttt{u64} LE) \cat{} \texttt{uncompressed\_length} (\texttt{u64} LE)
    \cat{} \texttt{compression} (2) \cat{} \texttt{hash} (32 raw) \cat{}
    option tag \cat{} \texttt{declared\_max\_uncompressed\_length}
    (\texttt{u64} LE) if present.
  \item[\texttt{ProfileDeclaration}] = \texttt{profile\_id} (20) \cat{}
    \texttt{version} (\texttt{SemVer}, 12) \cat{} \texttt{constraints}
    (\texttt{ProfileConstraints} =
    \texttt{max\_uncompressed\_block\_size} (\texttt{u64} LE) \cat{}
    \texttt{RetentionPolicy}). \texttt{RetentionPolicy} =
    \texttt{retain\_previous\_manifests} (\texttt{u32} LE) \cat{} option tag
    \cat{} \texttt{retain\_duration} (\texttt{i64} LE) if present \cat{}
    \texttt{retain\_named\_checkpoints} (bool, 1).
  \item[\texttt{ExtensionDeclaration}] = \texttt{extension\_id} (16 raw)
    \cat{} \texttt{version} (\texttt{SemVer}, 12) \cat{} \texttt{required}
    (bool, 1) \cat{} \texttt{u32} LE count \cat{}
    \texttt{preserved\_chunk\_roots} (\texttt{ChunkRef}s, canonical order,
    deduplicated) \cat{} \texttt{affected\_object\_kinds}
    (\texttt{u32}-LE-prefixed opaque blob) \cat{} \texttt{edit\_barriers}
    (\texttt{u32}-LE-prefixed opaque blob). The two blobs' internal form is
    Chapter~\ref{ch:barriers}; the bundle preserves them verbatim.
\end{description}

\begin{requirement}
\label{req:binfmt:manifest-canonical}
\textbf{Reject non-canonical manifests.} A decoder \MUST{} accept a manifest
payload only if re-encoding the decoded manifest reproduces the input
byte-for-byte. This single check subsumes: the stored \texttt{manifest\_id}
matching the body-derived id, every set-valued vector being in its canonical
order with no duplicates, and every optional field using presence byte
\tablenums{0}/\tablenums{1}. Unsorted, duplicated, or wrongly-identified
manifest bytes are malformed --- never re-sorted or repaired.
\end{requirement}

\section{The Operation Index}
\label{sec:bundle:opindex}

\begin{requirement}
\label{req:binfmt:opindex}
\textbf{Operation-index payload (ratifies P12-D1).} The uncompressed payload
of an \texttt{OperationIndex} chunk is:

\begin{center}
\texttt{u32} LE \texttt{block\_count} \cat{} that many \texttt{ChunkRef}s
(95 bytes each, strictly ascending canonical order) \cat{}
\texttt{u32} LE \texttt{entry\_count} \cat{} that many entries, each
\{\texttt{id} (16 raw operation-id bytes) \cat{} \texttt{block}
(\texttt{u32} LE ordinal into the block vector) \cat{} \texttt{offset}
(\texttt{u32} LE)\}, strictly ascending by \texttt{id} bytes.
\end{center}

The empty index is exactly 8 zero bytes. \texttt{offset} is the byte offset
of the envelope's \emph{first content byte} within the uncompressed payload
of the named block (the envelope's \texttt{u32} length prefix sits at
$\mathit{offset}-4$) --- well-defined by the id-leads property
(Requirement~\ref{req:binfmt:envelope}) and the block framing
(Section~\ref{sec:bundle:blocks}).

\textbf{One slot per id.} Strict ascent makes duplicate ids unrepresentable:
an index payload containing two entries with equal id bytes is malformed.
Equivocation candidates (multiple envelopes claiming one
\texttt{OperationId}) live \emph{inside} the operation set's slot model
(core Chapter~6), never as duplicate index rows.

\textbf{Staleness.} An index \emph{covers} a manifest iff its block vector
equals the manifest's deduplicated, canonically sorted
\texttt{operation\_roots} under \textbf{full \texttt{ChunkRef} equality} ---
every field, not just the content hash, since the index hands out its stored
references for reading. A reader that finds the index stale \MUST{} reject
it and rebuild from the blocks.

A rejected or stale index is \textbf{never bundle corruption}: the index is
a non-canonical accelerator, and rebuild-from-blocks is always sound.

Decoders \MUST{} reject: unsorted or duplicated blocks or entry ids, a block
reference whose kind is not \texttt{OperationEnvelopeBlock}, an entry whose
block ordinal is out of range, and trailing bytes.
\end{requirement}

The core specification's commit-time \SHOULD{} --- refresh the index when
the operation log has ``grown significantly'' since it was built --- has an
\textbf{implementation-defined} threshold in v0: this document deliberately
does not pin a number, and conforming writers may use any policy (including
always or never refreshing at commit), because the index is non-canonical.

\begin{openquestion}
Whether to pin a normative refresh threshold (e.g.\ a block-count or
byte-size ratio) or leave it permanently implementation-defined. Leaving it
open costs only lookup performance on stale-index bundles; pinning it too
early would constrain writers for no interoperability gain. Revisit when a
second writer implementation exists.
\end{openquestion}

% ===========================================================================
\chapter{Extension Declaration Blobs and Edit Barriers}
\label{ch:barriers}

The two opaque blobs a manifest \texttt{ExtensionDeclaration} carries ---
\texttt{affected\_object\_kinds} and \texttt{edit\_barriers} --- have their
internal byte form pinned here. This chapter \textbf{ratifies} P12-E1
(the blob and barrier-tree byte form), P12-E2 (the recursion bound), and
P12-E3 (the barrier \texttt{ObjectKind} representation). Barrier
\emph{semantics} --- scope matching, prohibited-edit evaluation,
conservative treatment of unknown extensions --- are core Chapter~8
(\sectionsc{Forward Compatibility and Edit Barriers}); this chapter pins
bytes only.

These layouts are \textbf{regime (b)}: all counts and length prefixes are
\texttt{u64} little-endian --- a deliberate, golden-locked divergence from the
\texttt{u32} regime (Section~\ref{sec:conventions:regimes}). They \textbf{keep
this form in schema major~1}: unlike the resolved-layout surface, these blobs
are carried \emph{opaquely inside the canonical manifest}
(Section~\ref{sec:bundle:manifest}), which stays major~0, so a major-0 reader
must continue to parse them as \texttt{u64}. Their unification waits for a
future major that revises the manifest (Section~\ref{sec:evolution:major1}).

\begin{openquestion}
\textbf{Unsafe-edit tombstone encoding (from P12-E5).} Core Chapter~8 now
ratifies the unsafe-edit tombstone \emph{semantics} (immediate deactivation of
the crossed extension's remaining barriers; a durable record \MUST{} land at
the next commit; \texttt{required = true} interaction). The manifest-side
\emph{byte encoding} of that record is unresolved --- and constrained: the
manifest schema is frozen at major~0, so the record cannot be a new manifest
field. Candidate channels: a marker inside the extension-declaration blob
layer (this chapter's regime-(b) surface), or a dedicated chunk kind
referenced from \texttt{preserved\_chunk\_roots}. To be designed in the next
bundle-format tranche; the editor-side producer
(\texttt{extensions\_requiring\_tombstone()}) already exists.
\end{openquestion}

\section{Framing}
\label{sec:barriers:framing}

\begin{description}
  \item[element] $\mathrm{elem}(x)$ = \texttt{u64} LE byte length \cat{}
    $x$'s canonical bytes.
  \item[set] $\mathrm{set}(xs)$ = elements' canonical byte strings, sorted
    ascending byte-lexicographic and \emph{deduplicated}; then \texttt{u64}
    LE element count \cat{} each element as $\mathrm{elem}$. Order and
    repetition in the source collection cannot affect the bytes; decoders
    reject unsorted or duplicated elements.
  \item[list] $\mathrm{list}(xs)$ = \texttt{u64} LE count \cat{} each
    element as $\mathrm{elem}$, order-significant (used only for condition
    subtrees).
\end{description}

\begin{requirement}
\label{req:binfmt:ext-blobs}
\textbf{The two blobs (ratifies P12-E1).} The
\texttt{affected\_object\_kinds} blob is $\mathrm{set}$ of barrier
\texttt{ObjectKind} elements; the \texttt{edit\_barriers} blob is
$\mathrm{set}$ of \texttt{EditBarrier} elements. Both decode under
reject-never-normalize with trailing bytes forbidden.
\end{requirement}

\begin{requirement}
\label{req:binfmt:object-kind-open}
\textbf{Barrier \texttt{ObjectKind} (ratifies P12-E3).} A barrier
\texttt{ObjectKind} is the \texttt{TypedObjectId} discriminant of
Section~\ref{sec:ids:typed-object-id}, encoded as \textbf{2 little-endian
bytes}. Decode is \textbf{open-value}: every \texttt{u16} decodes
successfully --- an unknown kind (a future core kind or an
extension-registered kind) is a \emph{value}, not a decode branch, and
simply never matches any object the reader knows. This is the format's
forward-compatibility stance for barrier kinds: unknown kinds are preserved
and re-emitted verbatim, never dropped or rejected.
\end{requirement}

\section{\texttt{EditBarrier}}
\label{sec:barriers:barrier}

An \texttt{EditBarrier}'s canonical bytes, positionally:

\begin{center}
\texttt{scope} \cat{} $\mathrm{set}$(\texttt{affected\_object\_kinds}:
\texttt{ObjectKind}) \cat{}
$\mathrm{set}$(\texttt{prohibited\_operation\_kinds}:
\texttt{OperationKindTag}, Section~\ref{sec:ops:kind-tag}) \cat{}
\texttt{condition}
\end{center}

\texttt{BarrierScope}: one discriminant byte, then the payload:

\begingroup\small
\begin{longtable}{p{0.35in} p{1.35in} p{3.8in}}
  \toprule
  \textbf{Disc} & \textbf{Variant} & \textbf{Payload} \\
  \midrule
  \endhead
  \tablenums{0} & \texttt{WholeScore} & (none) \\
  \tablenums{1} & \texttt{Region} & \texttt{RegionId}, 16 big-endian bytes \\
  \tablenums{2} & \texttt{StaffInstance} & \texttt{StaffInstanceId}, 16 BE \\
  \tablenums{3} & \texttt{AnalysisLayer} & \texttt{AnalysisLayerId}, 16 BE \\
  \tablenums{4} & \texttt{ObjectSet} & $\mathrm{set}$ of
    \texttt{TypedObjectId} canonical bytes (18/34 each) \\
  \tablenums{5} & \texttt{PitchSpace} & \texttt{u64} LE byte length \cat{}
    the pitch-space id's NFC UTF-8 bytes; decoders reject non-NFC input \\
  \tablenums{6} & \texttt{TuningContext} & (none) \\
  \tablenums{7} & \texttt{Registered} & \texttt{BarrierScopeRegistryId},
    \texttt{u128} \emph{little-endian} (16 bytes) \\
  \bottomrule
\end{longtable}
\endgroup

\texttt{BarrierCondition}: one discriminant byte, then the payload; the tree
is recursive:

\begingroup\small
\begin{longtable}{p{0.35in} p{1.85in} p{3.3in}}
  \toprule
  \textbf{Disc} & \textbf{Variant} & \textbf{Payload} \\
  \midrule
  \endhead
  \tablenums{0} & \texttt{Always} & (none) \\
  \tablenums{1} & \texttt{ObjectExists} & \texttt{TypedObjectId} \\
  \tablenums{2} & \texttt{ObjectHasExtensionData} & \texttt{object}
    (\texttt{TypedObjectId}) \cat{} \texttt{extension}
    (\texttt{ExtensionRef}, \texttt{u128} LE, 16) \\
  \tablenums{3} & \texttt{All} & $\mathrm{list}$ of conditions \\
  \tablenums{4} & \texttt{Any} & $\mathrm{list}$ of conditions \\
  \tablenums{5} & \texttt{Not} & one $\mathrm{elem}$-framed condition \\
  \tablenums{6} & \texttt{Registered} &
    \texttt{BarrierConditionRegistryId}, \texttt{u128} LE (16) \\
  \bottomrule
\end{longtable}
\endgroup

Note the endianness: the barrier layer's registry identifiers
(\texttt{BarrierScopeRegistryId}, \texttt{BarrierConditionRegistryId},
\texttt{ExtensionRef}) encode \texttt{u128} \emph{little-endian}, unlike the
big-endian identifier family of Chapter~\ref{ch:ids}. This is part of the
golden-locked regime-(b) surface.

\begin{requirement}
\label{req:binfmt:condition-depth}
\textbf{Recursion bound (ratifies P12-E2).}
$\texttt{MAX\_CONDITION\_DEPTH} = \tablenums{64}$ is the normative bound on
\texttt{BarrierCondition} nesting. Decoders \MUST{} reject a condition tree
nested deeper than 64 levels of \texttt{All}/\texttt{Any}/\texttt{Not};
writers \MUSTNOT{} emit one. The bound exists so adversarial bytes cannot
drive unbounded recursion; real barriers are depth 1--2.
\end{requirement}

% ===========================================================================
\chapter{Schema Evolution}
\label{ch:evolution}

The core specification delegates schema evolution to this document (core
Chapter~8, \sectionsc{Schema Versioning}: \emph{``Schema evolution is
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,
Section~\ref{sec:evolution:major2} the schema-major-2 delta and its
migration from major~1, and Section~\ref{sec:evolution:major3} the
schema-major-3 delta and its migration from major~2.

\section{The Chunk-Level Gate}
\label{sec:evolution:gate}

Every chunk declares a \texttt{SchemaVersion} (major, minor) in its
\texttt{ChunkRef} and the superblock declares the manifest's. The gate:

\begin{itemize}
  \item \textbf{Major} = incompatible. A reader \MUST{} reject a chunk whose
    schema major it does not support. A reader supports a contiguous accept-set
    $[\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}). Four majors are defined:
    \tablenums{0}, \tablenums{1} (Section~\ref{sec:evolution:major1}),
    \tablenums{2} (Section~\ref{sec:evolution:major2}), and \tablenums{3}
    (Section~\ref{sec:evolution:major3}). The accept-set is \textbf{per chunk
    role}, not one shared bound (Section~\ref{sec:evolution:major1}'s ``raised
    per chunk role'' rule, sharpened by major~3, the first bump under which the
    roles' maxima genuinely diverge): the \texttt{Snapshot} role's max is
    \tablenums{3}; the \texttt{OperationEnvelopeBlock} role's max is
    \tablenums{3} as of genesis tranche G2b
    (\texttt{spec/CONTRACT\_GENESIS\_G2B\_TUNING.md} ---
    \texttt{SetTuningContext}, \tablenums{34}, is born at v3
    unconditionally; the role stayed at \tablenums{2} from Push~4b tranche
    3b-i, when schema major~3 embedded no operation payload, until this
    rung); every other role's max is \tablenums{0}. The reference
    implementation's overall envelope is $\{0, 1, 2, 3\}$ ($\textsc{min} = 0$,
    $\textsc{max} = 3$), realized as these differing per-role maxima rather
    than a single shared bound.
  \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
    discriminant appended after the minor it otherwise declares, so that a
    decode failure on an unknown appended discriminant is attributable to a
    version skew rather than corruption.
\end{itemize}

\section{What ``Additive'' Means Here}
\label{sec:evolution:additive}

Under the frozen-layout rule (Requirement~\ref{req:binfmt:frozen-layout}),
positional struct layouts admit \emph{no} additive change: there is no
optional-field or trailing-field mechanism at the value level. In
particular, and stated honestly: \textbf{the manifest body cannot grow a
fourteenth field within major~0}. The manifest is a positional struct whose
decoder rejects trailing bytes, so manifest-body extension is
major-gated in v0 exactly like every other struct.

Adding a field is a \textsc{major} change \emph{regardless of its type}: an
\texttt{Option} field is not ``optional'' in the wire sense --- it still
occupies a new positional slot (a presence byte, then the payload when
present), which shifts every subsequent field and rejects under the
trailing-bytes rule. There is no ``downgrade to minor'' for an \texttt{Option}
addition. The first exercise of this is schema major~1
(Section~\ref{sec:evolution:major1}), which adds \texttt{Instrument.range}
(an \texttt{Option}) among other fields.

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{40}$
    (Requirement~\ref{req:binfmt:kind-discriminants}; the Phase-3
    tranche took \tablenums{24}--\tablenums{27} under this mechanism,
    the repeat pair \tablenums{28}/\tablenums{29} in the
    schema-major-2 revision, Push~4a took \tablenums{30}
    (\texttt{TransposeInterval}), genesis tranche G1 took \tablenums{31}
    (\texttt{CreateInstrument}), genesis tranche G2a took
    \tablenums{32}/\tablenums{33} (\texttt{SetCanvasLayoutDefaults},
    \texttt{SetSpellingPrecedence}), genesis tranche G2b took
    \tablenums{34} (\texttt{SetTuningContext}), genesis tranche G3a took
    \tablenums{35}--\tablenums{38} (\texttt{CreateStaffGroup},
    \texttt{CreatePartDefinition}, \texttt{CreateAnalysisLayer},
    \texttt{CreateView}), and genesis tranche G3b took \tablenums{39}
    (\texttt{CreateMeasure}) --- 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}; \tablenums{34}'s payload embeds a v3
    layout unconditionally, so its blocks stamp major~3,
    Section~\ref{sec:evolution:major3} --- the sole appended kind to do so;
    \tablenums{35}--\tablenums{39} are each major~0, no versioned walk
    existing for any of their five carried types);
  \item \texttt{OperationKindTag}: append at ${\geq}\,\tablenums{40}$
    (Requirement~\ref{req:binfmt:kind-tag}; the same sixteen variants as
    \texttt{OperationKind}, at the same sixteen discriminants, appended by
    the same eight tranches);
  \item \texttt{OperationPayload}: append at ${\geq}\,\tablenums{4}$
    (Section~\ref{sec:ops:payload}; \texttt{ResolveEquivocation} = 3, Push~3,
    is the one and only append this vocabulary has had);
  \item the value-layer unions enumerated as closed in
    Requirement~\ref{req:binfmt:frozen-layout} may gain appended variants
    only through a ratified revision of this document, also minor-additive.
\end{itemize}

\paragraph{The schema-minor derivation (G-minor).} Every appended
discriminant above is annotated with a \emph{global additive epoch}: one
schema-minor value shared across every vocabulary, assigned in the order the
revision that introduced it landed
(\texttt{spec/PLAN\_GMINOR\_SCHEMA\_MINOR.md}~\S4). An envelope's required
minor is the maximum epoch over every discriminant it actually emits --- its
outer \texttt{OperationPayload} variant, its primitive \texttt{OperationKind}
when \texttt{Primitive}, and any nested additive variant its encoder reaches;
a block's is the maximum over its envelopes. The emitted version is
$\{\text{major}, \max(\text{baseline\_minor}(\text{major}),
\text{epoch\_max})\}$: existing baselines (\tablenums{1} for major~0,
\tablenums{0} for majors~1--3) are never lowered, and a block emitting only
baseline vocabulary keeps its major's baseline minor rather than being
normalized to zero. This is content-minimal per-role stamping, not a single
document-wide counter: the canonical base, the manifest, and each operation
block are each stamped from only the discriminants their own bytes emit
(Section~\ref{sec:evolution:additive}'s per-chunk framing extends
unchanged). The manifest reaches \texttt{OperationKindTag} independently of
any operation envelope, through
\texttt{ExtensionDeclaration.edit\_barriers} $\to$
\texttt{EditBarrier.prohibited\_operation\_kinds}: a manifest naming a
barrier on a post-baseline tag takes that tag's epoch, and the manifest
major stays~0 regardless.

\texttt{ChunkKind} is \textbf{closed} --- it has no \texttt{Registered}
variant and no append story inside major~0, because its discriminant enters
every chunk's hash preimage; a new chunk kind is a format-major event.

Separately, many vocabularies carry a \texttt{Registered} \emph{escape
variant} (\texttt{RepairKind}, \texttt{ReanchorReason},
\texttt{PreconditionFailureReason}, \texttt{IntegrityAnomalyKind},
\texttt{ReplicaAnomalyReason}, \texttt{TransactionCategory},
\texttt{ResolutionAction}, \texttt{ConflictKind} via
\texttt{ExtensionConflict}, \texttt{BarrierScope}/\texttt{BarrierCondition},
\texttt{TieClass}, \texttt{StaffGroupKind}, \texttt{PitchSpacePosition},
\texttt{SpellingNominal}, \texttt{TypedObjectId}, and the barrier
\texttt{ObjectKind}'s open value space). Extension through an escape variant
is \textbf{not} a schema change at all: the wire form is already defined.

\section{Migration Discipline}
\label{sec:evolution:migration}

A schema-\textsc{major} bump \MUST{} ship with a migration documented in
this document's revision history (Chapter~\ref{ch:history}): what changed,
byte-for-byte, and the deterministic translation from the old form. The
precedent is the v0${\to}$v1 operation-payload migration, which lives in the
Operation Catalog (\sectionsc{v0 $\rightarrow$ v1 Payload Migration})
because it was semantic rather than byte-level
(Section~\ref{sec:ops:v0}); byte-level migrations belong here.

The \texttt{u64}/\texttt{u32} length-prefix divergence between regimes (a) and
(b) (Section~\ref{sec:conventions:regimes}), left open in earlier revisions for
a future major, is \textbf{partly resolved in schema major~1}
(Section~\ref{sec:evolution:major1}): the first major bump, scheduled for
data-model reasons, carries the unification for the independent non-canonical
resolved-layout surface. The barrier/extension blobs remain regime~(b) because
they ride the canonical manifest, which this bump keeps at major~0; their
unification stays open for a manifest-revising major.

\section{Schema Major 1}
\label{sec:evolution:major1}

Schema major~1 is the first data-model expansion major, defined here in full:
the changed value layouts, the length-prefix unification, and the
byte-for-byte migration from major~0. It bundles every change that was
deferred to ``the next major'' so that one coordinated migration discharges
them together.

\subsection{Where the changed fields reach}
The three added fields land in different chunk classes, and the major is
assigned \textbf{per payload type}, not per chunk kind:

\begin{itemize}
  \item \texttt{Canvas.layout\_defaults} and \texttt{Instrument.range} now
    also reach the \textbf{canonical operation layer}, each by a different
    genesis-tranche operation. \texttt{Instrument.range}: genesis tranche G1's
    \texttt{CreateInstrument} (\S\ref{sec:ops:kinds} discriminant
    \tablenums{31}) embeds the full \texttt{Instrument} value, whose
    schema-major-2 appends are mandatory --- so this payload always carries
    the complete (major-2) \texttt{Instrument} layout, \texttt{range}
    included, and a block carrying it is stamped \textbf{major~2}
    unconditionally, never merely major~1.
    \texttt{Canvas.layout\_defaults}: genesis tranche G2a's
    \texttt{SetCanvasLayoutDefaults} (discriminant \tablenums{32}) embeds the
    full \texttt{CanvasLayoutDefaults} value directly, rather than through the
    containing \texttt{Canvas} walk that carries the major-1 versioning ---
    \texttt{CanvasLayoutDefaults} has exactly one layout as a standalone
    value, so a block carrying this operation is stamped \textbf{major~0}.
    What remains confined to the \textbf{non-canonical} acceleration-cache
    full-\texttt{Score} snapshot (a \texttt{ChunkKind::Snapshot}) is the
    canvas \emph{object itself}: there is still no \texttt{CreateCanvas}, no
    \texttt{TypedObjectId} kind for it, and no operation mints, addresses, or
    deletes it --- the canvas is the inline genesis singleton, and that half
    of the earlier claim survives.
  \item \texttt{Region.permits\_spanning\_slurs} reaches the snapshot
    \emph{and} the \textbf{canonical operation layer}:
    \texttt{CreateRegion} embeds the full \texttt{Region} value
    (Section~\ref{sec:ops:payload}), so its v1 payload carries the v1
    \texttt{Region} layout. An operation-envelope block containing a
    \texttt{CreateRegion} therefore encodes v1 bytes and is stamped
    \textbf{major~1}; a block with no such operation stays \textbf{major~0}.
    Operation-envelope blocks are canonical, so this is a canonical
    operation-layer change, not merely a cache change.
  \item \texttt{ChunkKind::Snapshot} is itself payload-polymorphic: the same
    kind carries \emph{either} an acceleration-cache full \texttt{Score} (as
    above, stamped major~1) \emph{or} the canonical-base
    \texttt{MaterializedState}, disambiguated by manifest role. The canonical
    base embeds no \texttt{Canvas}, \texttt{Instrument}, or \texttt{Region}
    value, so it is unchanged and stays \textbf{major~0}. Its content-hash
    preimage (Section~\ref{sec:bundle:chunks}) includes the schema version, so
    re-stamping the unchanged base at major~1 would change its chunk id and
    churn every \texttt{SnapshotRef} for zero layout benefit. A writer
    \MUSTNOT{} do so; a conformance test \SHOULD{} assert the canonical base
    is byte-identical across the bump.
\end{itemize}

\subsection{Cross-major reader behaviour}
Two rules follow from the chunk classes above and the core specification's
\sectionsc{Schema Versioning} canonical/non-canonical distinction:

\begin{itemize}
  \item \textbf{Non-canonical chunks --- discard and regenerate.} The layout
    caches and the acceleration snapshot are non-canonical. A reader meeting a
    foreign-major one \MAY{} discard and regenerate it rather than decode it: a
    major-1 reader regenerates a major-0 layout cache instead of carrying a
    frozen old-width decoder, and it migrates a major-0 acceleration
    \texttt{Score} snapshot on read (cheaper than replaying the operation log).
  \item \textbf{Canonical chunks --- parse or open read-only.} The manifest and
    the canonical base stay major~0 and are always parseable. A major-1 op
    block is canonical: a major-0-only reader \MUSTNOT{} discard it (that would
    fork canonical state) --- it opens the bundle in read-only preservation
    mode, having read the major-0 base and manifest but being unable to replay
    the v1 \texttt{CreateRegion} operations. A major-1 reader migrates such a
    block on read (below).
\end{itemize}

So a major-0-only reader opens a major-1 bundle \emph{fully} only when the
bundle contains no v1 \texttt{CreateRegion} operation; otherwise it opens
read-only. It always reads the canonical base and manifest, and always
discards the higher-major non-canonical caches.

\subsection{The accept-set gate}
A reader supports a contiguous set of majors $[\textsc{min}, \textsc{max}]$
(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.

\subsection{Changed and new value layouts}
These extend Chapter~\ref{ch:values}'s regime~(a) rules. As there, \textbf{the
wire form is the reference implementation's struct layout} --- which is a
reduced subset of the core specification's fuller data model (the code's
\texttt{Instrument} carries a subset of the model's fields, etc.). The wire
form ratifies the code, not the model; a struct's v1 layout \textbf{appends}
its new field(s) after its existing major-0 fields:

\begin{itemize}
  \item \texttt{Canvas} $=$ \texttt{regions} \cat{} \texttt{layout\_defaults},
    where \texttt{CanvasLayoutDefaults} $=$ \texttt{page\_size}
    (\texttt{CanvasSize} $=$ \texttt{width} \cat{} \texttt{height}, two
    \texttt{CanonicalF64} leaves) \cat{} \texttt{margins}
    (\texttt{CanvasMargins} $=$ four \texttt{CanonicalF64} leaves: top,
    right, bottom, left).
  \item \texttt{Instrument} $=$ \texttt{id} \cat{} \texttt{name} \cat{}
    \texttt{range} (\texttt{Option<PitchRange>}: a presence byte, then for
    \texttt{Some} a \texttt{PitchRange} $=$ \texttt{lowest} \cat{}
    \texttt{highest}, each a \texttt{Pitch} under this chapter's rules).
  \item \texttt{Region} appends \texttt{permits\_spanning\_slurs}, one bare
    bool byte (\tablenums{0}/\tablenums{1}), after its major-0 fields.
  \item \textbf{Operation layer:} the \texttt{CreateRegion} payload embeds a
    length-prefixed \texttt{Region} (Section~\ref{sec:ops:payload}), so its v1
    form carries the v1 \texttt{Region} layout (the appended bool inside the
    embedded value). This is the one \emph{canonical} byte change in major~1;
    the operation envelope's own field order is unchanged, only its embedded
    \texttt{Region} grows.
\end{itemize}
Every embedded leaf keeps this chapter's framing (a \texttt{CanonicalF64} is a
\texttt{u32} LE length \cat{} 8 bytes $= 12$; a bool is one bare byte).

\subsection{Length-prefix unification (partial)}
Regime~(b) (Section~\ref{sec:conventions:regimes}) is \emph{narrowed}, not
fully retired, in major~1. The \texttt{ResolvedLayoutIR} output --- an
independent, non-canonical \texttt{LayoutCache} chunk --- moves from
\texttt{u64} to \texttt{u32} LE counts and length prefixes, matching
regime~(a), and its golden anchors re-lock in the same step. Because it is
non-canonical, a major-1 reader regenerates a major-0 resolved-layout cache
rather than decoding its \texttt{u64} form --- no frozen \texttt{u64} decoder
is required.

The extension-declaration and edit-barrier blobs (Chapter~\ref{ch:barriers})
\textbf{stay regime~(b)}: they are carried opaquely inside the canonical
manifest (Section~\ref{sec:bundle:manifest}), which stays major~0, so a
major-0 reader must keep parsing them as \texttt{u64}. Unifying them would
require bumping the manifest itself, which this data-model bump deliberately
avoids; that unification waits for a manifest-revising major.

\subsection{Migration from major~0}
The v0${\to}$v1 translation is total and default-filling: every new field has
a canonical default, so no value is unrecoverable --- including the
\texttt{CreateRegion} operation payload, whose embedded \texttt{Region}
default-fills structurally. This is unlike the \emph{semantic},
context-dependent operation-payload migration of Section~\ref{sec:ops:v0}
(which could be irreversible); the major-1 migration needs no score context.

\begin{center}
\begin{tabular}{p{1.9in} p{3.4in}}
  \toprule
  \textbf{major-0 form} & \textbf{major-1 form} \\
  \midrule
  \texttt{Canvas} $=$ \texttt{regions} &
    append \texttt{layout\_defaults} $=$ the A4/8\,mm default (page
    $105 \times 148.5$, margins $7.5$ staff spaces) \\
  \texttt{Instrument} $=$ \texttt{id}, \texttt{name} &
    append \texttt{range} $=$ \texttt{None} (presence byte \tablenums{0}) \\
  \texttt{Region} $= \ldots$ (snapshot) &
    append \texttt{permits\_spanning\_slurs} $=$ \tablenums{0}
    (\texttt{false}) \\
  \texttt{CreateRegion} op payload &
    default-fill the embedded \texttt{Region}'s appended field
    (\texttt{permits\_spanning\_slurs} $=$ \tablenums{0}); \emph{canonical} ---
    a v0 op block migrates on read, and a block bearing a v1 \texttt{CreateRegion}
    is major~1 (a major-0-only reader opens the bundle read-only) \\
  \texttt{ResolvedLayoutIR} \texttt{u64} prefixes &
    non-canonical \texttt{LayoutCache}: discard and regenerate at major~1
    under \texttt{u32} (no in-place byte translation) \\
  barrier / extension-declaration blobs &
    stay regime~(b) \texttt{u64} (manifest-embedded, manifest stays major~0);
    unchanged in this bump \\
  canonical-base \texttt{MaterializedState} &
    unchanged, byte-identical, stays major~0 \\
  \bottomrule
\end{tabular}
\end{center}

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:} nothing, as of genesis tranche G1.
    \texttt{Instrument} was snapshot-only when this section was first
    ratified (no operation embedded one; it reached only the acceleration
    full-\texttt{Score} snapshot) and \texttt{RepeatStructure} likewise,
    until the repeat-authoring pair moved it to the canonical operation
    layer. \texttt{CreateInstrument} (genesis tranche G1, discriminant
    \tablenums{31}) moved \texttt{Instrument} the same way --- see the next
    bullet, which now names it.
  \item \textbf{Canonical operation layer:} nine operation
    payloads embed filled values. \texttt{CreateInstrument} (genesis
    tranche G1 --- Operation Catalog \sectionsc{CreateInstrument},
    discriminant \tablenums{31}) embeds the full \texttt{Instrument} value;
    its schema-major-2 appends (\texttt{sound\_config},
    \texttt{default\_clef}, \texttt{default\_staff\_lines}, and the rest)
    are mandatory fields, not \texttt{Option}-hidden, so it is
    \emph{born at v2} exactly as \texttt{CreateRepeatStructure} below is ---
    no lower-major layout for this payload exists, and every block
    carrying one stamps major~2 under minimal stamping.
    \texttt{CreateRepeatStructure} (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 likewise \emph{born at
    v2}. 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 remaining 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
    \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.) That is
    $1~(\texttt{CreateInstrument}) + 1~(\texttt{CreateRepeatStructure}) +
    7 = 9$ payloads total.

    \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};
    \texttt{CreateRepeatStructure} $\Rightarrow$ always \textbf{2}
    (born at v2); \texttt{DeleteRepeatStructure} $\Rightarrow$
    \textbf{0} (a bare identifier under a minor kind append);
    \texttt{TransposeInterval} $\Rightarrow$ \textbf{0} (a sequence of
    identifiers and two \texttt{i32}s --- every constituent is a major-0
    layout, so the kind append is a schema \emph{minor}, and a
    \texttt{TransposeInterval} rides in a major-0 block); 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}

\section{Schema Major 3}
\label{sec:evolution:major3}

Schema major~3 is the third data-model expansion major (Push 4b tranche
3b-i, \sectionsc{Score Tuning Context}): \texttt{ScoreTuningContext} gains
\texttt{smufl} (the score's declared SMuFL version requirement) and
\texttt{overrides} (per-scope tuning overrides) on the canonical wire.
\texttt{accidental\_extensions} --- the third field the core specification
added alongside these two --- is deliberately \textbf{staged} to a later
major: its consumer, the engraver, does not exist yet, and freezing a wire
layout ahead of a real consumer is exactly what the frozen-layout rule
(Requirement~\ref{req:binfmt:frozen-layout}) warns against. When
\texttt{accidental\_extensions} does land, it appends \emph{after}
\texttt{overrides}, per the append-only rule this chapter has followed since
major~1.

\subsection{Where the changed fields reach}

\textbf{As first defined (Push~4b tranche 3b-i), no operation payload
embedded the tuning context} --- \texttt{ScoreTuningContext} reached the
wire only through the acceleration full-\texttt{Score} snapshot, and the
\texttt{OperationEnvelopeBlock} role's accept-set stayed at major~2. This
changed at genesis tranche G2b
(\texttt{spec/CONTRACT\_GENESIS\_G2B\_TUNING.md}), which corrects the claim
below:

\begin{itemize}
  \item \textbf{Reaches two sites, as of genesis tranche G2b.}
    \texttt{ScoreTuningContext} still reaches the wire through the
    acceleration full-\texttt{Score} snapshot, \emph{and} its authored
    subset --- \texttt{TuningContextSettings}, exactly the five
    wire-bearing fields, byte-identical to this section's layout
    (Section~\ref{sec:ops:kinds}, \tablenums{34}
    \texttt{SetTuningContext}) --- now reaches the wire through the
    canonical operation layer: \texttt{SetTuningContext} is \emph{born at
    v3 unconditionally} (the same shape as \texttt{CreateInstrument}'s v2
    birth, Section~\ref{sec:evolution:major2}), since \texttt{smufl} and
    \texttt{overrides} are mandatory appends with no lower-major layout for
    this payload to fall back to. The \texttt{OperationEnvelopeBlock}
    role's accept-set therefore \textbf{widens to major~3}
    (Section~\ref{sec:evolution:gate}) --- schema major~3 stopped being the
    data-model bump under which a chunk role's max does not move in
    lockstep with the others; that distinction now belongs to no major.
  \item \textbf{The canonical base is unchanged.} The
    \texttt{MaterializedState} embeds no tuning context (nor any other
    \texttt{Score} field value), so it remains major~0, byte-identical
    across the bump --- the same keystone as majors~1 and~2, and a
    conformance test \SHOULD{} assert it again. This is unaffected by G2b:
    the canonical carrier of the tuning context is the operation log, not
    the base, so the base's own stamping never moves.
  \item The manifest stays major~0 (nothing here touches it).
\end{itemize}

\subsection{Cross-major reader behaviour}
The major-1/major-2 rules extend unchanged: the acceleration snapshot is
non-canonical, so a reader \MAY{} discard and regenerate a foreign-major one,
or migrate it on read (the reference implementation migrates). Canonical
chunks parse or the bundle opens read-only. Migration \emph{composes}: a
major-3 reader migrates a major-0 snapshot
v0${\to}$v1${\to}$v2${\to}$v3 in one read, each step total and
default-filling. As originally defined (Push~4b tranche 3b-i), no operation
payload changed at this major, so a major-2-only reader's op-block
admission was exactly as before the bump and only the \texttt{Snapshot}
role's accept-set widened, to \tablenums{3}
(Section~\ref{sec:evolution:gate}). Genesis tranche G2b (above) changes
this: a major-2-only reader now meets a possible major-3 op block
(\texttt{SetTuningContext}) and opens read-only, exactly the one-way door
Section~\ref{sec:evolution:gate} describes for every other accept-set raise.

\subsection{Changed value layout}
As in majors~1 and~2, the wire form appends new fields \emph{after} the
existing ones, independent of the core specification's presentational field
order (Section~\ref{sec:evolution:major1}'s note applies unchanged):

\begin{itemize}
  \item \texttt{ScoreTuningContext} $=$ \texttt{default\_pitch\_space} \cat{}
    \texttt{default\_tuning\_system} \cat{} \texttt{reference} (the frozen
    major-0/1/2 prefix, unchanged since major~0) \cat{}
    \textbf{\texttt{smufl}} \cat{} \textbf{\texttt{overrides}}.
    \texttt{accidental\_extensions} is \textbf{not} on the wire this major
    (see above): a decoder default-fills it, exactly as it always has, and a
    future major appends it after \texttt{overrides} when it lands.
\end{itemize}

\subsection{New leaf-type layouts}
\begin{itemize}
  \item \texttt{SmuflVersion} $=$ \texttt{major} (\texttt{u16} LE, bare) \cat{}
    \texttt{minor\_centi} (\texttt{u16} LE, bare) --- the fractional SMuFL
    version digits normalized to hundredths (1.12 $\to$ \tablenums{12}, 1.4
    $\to$ \tablenums{40}, 1.3 $\to$ \tablenums{30}) so an integer comparison
    on the pair agrees with SMuFL's real release order (1.12 shipped before
    1.3, though \tablenums{3} literally sorts before \tablenums{12}).
  \item \texttt{SmuflVersionRequirement} $=$ \texttt{minimum}
    (\texttt{SmuflVersion}) \cat{} \texttt{authored\_against}
    (\texttt{SmuflVersion}) --- $8$ bytes total, neither field framed as a
    length-prefixed leaf (both are fixed-shape bare-integer pairs).
  \item \texttt{TuningScope}: one discriminant byte \cat{} payload ---
    \tablenums{0} Voice \cat{} \texttt{VoiceId}; \tablenums{1} Staff \cat{}
    \texttt{StaffId}; \tablenums{2} Region \cat{} \texttt{RegionId};
    \tablenums{3} Range \cat{} \texttt{start} (\texttt{TimeAnchor}) \cat{}
    \texttt{end} (\texttt{TimeAnchor}) \cat{} \texttt{voices}
    (\texttt{VoiceSelector}), fields in declaration order.
  \item \texttt{TuningOverride} $=$ \texttt{scope} (\texttt{TuningScope})
    \cat{} \texttt{pitch\_space} (\texttt{Option<PitchSpaceId>}) \cat{}
    \texttt{tuning\_system} (\texttt{Option<TuningSystemId>}) \cat{}
    \texttt{reference} (\texttt{Option<ReferencePitch>}) --- one presence
    byte per \texttt{Option}, the inner catalog-id/pitch leaves under this
    chapter's regime~(a) framing (a catalog id is a length-prefixed string;
    \texttt{ReferencePitch} carries its own established layout).
\end{itemize}

\subsection{Migration from major 2}
Total and default-filling, needing no score context; composes after the
major-1 and major-2 migrations for major-1/major-0 input. The flat $12$
default bytes this migration appends (\texttt{smufl} $= 8$,
\texttt{overrides}' empty count $= 4$) are the same for every score,
independent of its other content, since neither field depends on anything
already on the wire.

\begin{center}
\begin{tabular}{p{1.9in} p{3.4in}}
  \toprule
  \textbf{major-2 form} & \textbf{major-3 form} \\
  \midrule
  \texttt{ScoreTuningContext} & append \texttt{smufl} $=$ $1.4$/$1.4$ (both
    \texttt{minimum} and \texttt{authored\_against}, the version this
    reference implementation already targets), \texttt{overrides} $=$ empty
    \\
  canonical-base \texttt{MaterializedState} & unchanged, byte-identical,
    stays major~0 \\
  \bottomrule
\end{tabular}
\end{center}

% ===========================================================================
\chapter{Non-Canonical Pinned Encodings}
\label{ch:noncanon}

\textbf{Non-canonical} means: never part of document identity. Nothing in
this chapter enters a content hash that canonical state depends on, and all
of it can be discarded and rebuilt without changing the document. The
encodings are pinned for \emph{reproducibility} --- byte-equal conformance
claims and cache correctness --- not for durability.

\section{\texttt{LayoutObjectId} (\texttt{MUSCLOID})}
\label{sec:noncanon:muscloid}

Governed by core requirement \texttt{req:layoutir:object-id-derivation}.
$\texttt{LayoutObjectId} = \mathrm{trunc128}(\mathrm{BLAKE3}(
\texttt{MUSCLOID} \cat \mathit{inputs}))$, with three preimage shapes:

\begin{description}
  \item[stable] $\mathit{inputs}$ = the source
    \texttt{TypedObjectId}'s canonical bytes.
  \item[manifestation] $\mathit{inputs}$ = source canonical bytes \cat{}
    \texttt{RegionId} canonical bytes (16 BE) --- distinct regions give one
    source distinct manifestation ids.
  \item[synthesized] $\mathit{inputs}$ = source canonical bytes \cat{}
    five \texttt{u64} LE words: the \texttt{SynthesisKind} discriminant,
    the registry id's high and low 64 bits (zero unless
    \texttt{Registered}), and the instance key's high and low 64 bits.
\end{description}

\texttt{SynthesisKind} discriminants: \tablenums{0} CancellationAccidental,
\tablenums{1} KeySignatureNatural, \tablenums{2} GeneratedRest,
\tablenums{3} EngravedBreak, \tablenums{4} MultimeasureRest,
\tablenums{5} Cautionary, \tablenums{6} Registered.

\section{\texttt{ResolvedLayoutIR} Canonical Output}
\label{sec:noncanon:resolved}

The resolved layout's canonical bytes are the \textbf{byte-equal conformance
surface} of core Chapter~7: two conforming engravers given the same score,
profile, and glyph catalog must produce identical bytes. In schema major~0 the
encoding is regime (b) (\texttt{u64} LE counts and length prefixes); schema
major~1 moves it to regime (a)'s \texttt{u32} prefixes with the rest of the
unification (Section~\ref{sec:evolution:major1}), re-locking this surface's
goldens. Because the surface is non-canonical, a reader regenerates a
foreign-major layout cache rather than decoding it. Either way every geometric
coordinate is quantized to the $1/1024$ staff-space grid as a
\texttt{QuantizedCoord} (8 LE bytes; Chapter~\ref{ch:primitives});
a non-finite or out-of-range coordinate is a determinism violation and
\MUST{} be rejected, never normalized. The top-level section order is:
source score version \cat{} pages \cat{} glyphs \cat{} strokes \cat{}
engraving decisions \cat{} glyph-catalog identity; within each section,
elements carry their provenance (built on \texttt{MUSCLOID} ids) and their
quantized geometry. The full leaf grammar is pinned by the reference
implementation's golden and round-trip anchors (Chapter~\ref{ch:goldens})
rather than restated field-by-field here, because the surface is
non-canonical and evolves with the engraving feature set.

\section{Layout Caches and Font Metrics}
\label{sec:noncanon:caches}

\texttt{LayoutCache} chunks (\texttt{ChunkKind} \tablenums{6}) hold cached
layout artifacts; they are \textbf{always discardable}, and a reader
\MUSTNOT{} treat a missing, stale, or undecodable layout cache as bundle
corruption. The glyph-metrics identity hash is domain-separated under
\texttt{MUSCFNTM} (a reserved built-in, non-canonical tag): it names the
metrics a layout was computed against, so caches and conformance runs can
detect font drift; it never enters canonical state.

% ===========================================================================
\chapter{Golden Anchor Registry}
\label{ch:goldens}

The conformance contract binding this document to the reference
implementation. Three lock classes:

\begin{description}
  \item[literal-byte] the test asserts exact expected bytes or exact
    discriminant literals --- the strongest lock;
  \item[round-trip] the test asserts $\mathrm{decode} \circ \mathrm{encode} =
    \mathrm{id}$ and re-encode byte-stability over a corpus;
  \item[canonical-equality] the test asserts that semantically equal values
    encode identically (order-independence, reduction identities).
\end{description}

The first block restates the anchors already recorded in the core
specification's \texttt{app:bytes} \sectionsc{Reference-implementation
locks} table (which governs them); the second block adds the anchors this
document introduces, which \texttt{app:bytes} predates.

Each anchor names its crate file, then the test on a second line.

\begingroup\footnotesize
\begin{longtable}{>{\raggedright\arraybackslash}p{1.5in} >{\raggedright\arraybackslash}p{3.0in} p{1.0in}}
  \toprule
  \textbf{Layout} & \textbf{Anchor} & \textbf{Class} \\
  \midrule
  \endhead
  \multicolumn{3}{l}{\emph{Imported from \texttt{app:bytes}:}} \\
  \addlinespace[2pt]
  \texttt{TypedObjectId} &
    \texttt{epiphany-core/src/ids.rs}\newline
    \texttt{::typed\ub object\ub id\ub byte\ub form\ub is\ub locked} &
    literal-byte \\
  Promoted \texttt{VoiceId} &
    \texttt{epiphany-core/src/graph.rs}\newline
    \texttt{::promoted\ub voice\ub id\ub byte\ub form\ub is\ub locked} &
    literal-byte \\
  System \texttt{PitchId} &
    \texttt{epiphany-core/src/pitch.rs}\newline
    \texttt{::system\ub pitch\ub id\ub byte\ub form\ub is\ub locked} &
    literal-byte \\
  \texttt{IntegrityAnomalyId} &
    \texttt{epiphany-ops/src/anomaly.rs}\newline
    \texttt{::integrity\ub anomaly\ub id\ub byte\ub form\ub is\ub locked} &
    literal-byte \\
  \texttt{ObjectKind} (ops) &
    \texttt{epiphany-ops/src/support.rs}\newline
    \texttt{::object\ub kind\ub discriminants\ub are\ub golden} &
    literal-byte \\
  \texttt{ChunkKind} &
    \texttt{epiphany-bundle/src/chunk.rs}\newline
    \texttt{::chunk\ub kind\ub discriminants\ub are\ub golden} &
    literal-byte \\
  \texttt{Compression\allowbreak Algorithm} &
    \texttt{epiphany-bundle/src/chunk.rs}\newline
    \texttt{::compression\ub algorithm\ub encoding\ub is\ub golden} &
    literal-byte \\
  \texttt{ProfileId} &
    \texttt{epiphany-bundle/src/superblock.rs}\newline
    \texttt{::profile\ub id\ub discriminants\ub are\ub golden} &
    literal-byte \\
  \texttt{ManifestId} &
    \texttt{epiphany-bundle/src/ids.rs}\newline
    \texttt{::manifest\ub id\ub is\ub content\ub derived\ub and\ub deterministic} &
    canonical-equality \\
  \texttt{TransactionCategory} &
    \texttt{epiphany-ops/src/payload.rs}\newline
    \texttt{::transaction\ub category\ub discriminants\ub are\ub golden} &
    literal-byte \\
  \texttt{ResolutionAction} &
    \texttt{epiphany-ops/src/conflict.rs}\newline
    \texttt{::resolution\ub action\ub discriminants\ub are\ub golden} &
    literal-byte \\
  \texttt{BlobId} &
    \texttt{epiphany-determinism/src/hash.rs}\newline
    \texttt{ContentHash::of\ub blob} tests &
    round-trip \\
  \texttt{RationalTime} &
    \texttt{epiphany-core/src/time.rs}\newline
    \texttt{::equal\ub rationals\ub encode\ub identically} &
    canonical-equality \\
  \texttt{MUSCLOID} derivation &
    \texttt{epiphany-layout-ir/src/provenance.rs}\newline
    \texttt{::stable\ub id\ub uses\ub the\ub ratified\ub muscloid\ub derivation} &
    literal-byte \\
  Domain-tag spellings &
    \texttt{epiphany-determinism/src/domain.rs}\newline
    \texttt{::exact\ub tag\ub spellings\ub match\ub spec} &
    literal-byte \\
  \addlinespace[4pt]
  \multicolumn{3}{l}{\emph{Added by this document:}} \\
  \addlinespace[2pt]
  \texttt{OperationKind} discriminants (\S\ref{sec:ops:kinds}) &
    \texttt{epiphany-ops/src/payload.rs}\newline
    \texttt{::operation\ub kind\ub wire\ub discriminants\ub are\ub golden} &
    literal-byte \\
  \texttt{OperationPayload} discriminants (\S\ref{sec:ops:payload}) &
    \texttt{epiphany-ops/src/payload.rs}\newline
    \texttt{::operation\ub payload\ub discriminants\ub are\ub golden} &
    literal-byte \\
  \texttt{OperationKindTag} (\S\ref{sec:ops:kind-tag}) &
    \texttt{epiphany-ops/src/payload.rs}\newline
    \texttt{::operation\ub kind\ub tag\ub decode\ub mirrors\ub encode\ub exactly} &
    round-trip \\
  \texttt{ResolveEquivocation} payload (\S\ref{sec:ops:payload}) &
    \texttt{epiphany-ops/src/payload.rs}\newline
    \texttt{::resolve\ub equivocation\ub payload\ub encodes\ub target\ub then\ub hash} &
    literal-byte \\
  \texttt{OperationStamp} (\S\ref{sec:ops:stamp}) &
    \texttt{epiphany-ops/src/stamp.rs}\newline
    \texttt{::stamp\ub encode\ub is\ub stable} &
    literal-byte \\
  \texttt{CausalContext} (\S\ref{sec:ops:causal}) &
    \texttt{epiphany-ops/src/causal.rs}\newline
    \texttt{::canonical\ub encoding\ub is\ub build\ub order\ub independent} &
    canonical-equality \\
  \texttt{MaterializedState} (\S\ref{sec:ops:materialized}) &
    \texttt{epiphany-ops/src/decode.rs}\newline
    \texttt{::reduced\ub states\ub decode\ub and\ub reencode} &
    round-trip \\
  Operation-index payload (\S\ref{sec:bundle:opindex}) &
    \texttt{epiphany-bundle/src/opindex.rs}\newline
    \texttt{::payload\ub encoding\ub is\ub golden} &
    literal-byte \\
  Fixed header (\S\ref{sec:bundle:header}) &
    \texttt{epiphany-bundle/src/header.rs}\newline
    \texttt{::header\ub round\ub trips} &
    round-trip \\
  Superblock (\S\ref{sec:bundle:superblock}) &
    \texttt{epiphany-bundle/src/superblock.rs}\newline
    \texttt{::superblock\ub round\ub trips\ub through\ub 256\ub bytes} &
    round-trip \\
  Chunk hash preimage (\S\ref{sec:bundle:chunks}) &
    \texttt{epiphany-bundle/src/chunk.rs}\newline
    \texttt{::hash\ub preimage\ub matches\ub the\ub spec\ub layout} &
    literal-byte \\
  \texttt{ChunkRef} (\S\ref{sec:bundle:chunkref}) &
    \texttt{epiphany-bundle/src/chunk.rs}\newline
    \texttt{::chunk\ub ref\ub round\ub trips} &
    round-trip \\
  Manifest body (\S\ref{sec:bundle:manifest}) &
    \texttt{epiphany-bundle/src/manifest.rs}\newline
    \texttt{::re\ub encode\ub is\ub byte\ub identical},
    \texttt{::manifest\ub round\ub trips},
    \texttt{::duplicate\ub roots\ub collapse\ub on\ub encode},
    \texttt{::semver\ub orders\ub numerically\ub not\ub byte\ub wise} &
    round-trip + canonical-equality \\
  Barrier kinds blob (\S\ref{sec:barriers:framing}) &
    \texttt{epiphany-layout-ir/src/barrier.rs}\newline
    \texttt{::affected\ub object\ub kinds\ub blob\ub bytes\ub are\ub golden} &
    literal-byte \\
  Barriers blob (\S\ref{sec:barriers:barrier}) &
    \texttt{epiphany-layout-ir/src/barrier.rs}\newline
    \texttt{::edit\ub barriers\ub blob\ub bytes\ub are\ub golden} &
    literal-byte \\
  Barrier variants (\S\ref{sec:barriers:barrier}) &
    \texttt{epiphany-layout-ir/src/barrier.rs}\newline
    \texttt{::every\ub scope\ub and\ub condition\ub variant\ub round\ub trips\ub byte\ub identically} &
    round-trip \\
  Whole-\texttt{Score} codec (\S\ref{sec:values:score}) &
    \texttt{epiphany-core/src/codec.rs}\newline
    \texttt{::generator\ub scores\ub round\ub trip},
    \texttt{::trailing\ub and\ub truncated\ub bytes\ub are\ub rejected} &
    round-trip \\
  \texttt{CanonicalValue} seam (\S\ref{sec:values:canonical-value}) &
    \texttt{epiphany-core/src/codec.rs}\newline
    \texttt{::value\ub types\ub round\ub trip\ub over\ub generator\ub corpus} &
    round-trip \\
  \bottomrule
\end{longtable}
\endgroup

Struct \emph{bodies} in Chapter~\ref{ch:values} are round-trip-locked rather
than literal-byte-locked: their byte identity follows from the frozen
positional rule plus the literal-byte locks on every discriminant and leaf
they embed.

\section{The Decode Vector Corpus}
\label{sec:goldens:decode-vectors}

The cross-implementation decoder test is \textbf{delivered}, as a corpus of
literal byte strings each paired with the verdict a decoder owes it. The
reference implementation carries it at \texttt{spec/vectors/decode\_vectors.txt}
and regenerates it from a committed generator, so a change to any wire form
moves the file.

Each line is \texttt{surface\ \ verdict\ \ class\ \ name\ \ hex}. The
\texttt{verdict} is \texttt{accept} or \texttt{reject}. The \texttt{class}
names \emph{why} a rejected vector is rejected and is \textbf{informative
only}: implementations need not agree on an error taxonomy.

\begin{requirement}
  \label{req:binfmt:decode-vectors}
  A conforming decoder \MUST{} accept every \texttt{accept} vector for a
  surface it implements, and \MUST{} reject every \texttt{reject} vector for
  that surface. A value decoded from an \texttt{accept} vector \MUST{}
  re-encode to exactly that vector's bytes.

  Accepting a \texttt{reject} vector and then normalizing it is
  \emph{accepting} it, and does not satisfy this requirement. Canonical decode
  is injective: distinct byte strings denote distinct values, which is what
  content-addressing rests on.
\end{requirement}

\begin{rationale}
  The corpus is not a restatement of this document; it is what a second
  implementation can be run against. Every rejection class in it is one the
  reference implementation shipped a bug in, or one whose check no injectivity
  fuzzer can see: a whole-value re-encode guard catches the fields a decoder
  \emph{normalizes} and is blind to order-preserving sequence fields, which need
  per-site order checks; and a guard on an outer value can \emph{mask} a lenient
  inner codec rather than fix it (Push~5).

  A future revision should extend the corpus to the representative struct
  layouts of Section~\ref{sec:values:representative}, which remain round-trip
  locked rather than literal-byte locked.

  \textbf{Delivered (\texttt{spec/CONTRACT\_CORE\_DECODE\_VECTORS.md}).} The
  corpus now additionally pins all five representative layouts of
  Section~\ref{sec:values:representative} (\texttt{RationalTime},
  \texttt{TimeAnchor}, \texttt{Pitch}, \texttt{Event}, \texttt{Slur}), the
  schema-major-3 tuning-context leaves (\texttt{SmuflVersion},
  \texttt{SmuflVersionRequirement}, \texttt{TuningScope},
  \texttt{TuningOverride}) and their container (\texttt{ScoreTuningContext}),
  and one whole-\texttt{Score} snapshot at each schema major
  \texttt{0}--\texttt{3}. The mandatory regression vector is the one that
  motivated this extension: bytes encoding \texttt{ScoreTuningContext} with
  \texttt{overrides} before \texttt{smufl} --- the exact self-consistent field
  swap that previously passed the entire reference-implementation suite and
  8/8 conformance, because round-trip locking cannot see a decoder and
  encoder agreeing on the wrong order. Each per-major whole-\texttt{Score}
  vector genuinely decodes at its stamped major through
  \texttt{Score::decode\ub canonical\ub versioned}; majors \texttt{0}--\texttt{2}
  assert only that decoding succeeds (a migration deliberately rewrites bytes
  to the current layout, so the injectivity check there is that the input was
  already canonical \emph{at its own major}, which the frozen per-major
  encoder's own re-encode guard already established), while major \texttt{3}
  additionally asserts the decoded value re-encodes to exactly the input
  bytes.
\end{rationale}

% ===========================================================================
\chapter{Revision History}
\label{ch:history}

\begin{longtable}{p{2cm} p{2.5cm} p{9cm}}
  \toprule
  \textbf{Date} & \textbf{Section} & \textbf{Change} \\
  \midrule
  \endhead
  \today & All & 0.1.0 --- Initial companion: ratifies the previously
  provisional whole-\texttt{Score} value codec (core P11-4), operation-layer
  wire forms (ops), bundle physical layout (bundle P11-D2/D4/D5),
  operation-index payload (P12-D1), and extension-blob/edit-barrier byte
  forms (P12-E1/E2/E3); pins the no-varint rule, the frozen-positional
  schema-evolution keystone, and the id-leads envelope property;
  \texttt{SnapshotId} derivation deferred (open question). \\
    \today & Operation wire forms & 0.2.0 --- Phase-3 first tranche: appended
  \texttt{OperationKind} wire discriminants \tablenums{24}--\tablenums{27}
  (\texttt{CreateStaff}, \texttt{SetTimeSignature},
  \texttt{SetTempoSegment}, \texttt{SetStaffLayout}) with their payload
  layouts, the matching \texttt{OperationKindTag} discriminants
  \tablenums{24}--\tablenums{27} (kind-to-tag naming gains
  \texttt{CreateStaff}~$\rightarrow$~\texttt{InsertStaff}), and
  \texttt{PreconditionFailureReason} \tablenums{11}
  (\texttt{TempoMapMalformed}) --- a schema-\emph{minor} evolution under this
  document's own append-only rules (Chapter~\ref{ch:evolution}); no existing
  assignment changed. Semantics: Operation Catalog 0.5.0 (\sectionsc{CreateStaff},
  \sectionsc{Meter and Tempo Overwrites}, \sectionsc{SetStaffLayout}, and the
  value-restoring \sectionsc{UndoTransaction} revision). \\
  \today & Schema evolution / Graph value layouts & 0.3.0 --- Defines
  \textbf{schema major~1}, the first data-model expansion major
  (Section~\ref{sec:evolution:major1}): appends \texttt{Canvas.layout\_defaults}
  (new \texttt{CanvasLayoutDefaults}/\texttt{CanvasSize}/\texttt{CanvasMargins}
  layouts, snapshot-only), \texttt{Instrument.range} (\texttt{Option<PitchRange>},
  snapshot-only), and \texttt{Region.permits\_spanning\_slurs} (also inside the
  \emph{canonical} \texttt{CreateRegion} operation payload); narrows regime~(b)
  by unifying the non-canonical resolved-layout length prefixes to \texttt{u32}
  (the manifest-embedded barrier blobs stay \texttt{u64}, partly resolving the
  standing open question); pins per-payload-type major assignment (the
  canonical-base \texttt{MaterializedState} stays major~0, byte-identical),
  the accept-set gate ($[\textsc{min},\textsc{max}]$), the cross-major reader
  rules (discard-and-regenerate non-canonical chunks; parse-or-read-only for
  canonical ones, so a major-0 reader opens a bundle with v1 \texttt{CreateRegion}
  ops read-only), and the total default-filling v0${\to}$v1 migration table.
  Clarifies that any field add is a major change regardless of
  \texttt{Option}-ness. \\
  \today & Effect vocabularies / Extension blobs & 0.4.0 --- Pass-12
  G-ratification: appends \texttt{PreconditionFailureReason}
  \tablenums{12} (\texttt{SystemDerivedContentImmutable}, P12-K3) and
  \tablenums{13} (\texttt{RecreateContentMismatch}, P12-K9), and
  \texttt{ReanchorReason} \tablenums{6} (\texttt{SameCanvasNearer},
  P12-C4) --- schema-\emph{minor} appends under Chapter~\ref{ch:evolution};
  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). \\
  \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. \\
    \today & Operation vocabularies & 0.7.0 --- Transpose algebra (Push~4a):
  appends \texttt{OperationKind} \tablenums{30}
  (\texttt{TransposeInterval}: $\mathrm{seq}^{\Uparrow}$(\texttt{PitchId})
  \cat{} two \texttt{i32}s) and the matching \texttt{OperationKindTag}
  \tablenums{30}. Every constituent is a major-0 layout, so the payload
  stamps major~\tablenums{0} and the discriminant is a schema-\emph{minor}
  vocabulary append --- no major~3. Introduces the
  $\mathrm{seq}^{\Uparrow}$ notation (strictly increasing; a decoder
  \MUST{} reject a duplicate rather than normalize it) and marks
  \tablenums{9} (\texttt{Transpose}) frozen, its
  $\mathrm{seq}^{\uparrow}$ being a multiset. Appends two
  \texttt{PreconditionFailureReason} discriminants in the same epoch,
  \tablenums{14} (\texttt{AcousticRealizationPinned}: a target whose
  \texttt{AcousticRealization::AbsoluteHz} overrides the tuning system, so
  moving its scale position would move the notehead without moving the
  sound) and \tablenums{15} (\texttt{TranspositionOutOfRange}: an
  \texttt{alteration} or \texttt{octave} driven past its \texttt{i8}
  bound, where the frozen \tablenums{9} saturates and reports success).
  No existing assignment changed. Semantics: Operation Catalog
  \sectionsc{TransposeInterval}, 0.8.0; algebra: core Chapter~2,
  \sectionsc{Transposition and the Interval Type}. \\
    \today & Chunk references & 0.8.0 --- Strict \texttt{CompressionAlgorithm}
  decode (Push~5, P3): \texttt{req:binfmt:compression-none-parameter} \MUST{}
  reject a non-zero parameter byte on the \texttt{None} discriminant. Ignoring
  it made the codec non-injective --- two byte strings, one value --- which
  every structure embedding a \texttt{ChunkRef} inherited; the operation index,
  having no whole-value re-encode guard, accepted both. Found by the wire-decode
  fuzzer. Supersedes the core specification's ``ignored on read''; no wire
  layout changed and no conforming writer is affected. \\
    \today & Golden anchors & 0.9.0 --- Ratifies the decode vector corpus
  (Push~5, P4): \texttt{req:binfmt:decode-vectors} and
  Section~\ref{sec:goldens:decode-vectors}. The cross-implementation decoder
  test moves out of the \sectionsc{About This Companion} exclusion list and out
  of the \sectionsc{Golden Anchor Registry}'s ``deferred conformance harness''
  note: literal byte vectors with accept/reject verdicts now exist
  (\texttt{spec/vectors/decode\_vectors.txt}), and a conforming decoder owes them
  the verdict. Accepting a \texttt{reject} vector and normalizing it is
  \emph{accepting} it. The wire-format fuzzer remains an implementation
  deliverable. No wire layout changed. \\
    \today & Schema evolution / Graph value layouts & 0.10.0 --- Defines
  \textbf{schema major~3} (Section~\ref{sec:evolution:major3}, Push~4b
  tranche 3b-i): \texttt{ScoreTuningContext} gains \texttt{smufl}
  (\texttt{SmuflVersionRequirement}) and \texttt{overrides}
  ($\mathrm{seq}$(\texttt{TuningOverride})) on the canonical wire, with
  layouts for the four new leaf types (\texttt{SmuflVersion},
  \texttt{SmuflVersionRequirement}, \texttt{TuningScope},
  \texttt{TuningOverride}) and the total default-filling v2${\to}$v3
  migration table. \texttt{accidental\_extensions} is deliberately staged to
  a later major (no consumer yet) and stays off the wire. Reaches only the
  acceleration full-\texttt{Score} snapshot --- no operation payload embeds
  the tuning context, so the canonical operation layer and its accept-set
  are untouched (the first data-model major under which a chunk role's max
  does not move in lockstep with the others); the canonical base and
  manifest stay major~0, byte-identical. Accept-set: \texttt{Snapshot}
  widens to \tablenums{3}, \texttt{OperationEnvelopeBlock} stays at
  \tablenums{2}. Semantics: core specification Chapter~4, \sectionsc{Score
  Tuning Context} / \sectionsc{SMuFL Versioning}; the staging ruling itself
  is Push~4b's own (\texttt{spec/CONTRACT\_PUSH4B\_3BI\_WIRE.md}). \\
    \today & Golden anchors & 0.11.0 --- Extends the decode vector corpus
  (Section~\ref{sec:goldens:decode-vectors}) to \texttt{epiphany-core}'s score
  wire, closing the gap \S0.9.0 left open and delivering the ``future
  revision'' this section's own rationale anticipated: all five
  representative layouts of Section~\ref{sec:values:representative}
  (\texttt{RationalTime}, \texttt{TimeAnchor}, \texttt{Pitch}, \texttt{Event},
  \texttt{Slur}), the schema-major-3 tuning-context leaves and their
  container, and one whole-\texttt{Score} vector per schema major
  \texttt{0}--\texttt{3}. Includes the mandatory regression vector for the
  tranche-3b-i defect (a swapped \texttt{smufl}/\texttt{overrides} field
  order, which previously passed round-trip locking and 8/8 conformance).
  No wire layout changed; no existing vector's bytes moved
  (\texttt{spec/CONTRACT\_CORE\_DECODE\_VECTORS.md}). \\
    \today & Operation wire forms & 0.12.0 --- Genesis tranche G2a
  (\texttt{spec/CONTRACT\_GENESIS\_G2A\_SETTINGS.md}), plus the repair of a
  G1 omission this document's own contract wrongly declared out of scope.
  Appends \texttt{OperationKind} wire discriminants \tablenums{31}
  (\texttt{CreateInstrument}, genesis tranche G1 --- landed at
  \texttt{3b09595} with no matching entry here), \tablenums{32}
  (\texttt{SetCanvasLayoutDefaults}), and \tablenums{33}
  (\texttt{SetSpellingPrecedence}), with their payload layouts, and the
  matching \texttt{OperationKindTag} discriminants \tablenums{31}--\tablenums{33}
  (name-verbatim projection, as the two most recent prior additions are) ---
  schema-\emph{minor} evolutions under this document's own append-only
  rules; no existing assignment changed. \texttt{CreateInstrument} embeds
  the full \texttt{Instrument} value and is \emph{born at v2}
  unconditionally (Section~\ref{sec:evolution:major2}), which the
  Section~\ref{sec:evolution:major1}/\ref{sec:evolution:major2}
  ``Where the changed fields reach'' bullets are corrected to name: neither
  \texttt{Instrument} nor \texttt{Canvas.layout\_defaults} is
  snapshot-only any longer, and the \sectionsc{Schema Major 2} canonical
  operation-layer count moves from eight payloads to nine. Both new G2a
  payloads --- \texttt{SetCanvasLayoutDefaultsOp} and
  \texttt{SetSpellingPrecedenceOp} --- carry only major-0 layouts (neither
  carried type has ever been versioned as a standalone value), so no
  accept-set moves: \texttt{OperationEnvelopeBlock} stays at
  \tablenums{2}. The chunk schema \emph{minor} is knowingly still not
  stamped for any of \tablenums{24}--\tablenums{33} (filed as P13-S14, a
  retroactive sweep sequenced after this rung). Semantics: Operation
  Catalog \sectionsc{CreateInstrument} (retroactive),
  \sectionsc{SetCanvasLayoutDefaults}, \sectionsc{SetSpellingPrecedence},
  0.10.0. \\
    \today & Schema Evolution & 0.13.0 --- G-minor
  (\texttt{spec/CONTRACT\_GMINOR\_IMPLEMENTATION.md},
  \texttt{spec/PLAN\_GMINOR\_SCHEMA\_MINOR.md}): implements the minor
  \MUST{} of Section~\ref{sec:evolution:gate} for the first time
  (\texttt{binary\_format.tex:2330}, unchanged in substance, wired to a real
  writer-side derivation for the first time). Adds the global additive-epoch
  derivation (this chapter, \sectionsc{What ``Additive'' Means Here}) and
  repairs the stale \tablenums{30} next-free-slot narrative this section
  previously carried, which omitted \tablenums{30}--\tablenums{33}
  (\texttt{TransposeInterval}, \texttt{CreateInstrument},
  \texttt{SetCanvasLayoutDefaults}, \texttt{SetSpellingPrecedence}) from both
  the number and the history; the normative kind and tag tables were already
  current. No discriminant, wire layout, or accept-set changes: this is a
  correction to prose and a new writer-side derivation, not a new appended
  variant. \\
    \today & Operation wire forms & 0.14.0 --- Genesis tranche G2b
  (\texttt{spec/CONTRACT\_GENESIS\_G2B\_TUNING.md}): appends
  \texttt{OperationKind} wire discriminant \tablenums{34}
  (\texttt{SetTuningContext}) with its payload layout, and the matching
  \texttt{OperationKindTag} discriminant \tablenums{34} (name-verbatim,
  following the three most recent prior additions rather than the tag
  space's older Create$\rightarrow$Insert convention) --- a
  schema-\emph{minor} evolution (epoch~10,
  \texttt{spec/PLAN\_GMINOR\_SCHEMA\_MINOR.md} \S4) under this document's
  own append-only rules; no existing assignment changed. The payload
  carries \texttt{epiphany\_core::TuningContextSettings}, the
  \textbf{five-field authored subset} of \texttt{ScoreTuningContext} ---
  not the full graph type --- byte-identical to the existing
  schema-major-3 wire walk, so that \texttt{accidental\_extensions}
  (staged off the wire) cannot diverge between a live-authored session and
  the same document reloaded from bytes. \texttt{SetTuningContext} is the
  \textbf{sole genesis payload born at v3 unconditionally}
  (Section~\ref{sec:evolution:major3}), so \texttt{OperationEnvelopeBlock}'s
  accept-set raises \tablenums{2}~$\rightarrow$~\tablenums{3} --- the
  first accept-set move since genesis tranche G2a explicitly recorded
  staying at \tablenums{2}. Semantics: Operation Catalog
  \sectionsc{SetTuningContext}, 0.11.0. \\
    \today & Operation wire forms & 0.15.0 --- Genesis tranche G3a
  (\texttt{spec/CONTRACT\_GENESIS\_G3A\_ENTITIES.md}): appends
  \texttt{OperationKind} wire discriminants \tablenums{35}--\tablenums{38}
  (\texttt{CreateStaffGroup}, \texttt{CreatePartDefinition},
  \texttt{CreateAnalysisLayer}, \texttt{CreateView}) with their payload
  layouts, and the matching \texttt{OperationKindTag} discriminants
  \tablenums{35}--\tablenums{38} (name-verbatim, following the two most
  recent additions rather than the tag space's older Create$\rightarrow$Insert
  convention) --- a schema-\emph{minor} evolution (epoch~11,
  \texttt{spec/PLAN\_GMINOR\_SCHEMA\_MINOR.md} \S4) under this document's own
  append-only rules; no existing assignment changed. All four carried types
  (\texttt{StaffGroup}, \texttt{PartDefinition}, \texttt{AnalysisLayer},
  \texttt{ViewDefinition}) have never been versioned as standalone values, so
  no accept-set moves: \texttt{OperationEnvelopeBlock} stays at
  \tablenums{3} where genesis tranche G2b left it. Semantics: Operation
  Catalog \sectionsc{CreateStaffGroup}, \sectionsc{CreatePartDefinition},
  \sectionsc{CreateAnalysisLayer}, \sectionsc{CreateView}, 0.12.0. \\
    \today & Operation wire forms & 0.16.0 --- Genesis tranche G3b
  (\texttt{spec/CONTRACT\_GENESIS\_G3B\_MEASURE.md}), the final rung of the
  genesis operation tranche: appends \texttt{OperationKind} wire discriminant
  \tablenums{39} (\texttt{CreateMeasure}) with its payload layout, and the
  matching \texttt{OperationKindTag} discriminant \tablenums{39}
  (name-verbatim, following the four most recent additions rather than the
  tag space's older Create$\rightarrow$Insert convention) --- a
  schema-\emph{minor} evolution (epoch~12,
  \texttt{spec/PLAN\_GMINOR\_SCHEMA\_MINOR.md} \S4) under this document's own
  append-only rules; no existing assignment changed. Also appends three
  \texttt{PreconditionFailureReason} discriminants, \tablenums{16}--\tablenums{18}
  (\texttt{MeasureMeterMismatch}, \texttt{MeasureOutOfOrder},
  \texttt{MeasureOrderUnverifiable}), the same epoch. \texttt{Measure} has
  never been versioned as a standalone value --- its only non-scalar field,
  \texttt{TimeAnchor}, has a hand-written codec with no version branching of
  its own --- so \texttt{CreateMeasure} is schema major~0 unconditionally and
  no accept-set moves: \texttt{OperationEnvelopeBlock} stays at
  \tablenums{3} where genesis tranche G2b left it. This closes the genesis
  ladder: G1 $\rightarrow$ G2a $\rightarrow$ G-minor $\rightarrow$ G2b
  $\rightarrow$ G3a $\rightarrow$ G3b. Semantics: Operation Catalog
  \sectionsc{CreateMeasure}, 0.13.0. \\

    \today & The Fixed Header & 0.17.0 --- The container format major becomes
  \tablenums{1}, and \texttt{format\_minor} restarts at \tablenums{0}
  (\texttt{spec/CONTRACT\_FORMAT\_EPOCH\_MAJOR1.md}). This is the first
  \emph{container} major boundary, and it is not a change of wire layout: no
  field moves, no offset changes, and every byte range in the header table is
  what it was. What changes is what the major \emph{means}. A major-1 container
  is one whose every base-bearing commit was validated against a supplied
  reduction authority; major \tablenums{0} is legacy and \MUST{} be decoded
  deliberately as such rather than rejected.

  The major is the carrier precisely because the header never changes after
  creation. A superblock field could not do this job: a legacy container that
  later commits a validated base would keep carrying whatever its creation
  stamped, so provenance would be inheritable by a document that never earned
  it. A minor bump could not do it either --- readers ignore minor, and this
  document's own rules limit a minor change to appending append-safe
  discriminants, whereas making a previously-valid canonical base newly
  rejectable is a semantic acceptance change. The full epoch matrix, including
  the rule that a legacy container may open but \MUSTNOT{} acquire a canonical
  base, is normative in the Core Specification,
  \sectionsc{The Container Epoch}. \\
\bottomrule
\end{longtable}

\end{document}
