Schema major 1 Phase F: ratify engrave I8/I9/I10 + process trail
Spec/process only, no code. Closes the schema-major-1 track (Phases A-F): the two data-model batch rows parked behind the frozen-layout rule (P12-I7, P12-K7) landed via Phases C/D1, and the three engrave/layout-ir dispositions the implementation already made are ratified into the core spec. - core_spec: three normative requirements ratifying the implemented behavior -- break-constraint satisfaction (req:layoutir:break-satisfaction, I8: a SystemBreakAt/PageBreakAt is satisfied iff the final ResolvedLayoutIR starts a system/page at that slot), break-override attribution via a ConstrainedLayoutIR.break_origins sidecar declining to widen the constraint record (req:layoutir:break-origin-attribution, I9), and system-continuation synthesis Registered(SYSTEM_CONTINUATION_SYNTHESIS) with an (original, ordinal) instance key (req:layoutir:continuation-synthesis, I10). Revision-history row. PDF rebuilt (latexmk -xelatex, 0 undefined refs). - PASS12_RATIFICATION_LOG: schema-major-1 tranche (I7/K7 landed + I8/I9/I10 adopt), with the open cross-region-slur item flagged. - PASS12_BATCH: struck I7/K7/I8/I9/I10; added P12-K12 (which region governs a cross-region slur's spanning permission -- implemented as conservative AND). - engrave/layout-ir DECISIONS: ratification cross-refs; the P12-I7 note reworded so deferred Phase C' does not read as landed. - .gitignore: spec/*.xdv (xelatex intermediate; the tracked PDF is committed). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NEs4aYiu8MXjdYdMxw8PTd
This commit is contained in:
parent
64de92605f
commit
7045a13a18
|
|
@ -22,3 +22,4 @@ spec/*.fls
|
|||
spec/*.log
|
||||
spec/*.out
|
||||
spec/*.toc
|
||||
spec/*.xdv
|
||||
|
|
|
|||
|
|
@ -116,9 +116,11 @@ inputs the solver cannot measure.
|
|||
schema major. **Schema major 1 now defines the type** (`CanvasLayoutDefaults
|
||||
{ page_size: CanvasSize, margins: CanvasMargins }`, staff spaces, A4/8mm
|
||||
default) and ratifies its wire form (core spec + Binary Format 0.3.0,
|
||||
Phase A); the **code graph home lands in Phase C** (`Canvas` gains the
|
||||
field) and the engraver reads it in Phase C′. Until then the engraver takes
|
||||
the geometry as a constructor parameter. Default arithmetic (1 staff space = staff height / 4 = 2.0 mm at
|
||||
Phase A); the **code graph home landed in Phase C** (`Canvas` gained the
|
||||
field). Wiring the engraver to *read* it (Phase C′) is a byte-neutral
|
||||
follow-up **deferred** until a custom-geometry producer exists, so the
|
||||
engraver still takes the geometry as a constructor parameter (every score's
|
||||
`layout_defaults` is the A4 default today). Default arithmetic (1 staff space = staff height / 4 = 2.0 mm at
|
||||
an 8 mm staff): A4 210 × 297 mm → **105 × 148.5** staff spaces; 15 mm
|
||||
margins → **7.5** staff spaces; content area 180 × 267 mm → **90 × 133.5**
|
||||
staff spaces. 90 staff spaces wraps the ten-measure hand-off fixture
|
||||
|
|
@ -390,3 +392,14 @@ testkit's reference-suite harness.
|
|||
floor). The alternative — a duration-proportional (optical) redefinition —
|
||||
needs the pipeline's deferred duration-aware preferred widths and stays the
|
||||
catalog's open question.
|
||||
|
||||
## Break-constraint satisfaction predicate (Pass 12 P12-I8, ratified)
|
||||
|
||||
The break-constraint satisfaction predicate — a `SystemBreakAt`/`PageBreakAt` at
|
||||
`slot` is satisfied iff the final `ResolvedLayoutIR` starts a system/page at that
|
||||
slot (a region-first slot trivially) — was ratified into the core spec by the
|
||||
schema-major-1 track's Phase F (2026-07-06; core spec
|
||||
`req:layoutir:break-satisfaction`; `spec/PASS12_RATIFICATION_LOG.md`,
|
||||
schema-major-1 tranche). Satisfaction is a predicate on the output layout, not
|
||||
the solver's spring state; casting-off evaluates the declared hard break
|
||||
constraints as part of its tier claim.
|
||||
|
|
|
|||
|
|
@ -445,3 +445,23 @@ all-worst `unmeasured()` vector, which a transcription test pins as excluded
|
|||
by the Minimal column ("measuring is part of the Minimal claim"). The catalog
|
||||
also blesses the existing `TieBreakingWeights::default()` (all 1.0) as the
|
||||
normative defaults — pinned by test rather than re-declared.
|
||||
|
||||
## Break-origin attribution and system-continuation synthesis (Pass 12 P12-I9/I10, ratified)
|
||||
|
||||
Two long-standing layout-ir dispositions were ratified into the core spec by the
|
||||
schema-major-1 track's Phase F (2026-07-06; `spec/PASS12_RATIFICATION_LOG.md`,
|
||||
schema-major-1 tranche):
|
||||
|
||||
- **P12-I9 — break-override attribution via a sidecar.** Honouring a user break
|
||||
carries `DecisionSource::UserOverride(id)`, but a normalized break *constraint*
|
||||
(`SystemBreakAt`/`PageBreakAt`) carries no override identity. Attribution is
|
||||
threaded through a `ConstrainedLayoutIR.break_origins` sidecar populated by
|
||||
`to_constrained`; the normalized constraint record is deliberately **not**
|
||||
widened (attribution is a projection concern, not a solver input). Ratified as
|
||||
core spec `req:layoutir:break-origin-attribution`.
|
||||
- **P12-I10 — system-continuation synthesis.** A stroke spanning a system
|
||||
boundary is split; the post-first segments are synthesized under
|
||||
`SynthesisKind::Registered(SYSTEM_CONTINUATION_SYNTHESIS)` with a
|
||||
`(original, ordinal)` `stable_semantic_instance_key`. Since `LayoutObjectId`s
|
||||
are non-canonical and re-derived per layout, the key need only be stable within
|
||||
a layout. Ratified as core spec `req:layoutir:continuation-synthesis`.
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ code instead is the failure mode this batch exists to prevent.
|
|||
| P12-C4 | `epiphany-ops` C | `ReanchorReason` has no same-canvas variant: a rank-4 (same-canvas) survivor is recorded `ExplicitFallback` rather than appending a discriminant. Ratify a beyond-region reason or bless the fallback recording. | G / Pass 12 (re-anchoring) |
|
||||
| P12-K5 | `epiphany-ops` K | Equivocation resolution's third path — a profile-declared deterministic selection function (e.g. lowest-hash-wins) — is unpinned and unimplemented; the reducer has no policy hook. Referenced from the catalog §ResolveEquivocation rationale. | G / Pass 12 (equivocation) |
|
||||
| P12-K6 | `epiphany-ops` K | `ResolveEquivocation` edge semantics to pin: cascaded resolves (a promoted candidate that is itself a resolve does not govern a further promotion — single-pass implemented, vs. fixpoint); interaction with HLC-monotonicity quarantine (may a quarantined resolve govern?); a resolve held pending by its own causal gaps still governs promotion (set-level rule) while its effect stays pending; whether the invalid-target/chosen no-op warrants a dedicated `PreconditionFailureReason` (implemented: reuses `TargetMissing`). | G / Pass 12 (equivocation) |
|
||||
| P12-K7 | `epiphany-ops` K | Advisory-precondition catalog: the spec declares the duration-boundary advisory only for InsertEvent while the implementation also applies it to ModifyEvent's replacement value — state ModifyEvent's bucket explicitly. Also: which advisory checks are blocked on graph-model completion (Instrument declared range; a Region slur-spanning permission flag; which extent shapes constitute a resolvable musical end bound). | G / Pass 12 (validation) |
|
||||
| ~~P12-K7~~ **RATIFIED (schema-major-1 track, 2026-07-06; see PASS12_RATIFICATION_LOG)** | `epiphany-ops` K | Advisory-precondition catalog: the spec declares the duration-boundary advisory only for InsertEvent while the implementation also applies it to ModifyEvent's replacement value — state ModifyEvent's bucket explicitly. Also: which advisory checks are blocked on graph-model completion (Instrument declared range; a Region slur-spanning permission flag; which extent shapes constitute a resolvable musical end bound). | G / Pass 12 (validation) |
|
||||
| P12-I4 | `epiphany-layout-ir` I | Constraint-strength attachment: Ch9 defines `ConstraintStrength` and says the solver consumes constraints "in normalized form", but neither the normalized form nor Ch7's `LayoutConstraint` provides a channel for an instance to carry strength. Implemented rule: break strength = `BreakKind` (Hard→Required, Soft→Preferred{1.0}); other core families Required; `Registered` conservative Required. Bless the rule or add a strength field. | G / Pass 12 (solver) |
|
||||
| P12-I5 | `epiphany-layout-ir` I | No renderable status exists for "constraints present but not evaluated": every renderable `SolveStatus` is documented as "all hard constraints satisfied", leaving a below-conformance passthrough solver no honest report. Implemented encoding: `SolvedWithWarnings` + `satisfied_hard_constraints == false` + a warning. Sanction it or define a non-evaluating-tier report shape. | G / Pass 12 (solver) |
|
||||
| P12-I6 | `epiphany-layout-ir` I | The spacing pass MUST "build collision constraints" but no per-tier minimum emission set is named. Implemented floor: successive-notehead-column no-collision chains + per-glyph region containment + user-break constraints. A normative Minimal-tier floor would make the acceptance surface testable. | G / Pass 12 (solver) |
|
||||
|
|
@ -62,10 +62,11 @@ code instead is the failure mode this batch exists to prevent.
|
|||
| P12-K9 | `epiphany-ops` K | Differing-value re-creates (a live id re-carried with different content: `CreateStaff`, the carried `TimeSignature`, container creates) refuse with `TargetMissing`, which misnames the situation. Decide whether a dedicated `PreconditionFailureReason` (appended) is warranted. | G / Pass 12 (vocabulary) |
|
||||
| P12-K10 | `epiphany-ops` K | Undo strand-blocks (StrictInverse refusing to tombstone a minted object still referenced by a live non-member, e.g. a staff with a surviving instance) reuse `ConflictKind::TransactionConflict`. Decide whether undo refusals deserve their own conflict kind. | G / Pass 12 (undo) |
|
||||
| P12-K11 | `epiphany-ops` K | An undo's value restorations enter the write chains as ordinary writes by the undo op, so a second undo of the same transaction sees the first as a superseding writer (Conflicted/skip) while absence-restorations repeat idempotently — a documented asymmetry. Decide whether chain writes need distinguished undo provenance so repeated undo is uniformly idempotent. | G / Pass 12 (undo) |
|
||||
| P12-I7 **(IN PROGRESS — schema-major-1 track)** | `epiphany-engrave` I | Page geometry had no graph home: the spec named `Canvas.layout_defaults` ("paper size, margins") but defined no type, and adding a `Canvas` field is a schema-major change under the companion's frozen-layout rule. Casting-off therefore uses an engraver-side `PageGeometry` default (A4 at an 8mm staff: 105x148.5 ss, 7.5 ss margins). **Phase A of the schema-major-1 bump defines the type** (`CanvasLayoutDefaults { page_size: CanvasSize, margins: CanvasMargins }` in staff spaces, A4/8mm default) and ratifies its v1 wire form (Binary Format 0.3.0); the **graph home lands in code in Phase C** (`Canvas` gains the field), after which the engraver reads it (Phase C′) — until fully landed, solvers MAY default. | G (graph model, schema-major) |
|
||||
| P12-I8 | `epiphany-engrave` I | Break-constraint satisfaction predicate: implemented as "a `SystemBreakAt`/`PageBreakAt` is satisfied iff the final layout starts a system/page at that slot" (a region-first slot is trivially satisfied). Ch7/Ch9 never define satisfaction for break constraints; ratify the predicate. | G / Pass 12 (solver) |
|
||||
| P12-I9 | `epiphany-layout-ir` I | Honouring a user break must attribute the decision to its override (`DecisionSource::UserOverride(id)`), but constraints carry no override identity; implemented via a `ConstrainedLayoutIR.break_origins` sidecar populated by `to_constrained`. Bless the sidecar or widen the normalized constraint record. | G / Pass 12 (solver) |
|
||||
| P12-I10 | `epiphany-layout-ir` I | System-spanning strokes split at system boundaries need synthesized provenance for continuation segments; implemented as `SynthesisKind::Registered(SYSTEM_CONTINUATION_SYNTHESIS)` with a deterministic `(original, ordinal)` instance key. Add a first-class continuation synthesis kind or bless the registered id. | G / Pass 12 (provenance) |
|
||||
| P12-K12 | `epiphany-ops` K | Cross-region slur spanning permission: `Region.permits_spanning_slurs` (schema major 1, P12-K7) gates the CreateCrossCutting(Slur) advisory, but which region governs a slur whose endpoints lie in *different* regions is under-specified. Implemented as conservative **AND** (a boundary is permeable only when both endpoint regions permit); "the start region governs" or "either side" are equally defensible. The advisory is authoring-only and never alters reduction, so the choice is not byte-affecting. Ratify one reading. | G / Pass 12 (validation) |
|
||||
| ~~P12-I7~~ **RATIFIED (schema-major-1 track, 2026-07-06; see PASS12_RATIFICATION_LOG)** | `epiphany-engrave` I | Page geometry had no graph home: the spec named `Canvas.layout_defaults` ("paper size, margins") but defined no type, and adding a `Canvas` field is a schema-major change under the companion's frozen-layout rule. Casting-off therefore uses an engraver-side `PageGeometry` default (A4 at an 8mm staff: 105x148.5 ss, 7.5 ss margins). **Phase A of the schema-major-1 bump defines the type** (`CanvasLayoutDefaults { page_size: CanvasSize, margins: CanvasMargins }` in staff spaces, A4/8mm default) and ratifies its v1 wire form (Binary Format 0.3.0); the **graph home lands in code in Phase C** (`Canvas` gains the field), after which the engraver reads it (Phase C′) — until fully landed, solvers MAY default. | G (graph model, schema-major) |
|
||||
| ~~P12-I8~~ **RATIFIED (schema-major-1 track, 2026-07-06; core_spec `req:layoutir:break-satisfaction`)** | `epiphany-engrave` I | Break-constraint satisfaction predicate: implemented as "a `SystemBreakAt`/`PageBreakAt` is satisfied iff the final layout starts a system/page at that slot" (a region-first slot is trivially satisfied). Ch7/Ch9 never define satisfaction for break constraints; ratify the predicate. | G / Pass 12 (solver) |
|
||||
| ~~P12-I9~~ **RATIFIED (schema-major-1 track, 2026-07-06; core_spec `req:layoutir:break-origin-attribution`)** | `epiphany-layout-ir` I | Honouring a user break must attribute the decision to its override (`DecisionSource::UserOverride(id)`), but constraints carry no override identity; implemented via a `ConstrainedLayoutIR.break_origins` sidecar populated by `to_constrained`. Bless the sidecar or widen the normalized constraint record. | G / Pass 12 (solver) |
|
||||
| ~~P12-I10~~ **RATIFIED (schema-major-1 track, 2026-07-06; core_spec `req:layoutir:continuation-synthesis`)** | `epiphany-layout-ir` I | System-spanning strokes split at system boundaries need synthesized provenance for continuation segments; implemented as `SynthesisKind::Registered(SYSTEM_CONTINUATION_SYNTHESIS)` with a deterministic `(original, ordinal)` instance key. Add a first-class continuation synthesis kind or bless the registered id. | G / Pass 12 (provenance) |
|
||||
| ~~P12-I11~~ **RESOLVED (engrave v3 widow-rebalance)** | `epiphany-engrave` I | RS-1 honestly failed the Minimal casting-off threshold under the reference engraver (measured 1.0 vs 0.90): greedy first-fit left a two-measure stub last system (width CV 0.6145 ≥ the 0.5 anchor). **Resolved the honest way — an engrave-side casting-off balance pass, no catalog change:** casting-off gained a second **widow-rebalance** phase that moves whole trailing measures from a region's penultimate system into its final one, choosing the shift that minimizes the larger of the two distribution penalties the catalog defines for the break family (width imbalance vs non-final underfill; both share the 0.5 anchor). RS-1 now casts six/four instead of eight/two: casting_off 1.0 → **0.4463**, system_break 0.254 → 0.677, every axis ≤ 0.90. `ENGRAVER_VERSION` 2 → 3; render goldens regenerated; the suite's Xfail row promoted to a plain Pass. The `casting_off` 0.5 anchor and the Minimal column stood — the engraver improved, not the threshold — so the Quality Metric Catalog is normatively unchanged. | ✅ done |
|
||||
| ~~P12-I12~~ **RESOLVED (QMC 0.2.0: rhythmic-column spacing)** | `epiphany-engrave` I | The Standard-tier spacing floor warned on short healthy scores: 3–8-column entries with a wide clef/key lead measured spacing CV 0.36–0.41 > the 0.32 Standard floor (a spurious *diagnostic* — the scores all passed Minimal). **Resolved by the lead-aware refinement (Quality Metric Catalog 0.1.0 → 0.2.0):** `spacing_distortion` is now scoped to the system's **rhythmic columns** (slots bearing a notehead or rest), excluding the clef / key-signature / time-signature lead and treating barlines transparently (a note-to-note advance spans them) — so the furniture-width lead gap no longer inflates the CV. The three entries drop to 0.2188 / 0.0819 / 0.0856 (all below the 0.32 floor), and the axis stays honest on real irregularity (RS-3 keeps 0.2188 from a mid-line accidental). Anchor, orientation, range, thresholds, and the eight other axes unchanged; no layout/golden change (measurement-only, `ENGRAVER_VERSION` untouched). The **duration-aware optical-spacing** open question (deviation from duration-proportional spacing) stays open — it needs the pipeline's deferred duration-proportional preferred widths. | ✅ done |
|
||||
|
||||
|
|
|
|||
|
|
@ -74,3 +74,32 @@ change**: the defect was in the metric's own definition, not the engraver.
|
|||
(`spacing_distortion` scoped to rhythmic columns). Core spec unchanged (the
|
||||
axis's formal definition is delegated to the catalog; Chapter 9 carries only
|
||||
the field, which is unchanged).
|
||||
|
||||
## Schema-major-1 tranche (2026-07-06) — data-model growth + engrave ratify-only
|
||||
|
||||
The first binary-format schema-major bump (v0 → v1, `binary_format` 0.3.0),
|
||||
built machinery-first on a small payload, landed the two data-model rows the
|
||||
batch parked behind the frozen-layout rule (**P12-I7**, **P12-K7**) and ratifies
|
||||
the three engrave/layout-ir dispositions the implementation already made
|
||||
(**P12-I8/I9/I10**). Delivered as the schema-major-1 Phase A–F commit series
|
||||
(from `f4a2f1f`); this tranche records Phase F.
|
||||
|
||||
| Item | Disposition | Spec locus | Authority followed |
|
||||
|---|---|---|---|
|
||||
| P12-I7 page-geometry graph home | **landed (schema-major-1)** — `Canvas` gained `layout_defaults: CanvasLayoutDefaults { page_size: CanvasSize, margins: CanvasMargins }` (staff spaces, A4/8 mm default), defined in core spec (Phase A) and added to the graph + canonical wire form at major 1 (Phase C, byte-for-byte v0→v1 migrate-on-read, zero golden churn). The engraver still defaults to the same geometry; wiring it to *read* the graph field (C′) is a byte-neutral follow-up deferred until a custom-geometry producer exists | core_spec Ch5 §The Canvas (`CanvasLayoutDefaults`); binary_format §Schema Major 1 | `epiphany-core` (`graph.rs`, `codec.rs::decode_v0_score`) |
|
||||
| P12-K7 advisory-precondition catalog | **landed (schema-major-1) + adopt** — the two graph-model gaps the advisory catalog named are filled: `Instrument.range: Option<PitchRange>` and `Region.permits_spanning_slurs: bool` (major 1, Phases D1/D2), so `epiphany-ops` now enforces the InsertEvent pitch-in-range advisory (frame-guarded; "if any"/indeterminate → vacuous pass) and the CreateCrossCutting(Slur) region-spanning advisory. ModifyEvent's duration-boundary bucket is stated explicitly (it carries the full replacement value). Cross-region slur permission is read as **both** endpoint regions must permit (conservative AND) — see the open item below | core_spec Ch5 §Instruments / §Regions; Ch6 §6.10 advisory buckets; `PitchRange` | `epiphany-core` (`pitch.rs::PitchRange`, `graph.rs`); `epiphany-ops` (`validate.rs`) |
|
||||
| P12-I8 break-constraint satisfaction | **adopt** — Ch7 gains a normative predicate (Requirement `req:layoutir:break-satisfaction`): a `SystemBreakAt`/`PageBreakAt` at `slot` is satisfied iff the final `ResolvedLayoutIR` starts a system/page at that slot; a region-first slot is trivially satisfied; satisfaction is a predicate on the output, not the solver's spring state | core_spec Ch7 §ConstrainedLayoutIR (`req:layoutir:break-satisfaction`) | `epiphany-engrave` casting-off (evaluates hard break constraints for its tier claim) |
|
||||
| P12-I9 break-override attribution | **adopt (decline widening)** — Ch7 gains Requirement `req:layoutir:break-origin-attribution`: honouring a user break carries `DecisionSource::UserOverride(id)`, threaded through a `ConstrainedLayoutIR.break_origins` sidecar populated by the logical-stage projection. The normalized constraint record is deliberately **not** widened to carry override identity — attribution is a projection concern, not a solver input | core_spec Ch7 §Engraving Overrides (`req:layoutir:break-origin-attribution`) | `epiphany-layout-ir` (`constrained.rs::break_origins`, `to_constrained`) |
|
||||
| P12-I10 continuation synthesis | **adopt (bless registered id)** — Ch7 gains Requirement `req:layoutir:continuation-synthesis`: a system-spanning stroke's post-first segments are synthesized under `SynthesisKind::Registered(SYSTEM_CONTINUATION_SYNTHESIS)`, with `stable_semantic_instance_key = (original, ordinal)`; because `LayoutObjectId`s are non-canonical and re-derived per layout, the key need only be stable within a layout | core_spec Ch7 §Provenance (`req:layoutir:continuation-synthesis`) | `epiphany-layout-ir` (`provenance.rs`; `SYSTEM_CONTINUATION_SYNTHESIS`) |
|
||||
|
||||
**Version movements.** Binary Format companion 0.2.0 → 0.3.0 (schema major 1
|
||||
wire form + migration; Phase A). Core spec: `CanvasLayoutDefaults` / `PitchRange`
|
||||
/ `Region.permits_spanning_slurs` data-model additions (Phase A) and the three
|
||||
engrave requirements above (Phase F); revision-history row appended.
|
||||
|
||||
**Open item (flagged, not resolved).** Which region governs a *cross-region*
|
||||
slur's spanning permission is under-specified. The implementation chose the
|
||||
conservative **AND** (a boundary is permeable only when both endpoint regions set
|
||||
`permits_spanning_slurs`); a "the start region governs" or "either side" reading
|
||||
is equally defensible. Tracked for ratification; the advisory is authoring-only
|
||||
and never alters reduction, so the choice is not byte-affecting.
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -8041,6 +8041,22 @@ pub struct LayoutObjectId(pub u128);
|
|||
whose change should invalidate this layout object.
|
||||
\end{requirement}
|
||||
|
||||
\begin{requirement}
|
||||
\label{req:layoutir:continuation-synthesis}
|
||||
\textbf{System-spanning continuation.} A line primitive (stroke) that spans a
|
||||
system boundary is split into per-system segments; the segments after the
|
||||
first are engraver-synthesized and \MUST{} declare a \texttt{synthesis} kind.
|
||||
The reserved registered kind
|
||||
\texttt{SynthesisKind::Registered(SYSTEM\_CONTINUATION\_SYNTHESIS)} names this
|
||||
continuation. Its \texttt{stable\_semantic\_instance\_key} (per
|
||||
Requirement~\ref{req:layoutir:object-id-derivation}) is the pair
|
||||
\texttt{(original,\,ordinal)} --- the pre-split stroke's object and the
|
||||
segment's order within the split --- which is stable for a fixed set of system
|
||||
breaks. Because \texttt{LayoutObjectId}s are non-canonical and re-derived per
|
||||
layout, this key need only be stable within a layout, not across relayouts
|
||||
that move the breaks.
|
||||
\end{requirement}
|
||||
|
||||
\begin{requirement}
|
||||
\label{req:layoutir:object-id-derivation}
|
||||
A \texttt{LayoutObjectId} \MUST{} be stable across re-layouts whose
|
||||
|
|
@ -8540,6 +8556,21 @@ pub enum OverrideOrigin {
|
|||
overrides without explicit user action.
|
||||
\end{requirement}
|
||||
|
||||
\begin{requirement}
|
||||
\label{req:layoutir:break-origin-attribution}
|
||||
\textbf{Break-override attribution.} When the engraver honours a user break
|
||||
override, the resulting decision \MUST{} carry
|
||||
\texttt{DecisionSource::UserOverride(id)} naming the override. Because a
|
||||
normalized break \emph{constraint} (\texttt{SystemBreakAt} /
|
||||
\texttt{PageBreakAt}, Section~\ref{sec:layoutir:constrained}) carries no
|
||||
override identity, this attribution is threaded through the projection: the
|
||||
\texttt{ConstrainedLayoutIR} carries a \texttt{break\_origins} sidecar,
|
||||
populated when the logical stage projects the break, mapping each user-anchored
|
||||
break slot to its override id. The normalized constraint record is
|
||||
deliberately \emph{not} widened to carry override identity --- attribution is a
|
||||
projection concern, not a constraint-solver input.
|
||||
\end{requirement}
|
||||
|
||||
\section{ConstrainedLayoutIR}
|
||||
\label{sec:layoutir:constrained}
|
||||
|
||||
|
|
@ -8704,6 +8735,20 @@ pub enum BreakKind {
|
|||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\begin{requirement}
|
||||
\label{req:layoutir:break-satisfaction}
|
||||
\textbf{Break-constraint satisfaction.} A \texttt{SystemBreakAt} at
|
||||
\texttt{slot} is \emph{satisfied} iff the final resolved layout starts a
|
||||
system at that slot; a \texttt{PageBreakAt} iff the final layout starts a page
|
||||
there. A slot that already begins a system (respectively page) --- in
|
||||
particular a region's first slot --- is trivially satisfied. Satisfaction is a
|
||||
predicate on the output \texttt{ResolvedLayoutIR}, evaluable by any consumer,
|
||||
not on the solver's internal spring state. A solver's tier claim
|
||||
(Section~\ref{sec:layoutir:resolved}) reports which \texttt{Hard} break
|
||||
constraints its layout satisfies; a \texttt{Soft} break is advisory and MAY be
|
||||
left unsatisfied.
|
||||
\end{requirement}
|
||||
|
||||
\section{ResolvedLayoutIR}
|
||||
\label{sec:layoutir:resolved}
|
||||
|
||||
|
|
@ -14682,6 +14727,23 @@ layouts they own versus inherit:
|
|||
byte-for-byte v0${\to}$v1 migration are ratified in the Binary Format
|
||||
companion (0.2.0 $\rightarrow$ 0.3.0).
|
||||
\\
|
||||
\today & Schema major 1 Phase F (engrave ratify-only) &
|
||||
Ratifies three engrave/layout-ir dispositions the implementation already made
|
||||
(Pass 12 batch I8/I9/I10, now struck), with no byte-layout or architecture
|
||||
change: the \emph{break-constraint satisfaction} predicate
|
||||
(Requirement~\ref{req:layoutir:break-satisfaction} --- a \texttt{SystemBreakAt}
|
||||
/ \texttt{PageBreakAt} is satisfied iff the final \texttt{ResolvedLayoutIR}
|
||||
starts a system/page at that slot, a region-first slot trivially); \emph{break-override
|
||||
attribution} threaded through a \texttt{ConstrainedLayoutIR.break\_origins}
|
||||
sidecar, declining to widen the normalized constraint record
|
||||
(Requirement~\ref{req:layoutir:break-origin-attribution}); and the
|
||||
\emph{system-continuation} synthesis kind
|
||||
\texttt{Registered(SYSTEM\_CONTINUATION\_SYNTHESIS)} with an
|
||||
\texttt{(original,\,ordinal)} instance key
|
||||
(Requirement~\ref{req:layoutir:continuation-synthesis}). Flags one open item:
|
||||
which region governs a cross-region slur's spanning permission (implemented as
|
||||
conservative AND, P12-K12).
|
||||
\\
|
||||
\bottomrule
|
||||
\end{longtable}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue