# Handel *Dixit Dominus* HWV 232 — canonical rehearsal-aid methods

**Status:** canonical workflow through Movement 10 FINAL; Stage-1 parser v4 frozen, Movement-10 instrumental reconciliation QC v2; Modular Player v1 FINAL  
**Date:** 10 Oct 2026

This document is the operational method for subsequent movements. Historical
experiments and rejected approaches remain in the full project notes; this file
contains the rules we actually intend to follow.

Companion canonical references are:

```text
DIXIT_MODULAR_PLAYER_ARCHITECTURE_v1_FINAL.md
DIXIT_STAGE1_PARSER_CANONICAL_v4.md
```

That file is authoritative for the frozen shared-player implementation; this
document records how the player fits into the larger score → synthesis →
accompaniment → rehearsal workflow.

---

## 0. Current project lock

```text
Movement 1 — Dixit Dominus
  chorus/solo audio: accepted production stems
  score-derived metadata: accepted
  modular-player regression case: accepted
  special gain behaviour:
      dedicated solo duplicate suppression retained
      Soprano I/II written unisons retain BOTH voices
      each soprano attenuated to 0.75× through unison ranges

Movement 2 — Virgam virtutis tuae
  Alto v7 FINAL
  répétiteur piano v3 tie-aware FINAL
  Alto hidden calibration 1.50
  Piano hidden calibration 3.59

Movement 3 — Tecum principium
  Soprano I v11 FINAL
  canonical WAV:
      /home/ajp/dixit/mvt3/dixit_mvt3_soprano_v11_FINAL.wav
  répétiteur piano v1 FINAL
  91 bars · 3/4 · 98 BPM
  hidden calibration:
      Soprano I 1.00
      Piano 9.00

Movement 4 — Juravit Dominus
  chorus v12 FINAL
  production-final lock: 4 Oct 2026
  written Soprano I/II unisons keep BOTH voices at 0.75× each
  confirmed attenuation ranges:
      bar 37 start -> bar 46 beat 2
      bars 48–50 inclusive

Movement 5 — Tu es sacerdos
  chorus v14 FINAL
  répétiteur piano v1 FINAL
  30 bars · 4/4 · 100 BPM
  exact score end:
      tick 57600 = 72.000 s
  canonical vocal WAV masters:
      /home/ajp/dixit/mvt5/dixit_mvt5_soprano1_v14_FINAL.wav
      /home/ajp/dixit/mvt5/dixit_mvt5_soprano2_v14_FINAL.wav
      /home/ajp/dixit/mvt5/dixit_mvt5_alto_v14_FINAL.wav
      /home/ajp/dixit/mvt5/dixit_mvt5_tenor_v14_FINAL.wav
      /home/ajp/dixit/mvt5/dixit_mvt5_bass_v14_FINAL.wav
  final Melchisedech release at notional bar-31 downbeat:
      Nishiren S1/S2/Alto -> [k axh]
      Alex Tenor/Bass     -> [k e]
  web playback end:
      72.190 s
  no synthetic bar 31 is added to score metadata
  v14 vocal web URLs are cache-versioned (?v=v14)
  later editable USTX refinement:
      v15 shortens Alex Tenor/Bass terminal [k e] carrier to 15 ms (12 ticks)
      female [k axh] release unchanged
      production WAV/web lock remains v14 until the v15 rerender is explicitly promoted

Movement 6 — Dominus a dextris tuis
  production-final lock: 6 Oct 2026
  five final vocal WAV masters:
      /home/ajp/dixit/mvt6/dixit_mvt6_soprano1_FINAL.wav
      /home/ajp/dixit/mvt6/dixit_mvt6_soprano2_FINAL.wav
      /home/ajp/dixit/mvt6/dixit_mvt6_alto_FINAL.wav
      /home/ajp/dixit/mvt6/dixit_mvt6_tenor_FINAL.wav
      /home/ajp/dixit/mvt6/dixit_mvt6_bass_FINAL.wav
  répétiteur:
      dixit_mvt6_repetiteur_piano_v2.mid FINAL
      dixit_mvt6_repetiteur_piano_v2.wav FINAL
  score:
      148 bars · 3/4 throughout · 100 BPM
      exact score/MIDI end = 266.400 s
      FluidR3 piano WAV end = 269.105 s
      web transport end = 269.105 s
  final hidden calibration at visible 70%:
      Soprano I   0.5000
      Soprano II  0.5000
      Alto        0.5357
      Tenor       1.1800
      Bass        1.6000
      Piano       1.7382
  no solo-vs-chorus gain switch
  interpretive shape:
      bars 1–80 restrained solo texture
      bar 81 onward full chorus / fuller orchestra provides natural expansion
  piano v2:
      exact simultaneous Vln I/II same-pitch attacks collapse to one piano key
      exact simultaneous Vla I/II same-pitch attacks collapse to one piano key
      continuo and cross-family coincidences remain untouched

Movement 7 — Judicabit
  production-final lock: 6 Oct 2026
  vocal lock: chorus v20 FINAL
  source USTX:
      dixit_mvt7_chorus_v20_S1_BAR54_IMPLEBIT_L_FIX.ustx
  five final vocal WAVs exported by the user from v20
  répétiteur:
      dixit_mvt7_repetiteur_piano_v1.mid FINAL
      dixit_mvt7_repetiteur_piano_v1.wav FINAL
  score:
      61 bars · common time throughout · 100 BPM
      key signature: one flat (B-flat)
      exact score/MIDI end = 146.400 s
      web/piano playback endpoint = 148.402 s
  final hidden calibration at visible 70%:
      Soprano I   0.5357
      Soprano II  0.5357
      Alto        0.5357
      Tenor       1.1800
      Bass        1.6000
      Piano       2.3179
  important renderer rules:
      doubled-vowel refresh [V V] is a symptom-triggered transition/state rescue,
      not a blanket replacement for +~
      Alex fast implebit semiquaver: [i m p l] [e]
      Nishiren fast implebit semiquaver: [i m p] [l e]
      local S1 bar-54 exception: [i m p l] [l e]
      Alex final /t/ before silence: 15-ms [t e] carrier when needed
      final /t/ before immediate sung continuation may carry into that next event
  accompaniment:
      direct written reduction; no invented harmony
      same-family exact simultaneous same-pitch string doublings collapse to one piano attack

Movement 8 — Conquassabit
  production-final lock: 8 Oct 2026
  chorus v10 FINAL with accepted randomized-note-timing Bass
  canonical USTX:
      /home/ajp/dixit/mvt8/dixit_mvt8_chorus_v10_FINAL.ustx
      contains the exact accepted Bass timing-offset realization
  canonical vocal WAVs:
      /home/ajp/dixit/mvt8/dixit_mvt8_soprano1_v10_FINAL.wav
      /home/ajp/dixit/mvt8/dixit_mvt8_soprano2_v10_FINAL.wav
      /home/ajp/dixit/mvt8/dixit_mvt8_alto_v10_FINAL.wav
      /home/ajp/dixit/mvt8/dixit_mvt8_tenor_v10_FINAL.wav
      /home/ajp/dixit/mvt8/dixit_mvt8_bass_v10_RNDTIME_FINAL.wav
  répétiteur:
      dixit_mvt8_repetiteur_piano_v1.mid FINAL
      dixit_mvt8_repetiteur_piano_v1.wav FINAL
  score:
      50 bars · 3/4 throughout · 100 BPM
      printed key signature: one flat (B-flat only)
      exact score/MIDI end = 90.000 s
      FluidR3/player endpoint = 92.704 s
  final hidden calibration at visible 70%:
      Soprano I   0.5357
      Soprano II  0.5357
      Alto        0.5357
      Tenor       1.1800
      Bass        1.6000
      Piano       1.5852
  important renderer rules:
      all Conquassabit notes explicitly rearticulate
      women use gs separator; men use cl separator
      receiving separator may be omitted only when pitch changes AND
          previous final non-separator phone differs from receiving first phone
      M8 terminal bit-before-rest treatment is movement-specific
      Alex capita inter one-off: [i n] [t e r] -> [i n t] [t e r]
      Bass uses one accepted OpenUtau Randomize Note Timing realization,
          baked into the canonical USTX; do not re-randomize on each render
  accompaniment:
      literal written reduction; no invented harmony
      Vln I/II exact simultaneous same-pitch duplication collapses within family
      Vla I/II exact simultaneous same-pitch duplication collapses within family
      cross-family and continuo coincidences remain distinct
  MIDI SHA-256:
      24f1bf0283d24c4813e5fa56aad756e23dd7f658754a0fb2d7eb066f62e09690


Movement 9 — De torrente in via
  production-final lock: 9 Oct 2026
  solo Soprano I/II, chorus Tenor/Bass; accepted v3 USTX/WAV masters
  Soprano II timing-randomised and Bass timing-randomised once-only
  score 36 bars · 4/4 · 100 BPM · score 86.400 s · web 89.004 s
  piano v1 accepted, independent cello and continuo; Bärenreiter S2 b22 A#4
  final hidden gain at 70% visible:
      Soprano I 0.7500 · Soprano II 0.7500 · Tenor 0.8510
      Bass 1.1539 · Piano 1.2009

Movement 10 — Gloria Patri
  production-final lock: 10 Oct 2026
  full SSATB chorus with 5 accepted v34 WAVs
  accepted USTX: dixit_mvt10_v34_RANDOMIZED_175BARS_LISTENING.ustx
  Soprano II and Tenor timing randomised once-only, 175-bar containers restored
  score 175 bars · 4/4 · 100 BPM · score 420.000 s · web 422.004 s
  piano v3 accepted: 4493 attacks, 62 instrumental ties
  cello bars 122–125 user/Bärenreiter-verified correction, explicit overlay
  final hidden gain at 70% visible:
      Soprano I 0.5357 · Soprano II 0.5357 · Alto 0.5357
      Tenor 1.1800 · Bass 1.6000 · Piano 1.7786
  new production rules:
      sustained notes subdivided into renderer halves with explicit vowel
      extended melismas refreshed approximately every crotchet at untied notes
      score rests remain actual silence, avoid standalone [SP] carrier default
      score-derived underlay and Bärenreiter overrides remain distinct
  parser-v2 instrumental QC: physical ranges and B122–125, ties, note count,
      exact v3 MIDI SHA; not a claim of note-by-note visual verification

Player
  Modular Player v1 FINAL
  one shared player.js
  one shared player.css
  movement-specific behaviour in movement.json / movement-meta.json
  Replay is part of the shared state machine
  visible mixer defaults remain 70%
  score duration and playback-tail duration are distinct when needed
```

Older Movement-1 v14 and Movement-2/3 per-page engines are historical
implementation references, not the current player architecture.


---

## 1. Preserve a layered source model

Keep these layers distinct:

```text
literal source extraction
        ↓
documented edition/performance overrides
        ↓
renderer adaptation
        ↓
audio stems
        ↓
player metadata / UI
```

### Literal extraction

Philip Legge's vector PDF remains the primary machine-readable extraction
source for:

- pitches and durations;
- rests;
- clefs and accidentals;
- bar/system/page geometry;
- ties/slurs;
- lyric text objects and positions;
- continuo/bass line;
- figured-bass symbols.

The parser must report what Legge actually prints. Never silently "correct"
Legge during parsing.

### Performance overrides

The user's chorus performs from the current Bärenreiter/HHA edition. Where
Bärenreiter demonstrably differs from Legge, encode that difference as an
explicit, auditable **performance override**.

Do not hide edition differences inside geometry rules or phoneme heuristics.

---

## 2. Determine complete movement boundaries before parsing

Never assume a PDF page boundary is a movement boundary.

For every movement:

1. find the printed movement title;
2. follow bar numbering across pages;
3. continue until the next movement title;
4. verify staff topology across the entire span;
5. regression-test the final bar count.

Movement 2 demonstrated that a page-turn hyphen can otherwise look like the
end of a movement.

---

## 3. Infer staff/system topology from repeated musical structure

Do not use one fixed vertical-gap threshold for every movement.

Instead infer the repeating staff group:

- chorus + orchestra;
- soloist + continuo;
- soloist + strings + continuo;
- etc.

Use:

- staff labels;
- clef/staff geometry;
- lyric-bearing staves;
- repeated vertical grouping;
- next-movement title as a hard stop.

---

## 4. Maintain a shared engraving-glyph vocabulary

Every newly encountered Opus glyph must be:

1. identified from musical context;
2. validated by bar-duration closure;
3. added to the shared glyph vocabulary;
4. covered by regression tests.

Example learned in Movement 2:

```text
Opus `r` = standalone sixteenth flag
```

Never promote a guessed glyph meaning without rhythmic validation.

---

## 5. Treat lyric geometry carefully

A lyric object is not just its centre x-coordinate.

Preserve:

- left edge / origin;
- right edge;
- centre;
- baseline;
- system/bar association;
- sequential lyric order.

For Sibelius-derived engraving, the **left edge/origin** may identify the
intended note better than the word centre, especially for multi-letter
syllables among semiquavers.

**Authoritative-origin rule (Movement 5 v10 parser onward):** if the printed
lyric left edge/origin is directly and uniquely anchored to a plausible
notehead, that anchor outranks word-centre geometry. Do not require the
centre-based candidates to be nearly tied before applying this rule.

Regression cases include Movement-5 Soprano II bars 15 and 20; a full
movement audit also corrected the same one-semiquaver-late pattern in Soprano I
bar 3 and Bass bar 15.

Use sequential underlay as an additional constraint.

If geometry and sequence disagree, flag the case for review rather than
silently forcing the nearest note.

---

## 6. Separate pitch articulation from phonetic articulation

This is a central project rule.

> A tie suppresses a new pitch attack; it does not necessarily suppress a new
> phonetic event.

Therefore:

- detect and validate ties independently;
- merge tied pitch events acoustically;
- assign lyric/phoneme changes independently;
- allow a vowel change on a tied pitch when the score/edition requires it;
- flag suspicious consonant-bearing lyric attacks on tie continuations for
  source/edition review.

Do **not** globally remove tie destinations from lyric assignment.

Cross-barline and cross-system ties require explicit regression tests.

---

## 7. A rest ends sound, not necessarily lyric context

In solo writing, the same syllable may continue after a short written rest.

Represent these concepts separately:

```text
musical silence
semantic syllable continuity
neural phrase continuity
```

A rest may stop acoustic sound while the same vowel/syllable remains active
afterward.

---

## 8. Build a canonical note/lyric representation before synthesis

Before OpenUtau export, the canonical event model should know:

- absolute musical time;
- bar and beat;
- pitch;
- duration;
- tie-chain membership;
- rest status;
- syllable identity;
- whether a note is syllabic or melismatic;
- edition overrides;
- ornament instructions;
- solo/tutti role.

Do not use USTX itself as the primary score model.

---

## 9. Renderer-adaptation philosophy

The renderer layer exists to translate correct musical intent into a form the
synthetic singer can execute.

Order of diagnosis:

1. score extraction;
2. edition choice;
3. lyric assignment;
4. tie/rest topology;
5. phoneme timing;
6. neural phrase segmentation;
7. only then acoustic-expression parameters.

### Avoid symptom patching

Do not use local BREC/TENC/VELC changes as first-line repairs for:

- metallic notes;
- breathiness;
- phrase dropouts;
- consonant timing;
- bad re-attacks.

Movement 2 showed that these can disguise the actual structural defect.

Use BREC/TENC/VELC only when there is a genuine singer-wide expressive reason,
not to hide parser or phrase-topology errors.

---

## 10. Established Nishiren / DiffSinger renderer rules

### 10.1 Pure vowels and explicit Latin phonemes

Continue the explicit Latin phoneme approach established in Movement 1.

Use pure vowels and explicit consonant clusters rather than relying on
orthographic guessing.

### 10.2 Consonant anticipation

For a consonant-bearing syllable that launches rapid coloratura, allow
singer-style anticipation of the consonant into the preceding note so that the
vowel owns the written onset.

Movement-2 validated example:

```text
[m i] | [n a] ...
      ↓
[m i n] | [a] ...
```

This removed the metallic onset of bar-20 rapid coloratura.

General condition:

- new consonant-bearing syllable;
- followed immediately by several fast notes on one vowel;
- preceding note provides musically plausible space for consonant preparation.

Do not apply this blindly to every consonant.

### 10.3 Same-pitch vowel hiatus

A real vowel-to-vowel transition on an unchanged pitch needs explicit
separation so it does not become a lazy glide or an unintended re-attack.

Use the established short separator/closure treatment and preserve continuous
pitch where appropriate.

### 10.4 Selective bare-vowel refresh

Long melismas may fade or destabilise.

Use bare-vowel refreshes:

- selectively;
- at musically sensible subdivision points;
- on untied notes;
- without adding consonants.

Do not use a fixed-duration timer as the sole rule.

### 10.5 Short rest inside an ongoing same-syllable phrase

If a short written rest occurs inside one continuing melisma and a literal
USTX gap causes DiffSinger to split the neural sentence, represent the rest as
an explicit **`[SP]`** silence token.

This preserves:

- the written acoustic silence;
- the same syllable;
- the neural phrase context.

Movement-2 bar 20 validated this strongly.

General condition:

- genuine short written rest;
- same syllable/vowel resumes immediately afterward;
- renderer phrase-splitting causes an artificial fresh onset.

### 10.6 Short consonants on fast notes

Compact consonant timing on very short syllabic notes so that the vowel reaches
the beat promptly.

This is a phoneme-timing problem, not a timbre problem.

### 10.7 Word-final consonant placement * **

For choral diction, a word-final consonant that follows a fully sustained note
belongs on the **release**, not inside the notated vowel duration.

Canonical rule from Movement 4 onward:

```text
sung note:  sustain the vowel for the complete written duration
rest onset: begin the final consonant
rest:       finish the consonant promptly, then remain silent
```

This is especially important for long notes ending in unvoiced fricatives such
as `/s/`: allowing the renderer to predict the coda inside the note can produce
an exaggerated span of sibilance and short-change the vowel.

Implementation hierarchy:

1. **word-final consonant + following rest**
   → move the coda to the exact rest onset;
2. **word-final consonant + immediately following sung event**
   → right-align the coda inside the note/tie-chain, preserving the following
   vowel onset;
3. **tie-chain + following rest**
   → sustain the vowel through the complete tie-chain and release the coda on
   the following rest;
4. explicit editorial/conductor instructions override the default.

For native OpenUtau/DiffSinger, the preferred explicit representation is to
remove the coda phone from the vowel-bearing lyric and add a short
consonant-only release event at the rest onset. Keep that release entirely
inside the written rest.

Movement-4 first implementation uses a nominal **120 ms** release event,
converted to local ticks with a minimum of 48 ticks. This duration is a renderer
calibration, not score truth; the **onset at the rest boundary** is the canonical
musical rule.


**\* Short-rest / fast-passage exception (Movement 5 onward).**

The rest-onset rule is the default, not an instruction to consume a written
rest with consonant noise. In fast passage-work, an isolated short rest can be
an articulatory event in its own right.

If all of the following are true:

- a word-final consonant is followed by a very short written rest;
- the rest separates rapid sung figures;
- placing the coda on the rest would consume most of its duration;
- the preceding sung note has enough duration to accommodate a compact coda;

then place the final consonant in the **tail of the preceding written note** and
preserve the short rest as perceptible silence.

Movement-5 regression case:

```text
written semiquaver rest at 100 BPM: 120 ticks = 150 ms

bad generic treatment:
    consonant release ≈ 96 ticks
    remaining silence ≈ 24 ticks / 30 ms

preferred short-rest exception:
    compact coda finishes at rest onset
    complete 120-tick rest remains silent
```

Initial Movement-5 renderer calibrations:

```text
voiceless stop /k/: 48 ticks ≈ 60 ms
voiced final /m/:   64 ticks ≈ 80 ms
```

These durations are renderer calibrations, not universal phonetic constants.
The musical invariant is that the isolated short rest must remain perceptibly
present.

Use musical topology rather than note value alone: an isolated semiquaver rest
inside or between fast passage-work is a strong trigger; a longer or genuinely
breathing rest normally uses the default rest-onset release rule.


**\*\* Movement-end release (Movement 5 onward).**

If the final sung syllable of a movement ends in a consonant and there is no
printed following rest or bar, treat the score boundary as though the next
downbeat still exists for diction purposes:

```text
final written note:
    sustain the vowel through the complete notated duration

notional next-bar downbeat:
    begin the final consonant
```

Thus the consonant does **not** steal time from the final written note merely
because the engraving stops there.

Movement-5 regression case:

```text
bar 30 ends at position 57600
all five parts: final Melchisedech whole note

v5:
    [d e k] across the written whole note

v6 conceptual correction:
    [d e] 55680-57600
    final consonant begins at 57600 = hypothetical bar-31 beat 1

v14 FINAL production implementation:
    Nishiren — Soprano I / Soprano II / Alto:
        [d e] through 57600
        [k axh] begins at 57600

    Alex — Tenor / Bass:
        [d e] through 57600
        [k e] begins at 57600
```

The v14 release note remains a short renderer event beginning exactly at the
notional barline. `[k axh]` and `[k e]` are **singer-specific synthesis
implementations**, not changes to the musical rule and not phonetic targets to
copy automatically to other singers. Nishiren gives a good native release with
`[k axh]`; Alex's `[k e]` is slightly over-voiced but is the accepted pragmatic
implementation because it preserves an audible terminal stop.

Earlier experiments using a naked standalone `[k]`, `[e k]`, or sacrificial
future lexical context such as `[d e k] +~ [m e l]` are historical diagnostics,
not the final Movement-5 production method.

The synthetic project/audio may extend briefly beyond the score duration to
carry this release. The **musical score duration remains unchanged**. Movement
5 therefore has a 72.000-s score boundary but a 72.190-s web playback endpoint,
with no fictitious 31st bar in the score metadata.

Use a common ensemble release point for all simultaneously ending parts unless
the score or conductor explicitly requires otherwise.

Do not retrofit already accepted Movements 1–3 solely to enforce this newer
rule. Their frozen renders remain valid unless a specific audible defect merits
reopening them. Apply the rule prospectively from Movement 4 onward.

### 10.8 Final nasals and other voiced codas

Voiced final consonants such as `/m/` and `/n/` follow the same release-on-rest
rule. They may carry the preceding pitch briefly into the rest, but must not
introduce a conspicuous schwa or sound like an extra sung note.

---

## 11. Ornament layer

Keep ornaments separate from literal score extraction.

For a written Handel trill:

- upper auxiliary on the beat unless evidence says otherwise;
- even alternation;
- tempo-dependent number of repercussions;
- historically appropriate closing/suffix gesture;
- musically shaped exit, not a mechanical loop.

Store the ornament as an explicit performance instruction so the parser remains
literal.

---

## 12. Accompaniment method

### 12.1 Literal instrumental layer first

Extract and regression-test the written instrumental/continuo notes before
realisation.

### 12.2 Répétiteur layer second

Build an original rehearsal accompaniment rather than copying a proprietary
published reduction.

For continuo movements:

```text
LH = literal bass/continuo
RH = restrained harmonic realisation
```

The goal is functional rehearsal support, not a claim of historical continuo
reconstruction.

### 12.3 Tie-aware whole-texture sustain

A tied bass note can still sound re-attacked if the RH repeats an unchanged
chord at the tie destination.

General rule:

> At a confirmed bass-tie continuation, suppress an unchanged RH chord
> re-strike unless a genuine harmonic/figured-bass change requires it.

Regression-test the whole accompaniment texture, not just bass note-ons.

---

## 13. Audio rendering and calibration

Keep accepted source/render calibration stable across movements where the same
voicebank and rendering path are reused. Do not normalise every movement
independently.

Treat these as distinct layers:

```text
rendered master level
        ↓
hidden per-stem player calibration
        ↓
visible user mixer percentage
```

The hidden calibration compensates for raw render-level differences; the visible
mixer remains a rehearsal control and defaults to 70%.

Current locked references include:

```text
Movement 2
Alto  1.50
Piano 3.59

Movement 3
Soprano I 1.00
Piano     9.00
```

Do not alter a frozen WAV/MP3 master merely to achieve web-player balance. Adjust
the movement configuration instead, validate comparatively, and then freeze the
configuration.

### 13.1 Score-dependent gain rules are musical metadata, not audio edits

Movement 1 established two distinct classes:

1. **duplicate solo material** — when a dedicated Soloists stem carries the
   passage, suppress the duplicate note material in the full-part chorus stem;
2. **written choral unison** — when Soprano I and II are both genuinely written,
   retain both channels but reduce each modestly.

Accepted Soprano I/II unison behaviour:

```text
Soprano I = 0.75 × normal channel gain
Soprano II = 0.75 × normal channel gain
```

through `soprano_unison_ranges`.

Do not confuse a written unison with duplicate-render cleanup. Two written
choral parts should still sound like two parts.

---

## 14. Player architecture — Modular Player v1 FINAL

The project no longer has separate Movement-1, Movement-2 and Movement-3 player
engines.

Canonical architecture:

```text
shared/player.js
shared/player.css
        ↓
generic index.html shell
        ↓
movement.json
movement-meta.json
audio stems
```

Core rule:

> A new movement is data, not a new player implementation.

`shared/player.js` owns:

- stem loading/decoding;
- one-clock Web Audio scheduling;
- mixer construction;
- hidden calibration;
- score-dependent gain rules;
- play / pause / replay;
- score-bar seeking;
- timeline dragging;
- whole-bar loops;
- the 500 ms rehearsal loop pause;
- pitch-preserving tempo changes;
- lazy SoundTouch loading;
- movement selection;
- session-scoped autoplay-next;
- keyboard controls.

Movement-specific differences belong in `movement.json` or
`movement-meta.json`, not forked JavaScript.

The full frozen architecture and extension contract are documented in:

```text
DIXIT_MODULAR_PLAYER_ARCHITECTURE_v1_FINAL.md
```

### 14.1 Shared playback state machine

Use one explicit state model:

```text
loading → ready/paused → playing → ended
                    ↘ loopwait ↗
```

The Play button and Space key must call the same transition function.

At natural completion:

- keep the playhead at 100%;
- show **↻ Replay**;
- do not rewind automatically;
- Replay/Space from `ended` starts from bar 1;
- autoplay-next overrides Replay only when enabled and a next movement exists.

This behaviour must be implemented once in the shared engine.

---

## 15. Score-derived player metadata

Generate, do not hand-enter:

- bar count;
- bar start/end times;
- metre changes;
- tempo changes;
- solo/tutti ranges;
- exact unison ranges where relevant;
- any named score ranges required by declarative gain rules.

Player features depending on bars must use metadata rather than assumptions such
as "every bar is 2 seconds".

`movement-meta.json` is the authority for musical time. Raw audio-file duration
is not the authority for bar positions.

---

## 16. Multi-movement navigation and movement configuration

The shared manifest defines movement order:

```text
_modular/movements.json
```

Each movement supplies a small configuration:

```text
_modular/mvtN/movement.json
```

Typical configuration fields:

- movement number;
- title;
- metadata URL;
- stem key / label / file;
- hidden calibration;
- default visible percentage;
- master/compressor settings;
- loop pause;
- credits;
- optional declarative gain rules.

Adding a movement should normally require:

1. accepted audio stems;
2. score-derived `movement-meta.json`;
3. generic `index.html`;
4. one `movement.json`;
5. one manifest entry.

Do not invent movement-specific navigation or player code.

---

## 17. Listening-QC method

Listen first for **classes of failure**.

When a defect is heard, ask:

1. Is the score parsed correctly?
2. Is this an edition difference?
3. Is the syllable on the correct note?
4. Is there a tie?
5. Is there a short rest that splits the neural phrase?
6. Is a consonant consuming a fast note?
7. Is a vowel transition occurring on the same pitch?
8. Is a long melisma losing neural continuity?
9. Is accompaniment creating a false attack?
10. Is this truly a timbre problem only after all structural causes are ruled
    out?

Prefer a controlled A/B diagnostic that changes one structural cause at a time.

Do not promote a fix to the general pipeline until it succeeds musically.

---

## 18. Regression checklist for every movement

Before accepting a movement:

```text
SCORE / PARSER
[ ] complete movement boundary confirmed across pages
[ ] staff/system topology validated
[ ] all bars close rhythmically
[ ] no unexplained glyphs
[ ] accidentals correct
[ ] cross-barline ties correct
[ ] cross-system ties correct
[ ] pitch ties independent from lyric/phoneme events
[ ] lyric geometry/sequence consistent
[ ] edition overrides explicit
[ ] tuplet interpretation validated by engraving topology + metre closure
[ ] full-bar rests interpreted from active metre

VOCAL RENDER
[ ] rests preserve semantic syllable context where required
[ ] no orphaned +~ after phrase breaks
[ ] fast consonant onsets handled structurally
[ ] same-pitch vowel changes clean
[ ] untied same-pitch repetitions rearticulate
[ ] long melismas stable and refreshed only where needed
[ ] ornaments explicit and auditable
[ ] final consonants survive tie chains
[ ] word-final consonants before rests release on the rest onset, not early inside the vowel note
[ ] no unsupported phoneme tokens remain

ACCOMPANIMENT
[ ] literal instrumental extraction reaches zero unexplained closure errors
[ ] accompaniment does not re-strike tied harmony falsely
[ ] sparse continuo textures are realised cautiously
[ ] fully written orchestral textures are reduced directly before inventing harmony

AUDIO / PLAYER
[ ] final stem durations are compatible with score timeline
[ ] local 100% playback works without SoundTouch
[ ] all stems start from one AudioContext clock
[ ] bar navigation and loops use score metadata
[ ] loop is inclusive and pauses ~500 ms before repeating
[ ] movement dropdown works both directions
[ ] autoplay-next degrades gracefully
[ ] natural completion shows ↻ Replay and remains at 100%
[ ] Replay button and Space both restart from bar 1
[ ] mixer Mute / Max / Reset work for every configured stem
[ ] hidden calibration matches the accepted lock
[ ] score-dependent gain rules sound musically correct
```

For Movement 1 specifically, regression-test:

```text
[ ] dedicated solo passages do not double with full-part chorus renders
[ ] Soprano I/II written unisons retain BOTH voices
[ ] each soprano is 0.75× through the accepted unison ranges
```

---

## 19. Locking policy

Once a movement is accepted:

- freeze the vocal build;
- freeze accompaniment;
- freeze hidden calibration and declarative gain rules;
- freeze the referenced score metadata;
- validate the movement under the shared player;
- branch future experiments rather than mutating the lock.

The shared player itself has an independent release lock:

```text
Modular Player v1 FINAL
```

The frozen-player unit includes:

```text
_modular/shared/player.js
_modular/shared/player.css
_modular/movements.json
_modular/mvtN/index.html
_modular/mvtN/movement.json
referenced movement-meta.json files
referenced MP3 stems
```

The companion freeze workflow records SHA-256 manifests so the accepted player
can be distinguished from later experiments.

Current musical locks:

```text
Movement 1
  accepted production chorus/solo stems
  accepted score metadata
  modular-player regression lock
  written S1/S2 unisons: 0.75× each

Movement 2
  Alto v7 FINAL
  répétiteur piano v3 tie-aware FINAL
  Alto CAL 1.50
  Piano CAL 3.59

Movement 3
  Soprano I v11 FINAL
  répétiteur piano v1 FINAL
  91 bars · 3/4 · 98 BPM
  Soprano CAL 1.00
  Piano CAL 9.00
```

---

## 20. Workflow for Movement 4 onward

Use this sequence:

1. identify the complete score span;
2. parse literal Legge notation;
3. run parser regression and require rhythmic closure;
4. compare available Bärenreiter/HHA material;
5. encode explicit performance overrides;
6. build canonical note/lyric/tie model;
7. apply established renderer rules;
8. generate OpenUtau;
9. listen and diagnose structural classes of failure;
10. freeze the accepted vocal build;
11. build and audit the literal instrumental layer;
12. choose accompaniment strategy:
    - sparse continuo → cautious realisation;
    - fully written texture → direct reduction;
13. regression-test accompaniment ties and tuplets;
14. freeze accompaniment;
15. render web stems without altering canonical masters;
16. generate `movement-meta.json`;
17. create `_modular/mvtN/movement.json`;
18. add one entry to `_modular/movements.json`;
19. test under the unchanged shared player;
20. compare balance with locked previous movements;
21. run the full regression checklist;
22. freeze the movement;
23. add only genuinely new general lessons to this methods document.

The objective is cumulative: each completed movement should reduce the amount of
movement-specific repair needed by the next one.

---

# Movement 3 implementation lessons — mandatory additions

These rules were learned while implementing *Tecum principium* and are now part
of the canonical method for all later movements.

## A. Treat the methods document as an executable checklist

At the beginning of each new movement, instantiate regression tests for every
previous global rule that could apply. The purpose of cumulative documentation
is to prevent listening QC from rediscovering already-solved classes of error.

In particular, do not build a new exporter from a simplified mental summary of
the previous one.

## B. Consonant anticipation must not duplicate phones

Singer-style anticipation remains valid, but it is fundamentally a TIMING rule.

Do not implement it by universally copying the next syllable's onset phones into
the previous note. Never run two boundary passes that can append the same onset
twice.

For the current native OpenUtau workflow:

- retain a new syllable's onset on its own note by default;
- coalesce a genuinely identical boundary consonant (`...s | s...`);
- retain the validated special case where ONE simple consonant is prepared
  before a substantial rapid melisma;
- otherwise use explicit phoneme timing if anticipation is needed.

Regression-test exported phoneme strings for accidental duplicate clusters.

## C. Tie-chain pitch and tie-chain phonetics are separate

When true ties are collapsed to one pitch articulation, retain both the FIRST
and LAST source events in the chain.

Coda placement is determined from the LAST source event.

Thus a syllable ending at the receiving end of a barline tie still receives its
final consonant at the end of the tied sound.

If a new syllable or other genuine phonetic event occurs inside a tie chain,
flag it for explicit handling; do not silently flatten it.

## D. Untied repeated same-pitch notes rearticulate

After true ties have been merged:

```text
same pitch + tie     -> sustain one articulation
same pitch + no tie  -> new articulation
```

This remains true inside a melisma. A repeated untied pitch therefore receives
an explicit bare-vowel rearticulation instead of `+~`.

## E. Long-melisma refresh must be sparse

Do not restart a bare vowel at every convenient subdivision (for example every
triplet beat). Excessive refreshes create synthetic hiccups.

Use:
- sparse musically strong boundaries such as barlines;
- a minimum amount of intervening melisma;
- explicit rearticulation where the score actually repeats an untied pitch.

## F. Boundary regression tests are mandatory

For every movement, test at least:

- no duplicated onset cluster introduced by the exporter;
- syllable codas survive tie-chain merging;
- untied repeated same-pitch notes are not emitted as `+~`;
- true ties are not rearticulated;
- long-run vowel refresh density remains conservative.

## G. Repeated untied same-pitch notes may need an acoustic separator

The score rule remains:

```text
same pitch + tie      -> sustain one articulation
same pitch + no tie   -> new articulation
```

A bare-vowel restart is the default synthesis representation for an untied
repeated pitch inside the same syllable. However, DiffSinger may still fuse two
contiguous same-pitch notes acoustically even when the second note contains a
bare vowel.

For **the same vowel continuing within the same syllable**, Nishiren's validated
rearticulation device is now a short glottal separator:

```text
[o]  ->  [gs o]
```

Movement-3 bar 32 established the distinction experimentally. A bare `[o]` did
not articulate the repeated E5. `[cl o]` was also acoustically ineffective in
this same-vowel context. `[gs o]` produced the required restart, but Nishiren's
unmodified glottal stop was too strong. Moving only the `gs` onset later by
about **90.6 ms**, while leaving the vowel onset on the written note, gave the
preferred result. At 98 BPM / 480 PPQ this is **+71 ticks** on phoneme index 0.

Apply this only to genuine untied repeated-pitch rearticulations of the current
vowel, not to every bare-vowel refresh. Movement-3 v7 uses the rule at bar 32
and at the six same-vowel repeated-pitch restarts in bars 68, 70 and 72.

This rule does **not** replace the established short-closure treatment for a
true same-pitch vowel-to-vowel hiatus between different syllables/vowels. Keep
that as a separate class. Likewise, do **not** use `[SP]` for repeated-note
articulation: `[SP]` remains reserved for genuine written silence where neural
phrase continuity must be preserved.

## H. Cross-lingual DiffSinger banks: let the singer dictionary remap unsupported G2P phones

Do not assume that phonetic-hint syntax and ordinary lyric/G2P syntax take the
same path through OpenUtau. They do not.

For the current DIFF IT pipeline, OpenUtau's built-in Italian G2P uses:

```text
/tʃ/  -> tSS
/dʒ/  -> dZZ
/ʃ/   -> SS
```

This differs from older Italian syllable-based phonemizers, which may use
`tS`, `dZ`, and `S`. Do not mix those symbol inventories.

More importantly, a multi-dictionary DiffSinger bank may support Italian
cross-lingually through `dsdict-it.yaml` replacements. Ordinary lyric input is
passed through Italian G2P and then through the singer's replacement map, so an
abstract Italian phone such as `tSS` can be translated into whatever acoustic
model token that singer actually contains.

Bracketed phonetic hints are different: OpenUtau validates each explicit token
literally (or with the language prefix) against the singer's model vocabulary.
They do not automatically receive the same `dsdict-it.yaml` replacement path.
Thus forcing `[tSS i]` may still fail on a cross-lingual bank even though plain
Italian lyrics sing correctly.

Movement-3 regression example: ecclesiastical-Latin `-ci-` in `principium`.
The failed sequence was:

```text
[tS i]   -> `tS` rejected
[t S i]  -> `S` rejected
```

The production representation for Nishiren + DIFF IT is therefore the ordinary
orthographic syllable:

```text
ci
```

This deliberately hands `/tʃi/` to ItalianG2p, which generates the DIFF-IT
phone sequence and then allows Nishiren's own Italian dictionary to remap it to
supported model phones. Preserve explicit phonetic hints for phones already
known to be directly supported; fall back to orthographic G2P input where the
voicebank's cross-lingual replacement dictionary is required.

Movement-3 v5 applies this to all five `-ci-` occurrences (bars 10, 40, 62, 80,
and 86). OpenUtau/Nishiren listening subsequently confirmed that orthographic
`ci` works well. Regression-test that no `[tS i]` or `[t S i]` remains.

The same rule applies to ecclesiastical-Latin `/dʒ/`. OpenUtau's current
Italian G2P symbol is `dZZ`; the older/other-inventory `dZ` token is not valid
for this DIFF IT path. In Movement 3 the four failed `[dZ e]` syllables are all
`ge-` in `genui` (bars 81, 82, 83 and 87). Use ordinary orthographic `ge` so
ItalianG2p and Nishiren's singer dictionary perform the supported remapping.

## I. Preserve explicit editorial disambiguation of tuplets versus straight notes

When a performing edition deliberately changes beaming/stemming to distinguish
ordinary notes from nearby tuplets, treat that engraving choice as useful
edition evidence rather than normalising it away.

Movement-3 bar 31 is the regression example: Bärenreiter prints the final three
quavers with individual stems specifically to avoid confusion with surrounding
triplets. The intended rhythm is therefore:

```text
dotted crotchet + quaver + quaver + quaver
720 + 240 + 240 + 240 = 1440 ticks at 480 PPQ
```

Do not reinterpret those final three quavers as a triplet group.


## J. Repeated-word onsets may need consonant anticipation, not extra silence

When a repeated word already has an audible low-energy gap before its restart,
do not add a separator merely to make the repeat sound snappier. The problem
may instead be that the new onset consonant begins too late or too softly.

Movement-3 `virtutis | virtutis` is the regression example. In bars 15 and 43,
the second word begins `[v i]`. Advancing phoneme index 0 (`v`) by **30 ticks**
(about **38 ms at 98 BPM**) fills the pre-existing gap while leaving `/i/` on
the written onset:

```yaml
lyric: '[v i]'
phoneme_overrides:
- index: 0
  offset: -30
```

Treat this as a boundary-timing rule for the repeated-word context, not a global
rule that every `/v/` in the score should be advanced.

---

# Movement 3 final production lessons — v11 FINAL

**Lock date:** 4 Oct 2026

Movement 3 (*Tecum principium*) Soprano I **v11 is production-final**. Listening
QC accepted the complete track. Future work must branch from this lock rather
than altering it in place.

## K. Tie-chain final consonants must leave an audible receiving vowel

A syllable-final consonant attached to a collapsed tie chain must be timed from
the end of the complete tied sound, but it must not consume the short receiving
note that carries the end of the vowel.

Movement-3 bars 15 and 43 are the regression cases. The first `virtutis` ends
with `[t i s]` on a tie chain crossing into the next bar. Nishiren predicted the
final `/s/` too early, effectively replacing the receiving tied quaver with
sibilant/unvoiced material. Moving the final `s` later restored the sung tied
quaver.

The accepted v11 calibration is:

```yaml
lyric: '[t i s]'
phoneme_overrides:
- index: 2
  offset: 80
```

At 98 BPM / 480 PPQ, +80 ticks is about 102 ms. This is paired with the already
accepted repeated-word onset treatment on the following `[v i]`:

```yaml
phoneme_overrides:
- index: 0
  offset: -30
```

The musical objective is therefore:

```text
preserve tied vowel  ->  audible late /s/  ->  anticipated /v/  ->  /i/ on beat
```

Do not solve a disappearing receiving tie by deleting or rearticulating the tie.
Fix the coda timing.

## L. Long coloratura may require denser local vowel reseeding

The global rule remains sparse bare-vowel refresh, but the useful density is
renderer- and context-dependent. If a long melisma visibly/audibly loses energy,
add another bare-vowel seed at a musically strong untied boundary rather than
letting the neural state fade.

Movement-3 bar 25 is the regression case. The accepted v11 treatment reseeds
`[o]` at the barline and again at the two following quarter-note subdivisions:

```text
bar 25 + 0    [o]
bar 25 + 480  [o]
bar 25 + 960  [o]
```

A further bare-vowel refresh is present at bar 26 + 0. This is intentionally
more frequent than the default sparse policy because Nishiren audibly weakened
through this particular rapid run.

The principle is not "refresh every beat". It is: increase reseeding density
only where listening QC demonstrates loss of neural/acoustic stability, and
never break a true tie merely to insert a refresh.

## M. Same-vowel repeated-note glottal separators can remain singer-context dependent

For untied repeated same-pitch notes within one continuing vowel, `[gs o]`
remains the accepted Nishiren rearticulation device. However, Movement 3 showed
that Nishiren does not render identical `gs` timing uniformly in every phrase
context.

Accepted v11 calibrations are deliberately asymmetric:

```text
bar 32 reference restart:              gs offset +71
bars 68/70/72 first restart in pair:  gs offset -36
bars 68/70/72 second restart in pair: gs offset +36
```

The resulting articulations were accepted as production-grade even though small
residual differences remain between instances. Do not continue adding highly
specific timing hacks merely to make a neural singer mathematically uniform
once the musical rearticulation is clear and usable.

This is a renderer adaptation, not score semantics. A future singer/model may
need different values or no `gs` workaround at all.

## N. Movement 3 production lock

Current production lock:

```text
Movement 3 — Tecum principium
  Soprano I v11 FINAL
  Nishiren / DIFF IT
  98 BPM
  explicit-Latin hints where directly supported
  orthographic DIFF-IT fallback for cross-lingual ci / ge
  bar-31 straight-quaver override retained
  bars 15/43 tied-coda + repeated-word onset timing accepted
  long-melisma vowel refreshes accepted
  same-vowel gs rearticulations accepted with singer-context calibration
```

All listening QC passed on 4 Oct 2026. This USTX and its rendered WAV are the
Movement-3 Soprano production reference.

---

# Movement 3 accompaniment and player lessons — FINAL

**Lock date:** 4 Oct 2026

The user accepted the complete Movement-3 vocal v11 as production-grade and accepted the first accompaniment build without musical changes. Treat both as frozen masters:

```text
Soprano I:
    dixit_mvt3_soprano_v11_FINAL.wav
    vocal source: v11 FINAL USTX

Piano accompaniment:
    dixit_mvt3_repetiteur_piano_v1
    status: FINAL
```

## M. For fully written orchestral textures, reduce the written parts before inventing harmony

Movement 2 required an original figured-bass realisation because the surviving written texture was essentially solo voice plus continuo. Movement 3 is different: Handel supplies four complete upper-string voices plus continuo throughout the relevant orchestral passages.

The accepted Movement-3 répétiteur therefore uses:

```text
upper piano texture = literal Violin I + Violin II + Viola I + Viola II
bass                 = literal Violoncello/Bass/Continuo
```

Do not add an independent harmonic realisation when the score already supplies enough complete harmonic voices. The reduction should preserve the useful written attacks and voice-leading, not make the pianist reproduce an imagined published keyboard reduction.

This is the general decision rule:

```text
sparse continuo texture      -> realise harmony cautiously
fully written orchestral texture -> reduce the written parts directly
```

## N. Tuplet recognition is a two-stage inference: engraving topology proposes, meter validates

Movement 3 contains many unmarked triplet quaver groups. A robust instrumental parser cannot classify every group of three quavers as a triplet.

Accepted method:

1. use physical beam-group identity from the vector PDF to identify candidate three-quaver groups;
2. test candidate interpretation against exact bar closure;
3. apply the smallest set of triplet interpretations that makes the written 3/4 bar close;
4. retain straight quavers when closure does not require tuplet scaling.

This caught an important regression case in continuo bar 35: dotted crotchet + three beamed **ordinary** quavers is exactly 3/4. Blindly converting that three-note beam group to a triplet makes the bar short.

This complements the Bärenreiter bar-31 vocal regression, where the editor explicitly leaves three ordinary quavers unbeamed to distinguish them from nearby triplets.

General rule:

> Beaming is primary evidence for tuplet grouping, but not sufficient evidence for tuplet duration. Meter closure is the validation layer, not the initial classifier.

## O. Full-bar rests must be meter-aware

A semibreve-rest glyph in a 3/4 movement can represent a full-bar rest rather than a literal four-quarter duration. Interpret whole-bar rest semantics from the active time signature. This was necessary for zero-error closure of the Movement-3 instrumental extraction.

## P. Instrumental extraction must reach zero unexplained bar-closure errors before reduction

The final Movement-3 literal instrumental audit contains:

```text
Violin I:   403 events
Violin II:  257 events
Viola I:    190 events
Viola II:   194 events
Continuo:   244 events
confirmed instrumental ties: 12
bar-closure errors: 0
```

The 12 confirmed ties are sustained into the piano reduction rather than re-attacked. Do not proceed from a partially closing extraction to accompaniment synthesis by "fixing" durations in the reduction layer; repair the literal parser first.

## Q. Movement-3 player integration — superseded by Modular Player v1 FINAL

Movement 3 was the last movement to expose the cost of maintaining separate
player implementations. Its accepted audio and metadata now run under the same
shared modular engine as Movements 1 and 2.

Movement-3 musical/player data remain:

```text
91 bars
3/4
98 BPM

Soprano I calibration 1.00
Piano calibration     9.00

visible mixer defaults 70%
loop pause             500 ms
```

The frozen masters are not altered for web balance.

Canonical vocal WAV:

```text
/home/ajp/dixit/mvt3/dixit_mvt3_soprano_v11_FINAL.wav
```

Canonical web assets remain in the Movement-3 asset tree:

```text
/home/ajp/music/dixit-dominus/mvt3/movement-meta.json
/home/ajp/music/dixit-dominus/mvt3/audio/soprano1.mp3
/home/ajp/music/dixit-dominus/mvt3/audio/piano.mp3
```

The player shell/config now lives under:

```text
/home/ajp/music/dixit-dominus/_modular/mvt3/
```

Do not create another Movement-3-specific playback engine.

---

# Movement 4 final production lessons — v12 FINAL

**Lock date:** 4 Oct 2026

Movement 4 (*Juravit Dominus*) chorus **v12 is production-final**.

## N. Verify the page containing the next movement title

Do not assume the preceding movement ends on the prior page. Movement 4
continues in the top system of the page on which Movement 5 begins.

Boundary QC must inspect the complete page containing the next movement title.

## O. Nearby PDF lyric baselines belong to one visual underlay band

A single printed lyric line may contain small vertical-baseline shifts. Do not
discard a less-populated cluster merely because another nearby baseline has more
text objects.

Movement-4 Alto bars 28–29 are the regression case: clearly printed
`mi-nus, ju-ra-vit` sat about 1.5 pt away from the dominant baseline.

Anchor on the dominant baseline, but retain nearby lyric objects within the
validated lyric-band tolerance.

## P. Word-final consonant placement is prospective canonical technique * **

From Movement 4 onward:

```text
vowel -> full written note
final consonant -> exact following rest onset
```

Use a short consonant-only release event entirely within the written rest.

**\*** From Movement 5 onward, apply the short-rest / fast-passage exception:
if such a release would consume most of an isolated short rest between rapid
figures, finish the coda inside the preceding note and preserve the written rest
as silence.


**\*\*** At a movement ending with no printed following rest/bar, sustain the
final vowel through the complete final note and place the final consonant on
the **notional downbeat of the next bar**. The rendered audio may extend briefly
past the score boundary for this release.

Do not reopen already accepted Movements 1–3 solely to retrofit this rule.

## Q. Long neural sustains may need periodic bare-vowel reseeding

Listening QC can justify denser bare-vowel refreshes when a DiffSinger loses
level/state across very long sustained or melismatic spans.

Movement-4 Bass bars 3–5 are the regression case.

The accepted repair re-seeds `[a]` at each new long minim after the initial
`[r a]`.

Never repeat the onset consonant, and never break a genuine score tie merely to
insert a refresh.

## R. Renderer operations are singer-inventory specific

Describe the desired acoustic operation separately from the token used to
implement it.

Movement-4 experiments demonstrated:

```text
Nishiren: gs can be available
Alex:     gs is not available
Alex archive may contain es/q, but the standard Spanish phonemizer rejects q
Alex:     cl is a supported global special phone
```

Never copy a phoneme token between singers without checking the active
phonemizer and singer inventory.

## S. Difficult adjacent-vowel + large-leap rescue may remain singer specific

Movement-4 Bass `e-um` remained somewhat "gulpy" across downward leaps despite
closure and multisyllable-grouping experiments.

The accepted pragmatic v12 treatment anticipates only the `/u/` phoneme by
about 50 ms while leaving the written note/pitch onset unchanged.

Treat this as an **Alex-specific rescue technique**, not a generic Latin rule.

## T. Written choral unisons keep both voices

When Soprano I and Soprano II genuinely duplicate one another for a sustained
written passage, keep both stems and attenuate each to 0.75× in player metadata.

Movement-4 confirmed passages:

```text
bar 37 start -> bar 46 beat 2
bars 48–50 inclusive
```

Do not infer broad attenuation ranges from isolated pitch coincidences.

---

# Movement 5 final production lessons — v14 FINAL

**Lock date:** 5 Oct 2026

Movement 5 (*Tu es sacerdos*) chorus **v14 is production-final**.

