Push 3 ratify: extend the slur-rendering requirement + refresh slur_shape

The three slur refinements (dashed rendering, curve splitting, slur_shape
measured) lifted into the spec — Chapter 7 / Quality Metric Catalog only,
non-canonical, so no wire form and no companion-version move.

core_spec Ch7: req:layoutir:slur-curve extended — an authored non-Solid
SpanStyle line renders faithfully (the LineStyle rides the Curve, whose listing
gains the field); a slur spanning a system break splits into per-system
sub-curves (de Casteljau; first segment keeps the slur's provenance, the rest
synthesized continuations). Only the curvature-computing algorithm stays
forward-referenced out now (dash rendering no longer deferred).

quality_metric_catalog: the §slur_shape rationale and the notated-but-unrendered
open question refreshed to record slurs now render and are measured; the formula
(req:qmc:slur) is unchanged, so no catalog version move.

Revision-history row (Push 3); a Push-3 tranche in PASS12_RATIFICATION_LOG.md;
layout-ir DECISIONS cross-ref extended. Both specs build clean (latexmk
-xelatex, 0 undefined refs). No code change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Levi Neuwirth 2026-07-08 17:33:11 -04:00
parent 7d61271069
commit 449dd2ef8e
6 changed files with 79 additions and 19 deletions

View File