## U. Movement-end consonants preserve the complete final written vowel

The musical invariant is independent of singer technology:

```text
final written note -> complete written vowel duration
notional next-bar downbeat -> final consonant begins
```

Do not move the consonant earlier merely because the engraved movement ends.
The renderer and audio container may continue briefly beyond the score boundary.

Movement 5 is the canonical regression case:

```text
30 bars · 4/4 · 100 BPM
score end = tick 57600 = 72.000 s
word = Melchisedech
```

## V. Terminal-release tokens are singer-specific implementation details

Accepted Movement-5 v14 realization:

```text
Nishiren female voices:
    Soprano I  [k axh]
    Soprano II [k axh]
    Alto       [k axh]

Alex male voices:
    Tenor      [k e]
    Bass       [k e]
```

All begin at tick 57600, the same notional bar-31 downbeat.

Do not elevate `[k axh]` or `[k e]` into universal Latin phoneme rules. The
canonical rule is the **placement of the final consonant after the complete
written vowel**; the token used to make a particular DiffSinger produce that
consonant remains singer- and phonemizer-specific.

The accepted Alex `[k e]` release is a pragmatic compromise: its vowel component
is somewhat over-voiced, but it is preferable to an absent terminal stop.

## W. Keep score duration separate from renderer/playback tail

Movement 5 established a necessary three-way distinction:

```text
score duration:     72.000 s
v14 vocal WAV end:  approximately 72.154–72.162 s
web playback end:   72.190 s
```

The extra audio is diction/release tail only. It must not create an extra score
bar or alter bar-30 timing.

## X. Replacing web audio under the same pathname requires cache versioning

The shared player intentionally caches decoded stem assets aggressively. When a
new accepted render replaces an existing MP3 while keeping the same pathname,
a browser can continue to serve the old stem.

Movement-5 v14 exposed this directly: the new MP3s and 72.190-s metadata were
correct, but the browser initially replayed cached pre-v14 stems, making the new
terminal release appear to be cut off.

Canonical deployment rule:

```text
same stable pathname + new accepted audio revision
    -> change the URL identity in movement.json
```

A query-string version is sufficient, for example:

```text
/music/dixit-dominus/mvt5/audio/soprano1.mp3?v=v14
```

Changing the filename is also valid. Do not diagnose an apparent end-of-track
failure until stale browser audio has been ruled out.

This is a player-asset deployment rule, not a change to the score or renderer.

---

# Movement 6 final production lessons — FINAL

**Lock date:** 6 Oct 2026

Movement 6 (*Dominus a dextris tuis*) is production-final.

## Y. Courtesy time signatures at the next movement boundary do not change the current movement metre

Movement 6 contains 148 bars and remains in **3/4 throughout** at the accepted
100 BPM rehearsal tempo.

The common-time signs printed at the extreme right after bar 148 are courtesy
signatures for Movement 7, not a late Movement-6 metre change.

Canonical lesson:

> A time-signature glyph near the end of a system must be assigned to the
> musical span it actually governs. Do not let a next-movement courtesy signature
> create a false metre event in the current movement.

For Movement 6:

```text
bars:                  1–148
metre:                 3/4 throughout
tempo:                 100 BPM
exact score/MIDI end: 266.400 s
```

## Z. Solo and tutti roles may share the same rendered part stems

Movement 6 prints solo and tutti material on the same five vocal staves. The
accepted rehearsal build therefore uses the same Soprano I, Soprano II, Alto,
Tenor and Bass stems through both textures.

There is no dedicated Soloists stem and consequently no Movement-1-style
duplicate-solo suppression rule.

Do not invent separate audio architecture merely because the score changes
`Solo` / `Tutti` role. Treat the role as score/event metadata unless a distinct
rendered stem is actually required.

## AA. Do not impose a generic “soloists louder than chorus” rule when the movement's form argues otherwise

Movement 6 is accepted as a deliberate two-part dramatic shape:

```text
bars 1–80:
    restrained / reflective solo texture
    lighter accompaniment

bar 81 onward:
    full five-part chorus
    fuller written orchestral texture
    natural increase in weight
```

The accepted player has **no solo-vs-chorus gain switch**. The tutti expansion
comes from the written change in forces, not an artificial gain event.

This is an interpretive decision specific to Movement 6. It does not repeal
other movements' accepted solo/chorus balance.

## AB. Orchestral unison duplication must be reduced as piano texture, not reproduced as duplicate sample attacks

A literal orchestral reduction can contain two written instruments striking the
same pitch at the same instant. Those are two orchestral players, but on a piano
they correspond to one physical key.

Movement-6 piano v1 mapped both written notes to simultaneous identical piano
note-ons. This produced excessive weight at the bar-81 tutti entry.

Accepted piano v2 rule:

```text
Vln I + Vln II
same attack time + same written pitch
    -> one piano-key attack

Vla I + Vla II
same attack time + same written pitch
    -> one piano-key attack
```

Do **not** generalize this into indiscriminate pitch deduplication:

- continuo is untouched;
- violin/viola cross-family coincidences are untouched;
- genuine repeated notes remain repeated;
- written ties remain sustained;
- only exact simultaneous duplicate attacks inside the doubled upper-string
  families are collapsed.

Movement-6 audit:

```text
v1 logical piano attacks:        2215
v2 logical piano attacks:        1686
duplicate attacks removed:        529
before bar 81:                      1
bars 81–148:                      528
Vln I / Vln II duplicates:       314
Vla I / Vla II duplicates:       215
```

This is the canonical regression case for the broader principle:

> Preserve independent orchestral voice-leading, but do not confuse orchestral
> multiplicity with repeated striking of an identical piano key.

## AC. Hidden calibration can compensate for voicebank projection without changing the master audio

The accepted Movement-6 hidden calibration at the canonical visible 70% mixer
position is:

```text
Soprano I   0.5000
Soprano II  0.5000
Alto        0.5357
Tenor       1.1800
Bass        1.6000
Piano       1.7382
```

The relatively large Alex Tenor/Bass compensation is a player-balance decision,
not a change to the accepted WAV masters.

Do not normalize or destructively amplify a final singer WAV merely because one
voicebank projects less strongly in a mixed rehearsal texture. Preserve the
master and solve stable balance in hidden calibration.

## AD. Renderer-specific Latin consonant solutions remain lexical and singer specific

Movement 6 introduced the ecclesiastical-Latin soft `g` problem in the Alex
Floarea Spanish-phonemizer tracks.

Accepted listening-derived Alex mappings for this movement are:

```text
confregit -> [d y i t]
reges     -> [d y e s]
```

The earlier `[ch i t]` trial for `confregit` was rejected after listening.

Movement 6 also established two useful contextual repairs:

```text
melismatic confregit:
    [k o n] [f r e] +~ ...
    -> [k o n f r] [e] +~ ...

dextris:
    [d e k s] +~ [t r i s]
    -> [d e] +~ [k s t r i s]
```

These produce the desired practical result in the accepted render, but they are
**not universal Latin phonetic rules** and should not be transferred blindly to
Nishiren or another Alex/phonemizer configuration.

As elsewhere in the project, preserve the hierarchy:

```text
desired linguistic/acoustic target
        ↓
singer + phonemizer inventory
        ↓
listening-accepted renderer token
```

## AE. Score duration and a long instrumental renderer tail remain distinct

Movement-6 timing is:

```text
score / MIDI end:          266.400 s
FluidR3 piano WAV end:     269.105 s
documented renderer tail:    2.705 s
```

The player transport may retain the 269.105-s endpoint so the accepted piano
release decays naturally. The extra 2.705 s is not a 149th bar.

The five vocal masters end earlier because the voices finish before the
instrumental coda. Web stems may be silence-padded to a common transport length;
this must never be mistaken for stretching the vocal performance.

---

# Movement 7 vocal production lessons — v20 FINAL

**Lock date:** 6 Oct 2026

Movement 7 (*Judicabit*) chorus **v20 is vocal-production-final**. The user
exported the five accepted WAV stems from this build. The unchanged Movement-7
piano v1 was subsequently rendered with the canonical FluidR3 chain, accepted,
and locked with the final player balance.

## AF. Key signatures are movement-local parser state

Never inherit a key signature from a copied parser configuration or the
preceding movement.

Canonical parser sequence:

```text
movement begins
    -> read the printed key signature
    -> reset key-signature / accidental state
    -> initialize this movement from the printed signature
    -> parse pitches
    -> apply printed accidentals with normal bar-level persistence
```

Movement 7 is the regression case.

Movement 6 legitimately has two flats:

```text
B-flat
E-flat
```

Movement 7 has **one flat only**:

```text
B-flat
```

The first Movement-7 parser accidentally retained Movement 6's E-flat. This
silently converted unmarked written E-naturals to E-flat (displayed
enharmonically by OpenUtau in some places as D-sharp), while every affected bar
could still close rhythmically.

Therefore:

> Zero rhythm/bar-closure errors do not validate key-signature interpretation.

Stage-1 pitch QC must sample every pitch class affected by the active key
signature, especially after a movement boundary or copied-parser change.

## AG. `+~`, `[V]` and `[V V]` are distinct neural-sustain operations

A score continuation and a useful neural rendering instruction are not the same
thing.

Movement 7 established a practical hierarchy:

```text
+~
    use when the singer carries the vowel cleanly

[V]
    bare-vowel reseed when a long state simply fades or disappears

[V V]
    stronger late transition refresh when the singer decays before the next
    syllable or needs a crisp boundary into the following consonant
```

Waveform inspection showed that `[V V]` can cause the model to allocate a
second explicit vowel segment within one note. This can maintain useful acoustic
energy to the following phoneme boundary when `+~` or a single `[V]` decays.

This is a renderer-state tool, not a notation change.

## AH. Doubled-vowel refresh is symptom-triggered, not grammatical

Do **not** replace every continuation or every lexical vowel with a doubled
vowel.

Movement 7 also demonstrated the failure mode: a blanket

```text
[r u] -> [r u u]
```

pass across female `ruinas` improved some transitions but made others sound like
an intrusive `w` / "whroo-" onset. The broad pass was rolled back.

Accepted principle:

> Use `[V V]` where listening or waveform inspection demonstrates state decay
> or a weak boundary. Preserve the ordinary single vowel where it already
> renders cleanly.

The final build therefore contains local `ruinas` doubles only where they were
actually useful, notably Alto bars 35–36.

## AI. Doubled-vowel refresh can precede an anticipated consonant

When consonant anticipation is already musically justified, the sustained vowel
may itself need refreshing before the consonant.

Movement-7 Alex examples:

```text
[a b]   -> [a a b]
[a t]   -> [a a t]
[a t s] -> [a a t s]
```

This combines two established operations:

```text
second vowel segment -> keeps acoustic state alive
anticipated consonant -> prepares the next syllable before its written vowel onset
```

The written pitch onset of the following syllable remains unchanged.

Tenor bar 16 `nationibus` is the regression example:

```text
[a a t s] [i] [o]
```

This was substantially crisper than `[a t s] [i] [o]`.

## AJ. Long lexical notes can use a terminal vowel duplicate

The same state-refresh principle can work inside a long explicit syllable:

```text
[y u]   -> [y u u]
[t y u] -> [t y u u]
[b i]   -> [b i i]
[b u]   -> [b u u]
```

Use this conservatively on a long note immediately before another sung event
when the original waveform decays before the boundary.

It is not a spelling rule and should not be applied merely because the note is
long.

## AK. Fast `implebit` clusters require singer-specific consonant partitioning

At 100 BPM a semiquaver is only 150 ms. Asking a neural singer to create the
entire `/pl/` cluster on that first fast note can delay or erase the vowel.

Accepted Movement-7 treatments differ by singer.

Alex Tenor/Bass:

```text
[i m] [p l e]
    -> [i m p l] [e]
```

Nishiren S1/S2/Alto:

```text
[i m] [p l e]
    -> [i m p] [l e]
```

Local Nishiren exception, Soprano I bar 54:

```text
[i m p l] [l e]
```

because the ordinary female split lost the `/l/` in that context.

Do not force one singer's cluster partition onto another singer.

## AL. A final stop may need voiced future context to exist acoustically

Alex's Spanish model can contain a nominal final `/t/` or `/k/` phone while
producing essentially no audible release. Waveform inspection can show a flat
region even though the phoneme is explicitly present.

Movement 7 generalized the Movement-5 `Melchisedech` lesson.

If a final `/t/` is immediately followed by another sung event, the stop can be
carried into that event:

```text
judica... [i] [t y u] ...
```

The `/t/` remains linguistically final to `judicabit`; moving it into the next
phonetic event is renderer adaptation.

If the final stop is followed by silence, Alex may require a sacrificial voiced
carrier:

```text
[i] [t e] rest
```

The carrier should be as short as possible. In Movement 7, OpenUtau's practical
minimum of **15 ms** was sufficient to create the stop release while avoiding an
audible "teh" syllable.

At 100 BPM / 480 PPQ:

```text
15 ms = 12 ticks
```

This is an Alex/DIFF-ES implementation detail, not a Latin phonetic target.

The same insight motivated a Movement-5 editable v15 refinement:

```text
Alex Tenor/Bass final Melchisedech [k e]:
    48 ticks / 60 ms
    -> 12 ticks / 15 ms
```

The Movement-5 production audio remains on its previous lock until the shorter
rerender is explicitly promoted.

## AM. Preserve final consonants explicitly and audit them separately

A lyric underlay can be textually correct while a renderer release is absent.

For words such as:

```text
judicabit -> final /t/
nationibus -> final /s/
ruinas -> final /s/
```

perform a final-consonant audit independent of the vowel/syllable underlay.

Check:

```text
phoneme exists
        +
phoneme is timed in a musically sensible place
        +
waveform actually contains an audible release
```

Do not infer success merely because `[t]` or `[s]` appears in the USTX.

## AN. Edition underlay remains separate from renderer repair

When the performing edition supplies a corrected syllable placement, encode
that as an explicit edition/performance override before renderer adaptation.

Do not use doubled vowels, consonant anticipation, or timing hacks to conceal a
wrong score underlay.

The diagnostic order remains:

```text
score extraction
edition choice
lyric assignment
tie/rest topology
phoneme timing
neural phrase/state behaviour
acoustic controls
```

## AO. Movement-7 accompaniment extraction adds two parser cautions

The orchestral extraction exposed two notation cases that are legitimate score
structure, not parser failure.

### Clefs can change inside one staff

Movement 7 Continuo changes between treble and bass clef within systems.
Instrument pitch extraction must therefore use the latest active clef at each
note position; a fixed part-level clef is insufficient.

### A polyphonic staff does not close by summing all voices together

The Continuo is genuinely polyphonic in bars:

```text
2, 3, 8, 13, 41, 42
```

Summing all simultaneous voices gives more than four quarter-note units. That
does **not** mean the measure is corrupt.

For a polyphonic staff:

```text
identify voices / stem directions
validate each complete voice against the metre
do not require the sum of simultaneous voices to equal one bar
```

Movement 7 piano v1 selects the complete written bass voice from these
polyphonic bars and does not invent harmony.
# Movement 8 final production lessons — v10 + RNDTIME Bass FINAL

**Lock date:** 8 Oct 2026

Movement 8 (*Conquassabit*) is production-final. It contributed several rules
that apply beyond this movement, particularly around score-state detection,
explicit repeated-note articulation, and acoustic correlation between cloned
synthetic singers.

## AP. Detect the printed key signature at every movement boundary; do not inherit it

Movement 8 confirmed and strengthened the Movement-7 rule.

The first Movement-8 parser inherited a two-flat assumption from earlier work.
The score actually prints **one flat, B-flat only**. The canonical stage-1 parser
therefore detects the signature from the score itself:

```text
for each vocal staff:
    locate the staff's own clef
    inspect the key-signature corridor after that clef
    stop at the time signature / first musical event
    interpret accidental glyphs by staff position and clef

require S1 / S2 / Alto / Tenor / Bass consensus
if consensus fails:
    ABORT
```

There is no fallback to the previous movement and no hard-coded default.

For Movement 8 all five vocal staves independently report:

```text
B-flat only
```

Rhythmic closure cannot validate this. A wrong key signature can produce
perfectly closing measures with systematically wrong pitches.

The same ownership principle applies to clefs: a clef glyph belongs to a staff
only when both the named staff and the current score system geometry support
that assignment. Movement 8's final orchestral system on the page shared with
Movement 9 is the regression case; a lower-system Movement-9 clef must not leak
into Movement 8.

## AQ. Edition corrections remain explicit and minimal

The accepted performing-edition correction in Alto bars 6–9 changes pitch only.
The literal Legge extraction was preserved first, then the Bärenreiter/HHA
performance override was applied as a separate layer.

Exactly four Alto tone fields change. Rhythm, lyric assignment, phonemes,
duration, and note topology do not.

This is the model for edition differences:

```text
literal score extraction
        ↓
small explicit edition/performance override
        ↓
renderer adaptation
```

Do not hide a pitch correction inside a phonetic or timing repair.

## AR. Dense repeated text may require explicit attack on every written note

In *Conquassabit*, every written note of the word needs rearticulation,
including crotchets and quavers. Bare repeated vowels are not sufficient with
these singers.

Accepted singer-specific separator tokens are:

```text
Nishiren women: gs
Alex men:       cl
```

A separator at the receiving note may be omitted only when both conditions hold:

```text
1. written pitch changes
2. previous final non-separator phone != receiving first non-separator phone
```

Otherwise retain the separator. The Bass bar-13 `[s a] -> [a]` boundary is the
regression case: the pitch changes, but the acoustic boundary is still `a -> a`,
so `cl` remains necessary.

Movement-8 terminal `bit` before a rest uses a local implementation in which the
written note carries the full `[... i t]` material and the following rest-onset
slot can be repurposed as the separator. This is an M8 renderer solution, not a
general Latin rule.

Likewise, the accepted Alex `capita inter` repair is deliberately local:

```text
[i n] [t e r] -> [i n t] [t e r]
```

Do not generalize either repair without a matching acoustic failure.

## AS. Cloned-singer phase correlation is distinct from musical doubling

Movement 8 exposed a new failure mode in exact Tenor/Bass unisons. Tenor and
Bass are separate written parts but both use the same Alex synthetic singer.
On exact same-pitch notes their deterministic waveforms can become strongly
correlated or anti-correlated.

Bar 13 supplied a controlled regression case:

```text
Tenor: C4  Bb3 C4  Bb3 C4  Bb3
Bass:  F3  Bb3 F3  Bb3 F3  Bb3
             ^       ^       ^
          exact cloned-singer unisons
```

With the original renders the mean correlation across those three unisons was
approximately:

```text
-0.447
```

and the unison group was abnormally weak. This was destructive interference,
not a player bug and not a score-balance decision.

Several attractive-looking fixes were rejected as general rules:

```text
fixed ~2.09 ms delay
    -> corrected the local B-flat phase relationship but was pitch-specific

tiny note-synchronous vibrato
    -> moved phase relationships inconsistently and did not remove the pathology

static +3 / +5 cent tuning offsets
    -> produced strongly non-monotonic constructive/destructive outcomes;
       not true general decorrelation
```

A single application of OpenUtau **Randomize Note Timing** to the Bass produced:

```text
mean exact-unison correlation:
    original  -0.447
    randomized +0.091
```

and was accepted by listening over the complete movement.

The important distinction is:

> Written doubling / balance and cloned-singer waveform correlation are two
> different problems.

Do not use one control as a substitute for the other.

## AT. Canonical cloned-singer decorrelation is a fixed performance realization

For future production, treat one singer instance as the timing anchor and give
the routinely overlapping clone an independent micro-timing realization.

Project default:

```text
Nishiren:
    Soprano I  = timing anchor
    Soprano II = apply Randomize Note Timing once when producing the movement
    Alto       = unchanged unless a concrete collision requires attention

Alex:
    Tenor      = timing anchor
    Bass       = apply Randomize Note Timing once as the production default
```

The randomization is applied **once**, then the resulting offsets are saved in
the canonical USTX. Do not invoke Randomize Note Timing every time a WAV is
rendered; that would create a different performance on each render and destroy
reproducibility.

Movement 8 itself locks the accepted randomized Bass realization in:

```text
/home/ajp/dixit/mvt8/dixit_mvt8_chorus_v10_FINAL.ustx
```

with the corresponding accepted acoustic master:

```text
/home/ajp/dixit/mvt8/dixit_mvt8_bass_v10_RNDTIME_FINAL.wav
```

Movement 8 Soprano II was already accepted before this rule was adopted and is
not retroactively changed.