@ -571,9 +571,15 @@ these are E1 implementation decisions for the Phase-F ratification pass:
> `req:layoutir:resolved-primitives` in core spec Chapter 7 (§ResolvedLayoutIR) > `req:layoutir:resolved-primitives` in core spec Chapter 7 (§ResolvedLayoutIR)
> — the struct listing now carries `strokes`/`curves` and the `Stroke`/`Curve` > — the struct listing now carries `strokes`/`curves` and the `Stroke`/`Curve`
> shapes, and the RenderIR provenance requirement was widened to name all three > shapes, and the RenderIR provenance requirement was widened to name all three
> primitive kinds. The curvature *algorithm* and dash rendering stay > primitive kinds. Non-canonical, so no wire/companion-version change
> forward-referenced out. Non-canonical, so no wire/companion-version change
> (PASS12_RATIFICATION_LOG.md, schema-major-2 tranche). > (PASS12_RATIFICATION_LOG.md, schema-major-2 tranche).
>
> **Extended (Push 3, 2026-07-08):** the three E2 deferrals landed and
> `req:layoutir:slur-curve` was extended — dashed/dotted lines render faithfully
> (the `Curve` listing gains `line`), break-spanning slurs split into per-system
> sub-curves (de Casteljau), and `slur_shape_penalty` is measured (only the
> curvature *algorithm* stays forward-referenced out now). See the Push-3
> tranche in PASS12_RATIFICATION_LOG.md and the engrave DECISIONS.
The third pipeline primitive kind. Primitives were two parallel flat Vecs The third pipeline primitive kind. Primitives were two parallel flat Vecs
(`glyphs`, `strokes`) at each of the three IR stages; a `Curve` (four control (`glyphs`, `strokes`) at each of the three IR stages; a `Curve` (four control

View File

@ -208,3 +208,30 @@ stays 0.6.0 — layout geometry is non-canonical.
curve splitting (de Casteljau), and the `slur_shape` quality metric moving off curve splitting (de Casteljau), and the `slur_shape` quality metric moving off
`0.0`-by-construction — all Standard-tier / Push-3 work, named in the crate `0.0`-by-construction — all Standard-tier / Push-3 work, named in the crate
DECISIONS, none a Pass-13 ambiguity. DECISIONS, none a Pass-13 ambiguity.
## Push-3 tranche (2026-07-08) — slur rendering completion
The three slur refinements the schema-major-2 Phase-F ratification deferred,
landed and ratified. Layout-IR (Chapter 7) only, non-canonical — a
ratify-as-implemented with **no wire form and no companion version move**
(mirrors the schema-major-2 rendering tranche). Delivered as commits `c5173d2`
(dashed rendering), `5869691` (curve splitting), `7d61271` (slur_shape
measured).
| Item | Disposition | Spec locus | Consumer |
|---|---|---|---|
| Dashed/dotted slur rendering | **adopt**`req:layoutir:slur-curve` extended: an authored non-`Solid` `SpanStyle` line renders faithfully (the `LineStyle` rides the `Curve`, whose Ch7 listing gains the field); an implementation that defers the pattern must surface it, never silently render solid. The E2 `SlurLineStyleNotRendered` diagnostic is retired (the style is rendered, not deferred) | core_spec Ch7 §ResolvedLayoutIR (`req:layoutir:slur-curve`, `Curve` listing) | `epiphany-layout-ir` (`Curve.line`); `epiphany-render-svg` (`stroke-dasharray`) |
| Curve splitting across systems | **adopt**`req:layoutir:slur-curve` extended: a slur spanning a system break splits into per-system sub-curves by de Casteljau (first segment keeps the slur's provenance, the rest synthesized continuations under `req:layoutir:continuation-synthesis`), replacing E2's draw-whole-in-start-system floating end | core_spec Ch7 §ResolvedLayoutIR (`req:layoutir:slur-curve`) | `epiphany-engrave` (casting `curve_fate`, `sub_cubic`) |
| slur_shape measured | **adopt (implement pinned formula)**`slur_shape_penalty` moves off its `0.0` placeholder to the catalog's pinned `req:qmc:slur` formula (arc ratio ρ = apex/chord against the `[0.08, 0.25]` band). The Quality Metric Catalog's §`slur_shape` rationale and the notated-but-unrendered open question are refreshed to record slurs now render and are measured; the formula is unchanged, so no catalog version move | quality_metric_catalog §`slur_shape_penalty` (`req:qmc:slur`, rationale) | `epiphany-engrave` (`quality.rs::slur_shape_raw`) |
**Version movements.** None: core spec Ch7 `req:layoutir:slur-curve` extended +
the `Curve` listing gains `line`; a revision-history row (Push 3); the Quality
Metric Catalog rationale refreshed (no formula change). Operation Catalog stays
0.7.0, Binary Format 0.6.0, Quality Metric Catalog 0.2.0 — all non-canonical /
formula-stable.
**Deferred (documented, not open candidates).** Kind-differentiated slur
appearance (Phrase/Editorial's own line, distinct from the SpanStyle dash),
duration-aware slur height (would pull the clamped short/long slurs back into
the shallow-arc band), collision-aware slur reshaping (the Standard-tier
`slur_shape` driver) — all Standard-tier work.

Binary file not shown.

View File

@ -9289,6 +9289,10 @@ pub struct Curve {
pub thickness: StaffSpace, pub thickness: StaffSpace,
pub layer: i32, pub layer: i32,
pub style: GlyphStyle, pub style: GlyphStyle,
/// The line pattern the renderer strokes the path with
/// (a slur's authored `SpanStyle.line`): solid, dashed, or dotted.
pub line: LineStyle,
} }
\end{lstlisting} \end{lstlisting}
@ -9333,19 +9337,24 @@ pub struct Curve {
\begin{requirement} \begin{requirement}
\label{req:layoutir:slur-curve} \label{req:layoutir:slur-curve}
\textbf{Minimal-tier slur rendering (ratified schema-major-2, \textbf{Slur rendering (ratified schema-major-2, Phase~F; extended
Phase~F).} A \texttt{Slur} (\ref{sec:graph:slurs}) \MUST{} render Push~3).} A \texttt{Slur} (\ref{sec:graph:slurs}) \MUST{} render
as a cubic-B\'ezier \texttt{Curve} arcing between its two endpoint as a cubic-B\'ezier \texttt{Curve} arcing between its two endpoint
event columns, honoring an authored \texttt{CurvatureOverride} event columns, honoring an authored \texttt{CurvatureOverride}
(direction and apex height) when present and choosing them (direction and apex height) when present and choosing them
otherwise. A slur whose endpoint does not resolve to a column on a otherwise. A slur whose endpoint does not resolve to a column on a
single staff of one region draws \emph{no} curve: a traced anchor single staff of one region draws \emph{no} curve: a traced anchor
preserves its provenance rather than a floating arc. An authored preserves its provenance rather than a floating arc. An authored
non-\texttt{Solid} \texttt{SpanStyle} line (dashed, dotted) \MAY{} non-\texttt{Solid} \texttt{SpanStyle} line (dashed, dotted) is
be deferred to a higher tier, but \MUST{} be surfaced (a layout rendered faithfully as that pattern (its \texttt{LineStyle} rides
diagnostic), never silently rendered solid. The curvature-computing the \texttt{Curve}); an implementation that instead defers the
algorithm and the dash rendering are engraving-specification pattern \MUST{} surface the deferral (a layout diagnostic), never
concerns (\ref{sec:layoutir:forward}). silently rendering solid. A slur whose span crosses a system break
\MUST{} split into per-system sub-curves --- the first carrying the
slur's provenance, the rest engraver-synthesized continuations
(\ref{req:layoutir:continuation-synthesis}) --- rather than drawing
whole in one system. The curvature-computing algorithm remains an
engraving-specification concern (\ref{sec:layoutir:forward}).
\end{requirement} \end{requirement}
\section{RenderIR (Interface Only)} \section{RenderIR (Interface Only)}
@ -15507,6 +15516,19 @@ layouts they own versus inherit:
moves --- an engrave-side ratify-as-implemented, mirroring the moves --- an engrave-side ratify-as-implemented, mirroring the
schema-major-1 Phase~F precedent. schema-major-1 Phase~F precedent.
\\ \\
\today & Layout IR (slur rendering completion, Push 3) &
The three slur refinements \ref{req:layoutir:slur-curve} deferred are
now landed and its requirement extended: an authored non-\texttt{Solid}
\texttt{SpanStyle} line renders faithfully (dashed / dotted --- the
\texttt{LineStyle} rides the \texttt{Curve}, whose listing gains the
field), a slur spanning a system break splits into per-system
sub-curves (de~Casteljau; first segment keeps the slur's provenance,
the rest synthesized continuations), and \texttt{slur\_shape\_penalty}
moves off its pinned $0.0$ to a real measurement (Quality Metric
Catalog \sectionsc{slur\_shape\_penalty} rationale refreshed; formula
unchanged, no version move). Layout geometry stays non-canonical --- no
wire form, no companion version moves.
\\
\bottomrule \bottomrule
\end{longtable} \end{longtable}

Binary file not shown.

View File

@ -601,18 +601,19 @@ all} and claims no conformance tier (the core's \texttt{Stub} tier).
\begin{openquestion} \begin{openquestion}
\textbf{The notated-but-unrendered honesty edge.} A score whose \textbf{The notated-but-unrendered honesty edge.} A score whose
\emph{source} notates slurs, engraved by a solver that draws no slur \emph{source} notates geometry a solver does not draw scores
geometry, scores $\texttt{slur\_shape\_penalty} = 0.0$ under this rule --- vacuous-$0.0$ on that axis under this rule --- the axis sees nothing
the axis sees no drawn slurs and finds nothing to penalize, even though drawn and finds nothing to penalize, even though the output is arguably
the output is arguably \emph{worse} than a badly-drawn slur. v0.1 \emph{worse} than a badly-drawn one. The metric axes evaluate the geometry
deliberately pins vacuous-$0.0$: the metric axes evaluate the geometry the the solver produced, and \emph{rendering completeness} --- whether notated
solver produced, and \emph{rendering completeness} --- whether notated
content is realized at all --- is governed by constraint families and content is realized at all --- is governed by constraint families and
visual acceptance testing, not by the quality metrics. Should a future visual acceptance testing, not by the quality metrics. Should a future
revision instead score notated-but-unrendered geometry classes at the revision instead score notated-but-unrendered geometry classes at the
worst value, so that the metric vector cannot flatter an incomplete worst value, so that the metric vector cannot flatter an incomplete
renderer? Resolving this requires a normative definition of ``notated renderer? Resolving this requires a normative definition of ``notated
content that demands drawn geometry,'' which does not exist yet. content that demands drawn geometry,'' which does not exist yet.
\emph{Slurs no longer instance this edge} (they render and are measured,
schema-major-2); it persists for still-logical-only classes such as beams.
\end{openquestion} \end{openquestion}
\section{Normalization Form} \section{Normalization Form}
@ -814,10 +815,14 @@ The anchor makes a semicircular slur ($\rho = 0.5$, $\mathit{raw}_u =
0.25$) exactly worst-tolerable, and a completely flat slur ($\rho = 0$, 0.25$) exactly worst-tolerable, and a completely flat slur ($\rho = 0$,
$\mathit{raw}_u = 0.08$) roughly a third of the way to failing. $\mathit{raw}_u = 0.08$) roughly a third of the way to failing.
The v0.1 reference pipeline draws no slur geometry (slurs exist logically, The implementation now \emph{draws} slurs as cubic-B\'ezier curves and
not as curves), so this axis evaluates to $0.0$ today under the measures this axis directly (schema-major-2 rendering; the first
vacuous-geometry rule --- the definition is pinned now so that the first slur-drawing release, as the pinned definition anticipated). A layout with
implementation to draw slurs is measured from its first release. no drawn slur curve still evaluates to $0.0$ under the vacuous-geometry
rule. A tier that draws the ideal shallow arc for every slur measures $0$
on this axis; a fixed-height engraver scores non-zero on slurs whose span
pushes the arc ratio outside the $[0.08, 0.25]$ band (a very short or very
long slur), which a duration-aware height corrects.
\end{rationale} \end{rationale}
\section{\texttt{beam\_slope\_penalty}} \section{\texttt{beam\_slope\_penalty}}