## AU. Timing decorrelation does not replace written-doubling attenuation

The established Soprano-I/Soprano-II gain treatment remains valid where the
score contains a **substantial passage of genuine written doubling**.

Keep the conceptual layers separate:

```text
Randomize Note Timing
    -> acoustic decorrelation of cloned singer instances

0.75×-type passage attenuation
    -> musical balance when two written parts substantially duplicate one line
```

An occasional coincidental unison does not justify passage gain attenuation.
Conversely, decorrelating two cloned singers does not mean a long doubled
passage should automatically be allowed to become twice as prominent.

The existing Movement-1 and Movement-4 written-unison attenuation remains a
musical precedent.

## AV. Piano same-family collapse is a third, separate operation

The répétiteur handles duplicate orchestral pitches differently because a
single pianist cannot meaningfully strike the same physical key twice at the
same instant.

Movement 8 therefore retains:

```text
Vln I + Vln II exact simultaneous same pitch -> one piano attack
Vla I + Vla II exact simultaneous same pitch -> one piano attack

cross-family coincidence -> retain
continuo coincidence     -> retain
true repeated attack     -> retain
```

This is a **keyboard reduction rule**. It is neither vocal phase decorrelation
nor player gain attenuation.

The three mechanisms must not be conflated:

```text
orchestral duplicate -> collapse in piano reduction
cloned synthetic singers -> fixed micro-timing decorrelation
substantial written vocal doubling -> optional light passage attenuation
```

## AW. Movement-8 production lock

Final score and accompaniment:

```text
50 bars
3/4 throughout
100 BPM
one-flat key signature (B-flat only)
score/MIDI endpoint:      90.000 s
FluidR3/player endpoint:  92.704 s
piano MIDI note-ons:      777
piano MIDI SHA-256:
24f1bf0283d24c4813e5fa56aad756e23dd7f658754a0fb2d7eb066f62e09690
```

Final hidden calibration at visible 70%:

```text
Soprano I   0.5357
Soprano II  0.5357
Alto        0.5357
Tenor       1.1800
Bass        1.6000
Piano       1.5852
```

The vocal source, accepted Bass render, piano MIDI/WAV, player configuration,
score metadata, and web assets form one frozen Movement-8 production state.


## AX. Stage-1 parser canonical v4: bind score state to the retained system before decoding it

Movement 9 begins on the **same PDF page** on which Movement 8 ends.  This made
an implicit parser assumption visible: nearest-staff geometry alone is not a
sufficient ownership rule when two independent score systems share one page.

The canonical parser is now:

```text
dixit_stage1_parser_v4_CANONICAL.py
```

with frozen profiles/regression cases for Movements 8 and 9.

The order of operations is now a hard invariant:

```text
identify complete page systems
        ↓
retain only the systems belonging to the selected movement
        ↓
bind named vocal staves within those retained systems
        ↓
locate each staff's own clef
        ↓
decode the printed key-signature corridor
        ↓
require exact named-vocal-staff consensus
        ↓
parse pitches / accidentals / rhythm / lyrics
```

Do **not** decode page-level clefs or key accidentals and then decide which
movement/system they belonged to.  Filtering to the movement comes first.

Within a retained system a candidate clef/key glyph belongs to a staff only if
both conditions hold:

```text
1. that staff is the nearest staff geometrically; AND
2. the glyph lies within the allowed vertical proximity of that staff/system.
```

This prevents an opening clef or accidental from the other system on the same
PDF page from contaminating movement-local state.

PDF page 51 is the canonical two-way regression case:

```text
Movement 8 — retain TOP system only
    printed opening signature at its own movement start: B-flat only
    5 named vocal staves agree
    final bar: 50

Movement 9 — retain LOWER system only
    printed opening signature: B-flat + E-flat
    4 named vocal staves agree
    final bar: 36
```

The canonical v4 regression suite reproduces the already-validated core
extraction byte-for-byte for the principal event/lyric/syllable CSVs in both
movements.  Thus adoption of v4 changes parser ownership infrastructure, not the
frozen Movement-8 musical extraction.

Canonical safety rule:

> Movement boundary and system ownership are score state.  Resolve them before
> clef, key-signature, accidental, lyric, or note interpretation.  If printed
> opening-state consensus fails, abort; never inherit a fallback from a nearby
> system or preceding movement.

---


---

# Movement 10 — production lessons and parser-quality addendum


**Applies prospectively; do not retrofit Movements 1–9 solely for conformity.**

## 1. Long notes need renderer-friendly vowel subdivision

On an untied whole note whose vowel decays or whose predicted coda arrives too early, divide the **renderer event**, not the score event, into shorter notes of identical pitch and identical total duration. At 100 BPM, our successful default was two minims. Keep the initial consonant on the first half, repeat the vowel at the join, and put the terminal consonant on the second half:

- `[r a t]` (four beats) → `[r a]` (two beats) + `[a t]` (two beats)
- `[i n]` → `[i]` + `[i n]`
- `[p r i n]` → `[p r i]` + `[i n]`

These are synthesis-time subdivisions. **Never transcribe the halves as two new Handel notes in the canonical literal score layer.** Do not break true written ties indiscriminately. Some tied long notes benefit from a doubled-vowel state refresh within a single OpenUtau note; decide acoustically.

For a three-beat note, another accepted local treatment was a two-beat first event followed by a one-beat continuation, e.g. Alto M10 bar 47 `[t s i]` (two beats) `[i]` (one beat), preserving the original pitch and duration.

## 2. Systematic vowel re-seeding in extended melismas

Don't allow tens of `+~` continuations to accumulate simply because note pitches change. A score melisma is not inherently monotonic; the singer refreshes breath/vocal energy and maintains vowel presence. Scan contiguous vowels after an initial syllable such as `[g l o]`, `[p a]`, `[s a]`, `[a]`. If there is an extended run of unrefreshed `+~`, re-seed `[o]` or `[a]` approximately once per crotchet **at existing untied note onsets**, preferentially on whole beats. Preserve following *ria*, *men*, etc. consonants and edited score underlay. The v26 Alto audition and v27/v28 all-voice extensions were user-accepted.

The run detector should consider phonemes' **active sustained vowel**, not just exact `[a]` or `[o]` tokens; an `[a]` melisma may start as `[p a]` or `[s a]`. Exempt rests, true tie receivers, rearticulated consonant syllables, and already-refreshed spans. Audition to check that re-seeds do not become audible repeated attacks.

## 3. Explicit score rests, not standalone pitched silence carriers

Movement 10 established that an isolated pitched `[SP]` note occupying a genuine printed rest can produce audible artifacts. Default to an actual **empty score rest** in the OpenUtau note timeline and restart the ongoing vowel `[a]` on the next sung note, even if the melismatic syllable identity continues. This does not invalidate the historically accepted narrow Movement-2 use of `[SP]` where maintaining DiffSinger phrase context solved a specific audible issue. Keep these distinct.

## 4. Singer-specific articulation must be learned by listening

OpenUtau Nishiren female voices: short semiquaver `[t u][i]` benefited from `[t u i][i]`; Alex male voices did not require this treatment. For `sancto`, the accepted female short-note articulation was `[s a n k t cl][cl k cl t o]`, while longer melismatic `san-` at a crotchet/minim may simply be `[a n][cl k cl t o]`. Alex's accepted ordinary quaver implementation was `[s a n k cl][cl k cl t o]` (and its shorter melismatic counterpart). Do not propagate these as language-wide Latin transcription rules or between singer inventories without audition.

Consonant closure before *men* depends on the note duration and acoustic behavior: short pre-*men* notes generally use `[a][m e n]`; on a long same-pitch sustain an explicit `[cl a]` (Alex) or `[gs a]` (Nishiren) may tighten the /m/ at its actual score onset. The Movement-10 auditions produced specific exceptions; treat duration as a heuristic, not a mechanistic guarantee.

## 5. Editorial overrides and instrumental clef/range QC

Keep **literal Legge extraction → documented Bärenreiter/performer overrides → renderer adaptation → stems → player** as separate layers. M10 requires explicit corrections including Tenor bars 47–48 missing syllabic underlay and instrumental Violoncello bars 122–125. The high cello notes in Legge's bass-clef ledger notation are made clearer in Bärenreiter by a switch to treble clef during bar 122 through bar 125, then back to bass clef at bar 126. The literal vector parser erroneously produced two impossible A1s and missed bar-123 pitches; the piano v3 overlay restores the user-verified reading (E4, F♯4, G4, quaver rest, C4/G4 double-stop). A genuine E♭4 tie crosses bars 124–125.

The post-extraction instrumental validator checks all 175 bars, physical instrumental ranges, score-time coverage, 62 preserved instrumental ties, those four corrected cello bars, and the exact accepted MIDI checksum. Its findings **do not constitute a fresh score-glyph-by-glyph transcription**; the older raw vector staff ownership/overlap parser has documented weaknesses. Future scores need improved ledger-line, chord/polyphonic-rest and staff-local clef-state interpretation, not merely an out-of-range detector.

## 6. OpenUtau timing randomisation and vocal WAVs

Once-only Randomize Note Timing on Movement-10 Soprano II and Tenor was accepted and frozen in the USTX/WAV masters. OpenUtau expanded those parts' nominal containers to 176 bars without adding musical notes. Correcting the containers to 175 bars removed that editor artifact without touching any note. WAV audit confirmed that the exported audio files did **not** contain an additional bar of silent padding. Never rerandomize accepted stems or trim finished WAVs merely because a part container expanded.

## 7. M10 production lock (10 October 2026)

Movement 10 — *Gloria Patri*: 175 bars, 4/4, 100 BPM; score 420.000s, web transport 422.004s. Five accepted v34 chorus vocal WAVs (Nishiren S1/S2/Alto, Alex Tenor/Bass); corrected 175-bar USTX with S2/Tenor once-only randomized timing. Written piano reduction v3 (FluidSynth/FluidR3), accepted with cello bars 122–125 Bärenreiter correction. Final hidden calibrations, all visible sliders 70%: S1 0.5357, S2 0.5357, Alto 0.5357, Tenor 1.1800, Bass 1.6000, Piano **1.7786**, accepted global +5dB piano lift. Voices were already accepted and are unchanged.

Movement-10 lock metadata, SHA-256 manifest and instrumental parser-v2 audit are stored under `~/dixit/mvt10/` when the final-lock script is executed. Shared player and Movements 1–9 stay frozen.
