diff --git a/README.adoc b/README.adoc
index 24083c7..bd0a4ee 100644
--- a/README.adoc
+++ b/README.adoc
@@ -204,8 +204,9 @@
 Änderungsantrag::
   Ändert nicht das Stammgesetz, sondern eine *Drucksache* — siehe unten.
 Beschlussempfehlung::
-  Trägt ihre Fassung in einer zweispaltigen Zusammenstellung. Erkannt,
-  aber noch nicht angewandt (siehe unten).
+  Trägt ihre Fassung in einer zweispaltigen Zusammenstellung, die
+  aufgelöst wird — die Synopse zeigt dann die vom Ausschuss beschlossene
+  Fassung (siehe unten).
 Dokument ohne Änderungsbefehle::
   Entschließungs- und schlichter Antrag, Plenarprotokoll, Bericht. Sie
   werden übergangen und gemeldet — nicht stillschweigend zu null
@@ -243,31 +244,45 @@
 Beschlussformel führt („1. In Nr. 1.29 die Angabe „,“ am Ende durch die
 Angabe „;“ ersetzt.“).
 
-=== Beschlussempfehlungen: erkannt, noch nicht angewandt
+=== Beschlussempfehlungen: die beschlossene Fassung
 
 Die maßgebliche Fassung einer Beschlussempfehlung steht in einer
 zweispaltigen Zusammenstellung: links der Entwurf, rechts die Beschlüsse
-des Ausschusses. Die Spaltentrennung ist erledigt und belegt — anders
-als beim alten BGBl und beim Berliner GVBl stehen die Spalten *nicht*
-nacheinander im Inhaltsstrom, sondern zeilenweise verschränkt, weshalb
-sie erstmals koordinatenbasiert getrennt werden (`PatchTextExtraktor.
-extrahiereSpalten`, Schnitt an der Blattmitte, aber nur an einem
-tatsächlichen Spaltensteg, damit ganzseitenbreite Zeilen ungeschnitten
-bleiben). Der Akzeptanztest hält fest, dass die linke Spalte Befehl für
-Befehl den Regierungsentwurf ergibt, aus dem die Zusammenstellung gebaut
-ist.
+des Ausschusses. Anders als beim alten BGBl und beim Berliner GVBl
+stehen die Spalten *nicht* nacheinander im Inhaltsstrom, sondern
+zeilenweise verschränkt; getrennt werden sie deshalb über die
+Koordinaten (`PatchTextExtraktor.extrahiereSpalten`, Schnitt an der
+Blattmitte, aber nur an einem tatsächlichen Spaltensteg, damit
+ganzseitenbreite Zeilen ungeschnitten bleiben).
 
-Was fehlt, ist die Auflösung der rechten Spalte. Sie druckt Unverändertes
-nicht ab, sondern vermerkt bloß „unverändert“ — und zwar nicht nur je
-Gliederungspunkt, sondern auch zeilenweise innerhalb zitierter Blöcke.
-Dadurch ist die rechte Spalte für sich genommen kein vollständiges
-Dokument: Ihre Anführungszeichen gehen nicht auf. Eine Auflösung über
-Gliederungspfade allein scheitert daran nachweislich; nötig ist die
-zeilenweise Zuordnung beider Spalten über ihre gemeinsame Grundlinie im
-PDF. Bis dahin wird eine Beschlussempfehlung erkannt und mit Begründung
-übergangen — samt Hinweis auf die Drucksachennummer des Entwurfs, der
-sich stattdessen eignet. Eine halb aufgelöste Fassung auszugeben wäre
-schlimmer als keine.
+Die rechte Spalte für sich gelesen ist allerdings kein vollständiges
+Dokument: Sie druckt Unverändertes nicht ab, sondern vermerkt bloß
+„unverändert“ — und zwar nicht nur je Gliederungspunkt, sondern auch
+zeilenweise innerhalb zitierter Blöcke, weshalb ihre Anführungszeichen
+nicht aufgehen. Eine Auflösung über die Gliederungspfade scheitert daran
+nachweislich. Maßgeblich ist stattdessen die *Grundlinie*: Beide Spalten
+sind zeilensynchron gesetzt, jeder Vermerk steht auf der Höhe der
+Entwurfszeile, die er meint. Der `ZusammenstellungsLeser` führt beide
+Spalten über Seite und Grundlinie in eine gemeinsame Lesereihenfolge
+zusammen und entscheidet dann Zeile für Zeile: „unverändert“ holt den
+Wortlaut aus der Entwurfsspalte, „entfällt“ streicht ihn, sonst gilt die
+Ausschussspalte. Dabei meint „unverändert“ den Wortlaut, nicht die
+Zählung — streicht der Ausschuss einen Punkt, rücken die folgenden auf,
+und seine Marke tritt an die Stelle der des Entwurfs.
+
+Die Quellenzeile der Synopse weist die verwendete Spalte als
+`[Beschlussempfehlung …, Ausschussfassung]` aus. Lässt sich die
+Zusammenstellung nicht auflösen, wird die Datei nach wie vor mit
+Begründung übergangen — samt Hinweis auf die Drucksachennummer des
+Entwurfs, der sich stattdessen eignet. Eine halb aufgelöste Fassung
+auszugeben wäre schlimmer als keine.
+
+Belegt ist beides: dass die *linke* Spalte Befehl für Befehl den
+Regierungsentwurf ergibt, aus dem die Zusammenstellung gebaut ist, und
+dass die aufgelöste Fassung mehr Befehle trägt als er — der Ausschuss
+hat der GEG-Novelle zwei Artikel hinzugefügt. Zwei Beispiele stehen im
+Test: BT-Drs. 20/7619 (GEG) und BT-Drs. 19/24334 (Drittes
+Bevölkerungsschutzgesetz).
 
 [[web]]
 == Web-App
diff --git a/src/main/java/eu/mulk/aendggner/Pipeline.java b/src/main/java/eu/mulk/aendggner/Pipeline.java
index 2427c4e..4b2b7d9 100644
--- a/src/main/java/eu/mulk/aendggner/Pipeline.java
+++ b/src/main/java/eu/mulk/aendggner/Pipeline.java
@@ -19,6 +19,7 @@
 import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.List;
+import org.jspecify.annotations.Nullable;
 
 /**
  * Kernpipeline: Stammgesetz laden → Änderungsgesetze parsen und anwenden → Synopse rendern.
@@ -47,16 +48,31 @@
    * @param eingearbeitet die Dokumente, die vor der Anwendung in {@code text} eingearbeitet wurden
    *     — bei einem Entwurf die Änderungsanträge, die ihn geändert haben. Sie gehen in die
    *     Quellenzeile ein, denn die gezeigte Fassung ist ohne sie nicht nachvollziehbar.
+   * @param fassung welche von mehreren Fassungen des Dokuments gilt, sofern es mehrere trägt — die
+   *     Beschlussempfehlung stellt Entwurf und Ausschussfassung nebeneinander. Sonst {@code null}.
    */
-  record Quelldokument(Quelle quelle, DokumentKopf kopf, String text, List<String> eingearbeitet) {
+  record Quelldokument(
+      Quelle quelle,
+      DokumentKopf kopf,
+      String text,
+      List<String> eingearbeitet,
+      @Nullable String fassung) {
 
     Quelldokument(Quelle quelle, DokumentKopf kopf, String text) {
-      this(quelle, kopf, text, List.of());
+      this(quelle, kopf, text, List.of(), null);
+    }
+
+    Quelldokument(Quelle quelle, DokumentKopf kopf, String text, List<String> eingearbeitet) {
+      this(quelle, kopf, text, eingearbeitet, null);
     }
 
     String quellenAngabe(List<String> artikel) {
       var sb = new StringBuilder(quelle.name());
-      sb.append(" [").append(kopf.anzeigeName()).append("]");
+      sb.append(" [").append(kopf.anzeigeName());
+      if (fassung != null) {
+        sb.append(", ").append(fassung);
+      }
+      sb.append("]");
       for (var zusatz : eingearbeitet) {
         sb.append(" + ").append(zusatz);
       }
@@ -139,20 +155,30 @@
         continue;
       }
       if (kopf.art() == DokumentArt.BESCHLUSSEMPFEHLUNG) {
-        // Die beschlossene Fassung steht in der zweispaltigen Zusammenstellung, deren rechte
-        // Spalte für sich unvollständig ist („unverändert“ statt des Wortlauts, Zitate, die nicht
-        // aufgehen). Sie aufzulösen verlangt die zeilenweise Zuordnung beider Spalten und ist noch
-        // nicht umgesetzt; eine halb aufgelöste Fassung auszugeben wäre schlimmer als keine.
-        warnungen.add(
-            ("%s ist eine Beschlussempfehlung. Ihre maßgebliche Fassung steht in der zweispaltigen"
-                    + " Zusammenstellung, deren Auflösung noch nicht umgesetzt ist; die Datei wurde"
-                    + " übergangen. Für eine Synopse eignet sich der zugrunde liegende"
-                    + " Gesetzentwurf%s.")
-                .formatted(
-                    datei.name(),
-                    kopf.bezugsDrucksachen().isEmpty()
-                        ? ""
-                        : " (Drs. " + kopf.bezugsDrucksachen().get(0) + ")"));
+        // Die maßgebliche Fassung steht nicht im Fließtext, sondern in der zweispaltigen
+        // Zusammenstellung: links der Entwurf, rechts die Beschlüsse des Ausschusses.
+        var fassung = extraktor.leseZusammenstellung(datei);
+        warnungen.addAll(fassung.warnungen());
+        if (fassung.text() == null) {
+          // Eine halb aufgelöste Fassung auszugeben wäre schlimmer als keine.
+          warnungen.add(
+              ("%s ist eine Beschlussempfehlung, deren Zusammenstellung sich nicht auflösen ließ;"
+                      + " die Datei wurde übergangen. Für eine Synopse eignet sich der zugrunde"
+                      + " liegende Gesetzentwurf%s.")
+                  .formatted(
+                      datei.name(),
+                      kopf.bezugsDrucksachen().isEmpty()
+                          ? ""
+                          : " (Drs. " + kopf.bezugsDrucksachen().get(0) + ")"));
+          continue;
+        }
+        dokumente.add(
+            new Quelldokument(
+                datei,
+                kopf,
+                TextBereiniger.bereinige(fassung.text()),
+                List.of(),
+                "Ausschussfassung"));
         continue;
       }
       dokumente.add(new Quelldokument(datei, kopf, TextBereiniger.bereinige(rohText)));
@@ -208,7 +234,12 @@
       eingearbeitet.add(antrag.quelle().name() + " [" + antrag.kopf().anzeigeName() + "]");
       ergebnis.set(
           zielIndex,
-          new Quelldokument(ziel.quelle(), ziel.kopf(), patch.text(), List.copyOf(eingearbeitet)));
+          new Quelldokument(
+              ziel.quelle(),
+              ziel.kopf(),
+              patch.text(),
+              List.copyOf(eingearbeitet),
+              ziel.fassung()));
     }
     return ergebnis;
   }
diff --git a/src/main/java/eu/mulk/aendggner/aenderung/parse/FontgroessenFilter.java b/src/main/java/eu/mulk/aendggner/aenderung/parse/FontgroessenFilter.java
index 3ad0b84..1a9c717 100644
--- a/src/main/java/eu/mulk/aendggner/aenderung/parse/FontgroessenFilter.java
+++ b/src/main/java/eu/mulk/aendggner/aenderung/parse/FontgroessenFilter.java
@@ -3,7 +3,6 @@
 import java.io.IOException;
 import java.io.StringWriter;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -55,14 +54,18 @@
   private static final double KANDIDATEN_SCHWELLE = 0.25;
 
   /**
-   * Interne End-X-Metadaten am Zeilenende („␂527␂“), von {@link #klassifiziereZeilenenden}
-   * konsumiert; verlässt diese Klasse nie.
+   * Interne Zeilenmetadaten am Zeilenende („␂22,7315,527“ = Seite, Grundlinie ×10, End-X), von
+   * {@link #zerlege} eingelesen; als Text verlassen sie diese Klasse nie.
+   *
+   * <p>Die Metadaten reisen im Textstrom mit, statt nebenher gesammelt zu werden: Nur so ist ihre
+   * Zuordnung zu den Zeilen gesichert. PDFBox schreibt Zeilentrenner an mehreren Stellen
+   * (Zeilenende, Seitenende), und eine parallel geführte Liste geriete dort aus dem Tritt.
    */
-  private static final char ENDX_MARKE = '\uE002';
+  private static final char ZEILEN_MARKE = '\uE002';
 
-  /** Verirrte End-X-Metadaten mitten in einer Zeile (siehe {@link #klassifiziereZeilenenden}). */
-  private static final java.util.regex.Pattern ENDX_REST =
-      java.util.regex.Pattern.compile("\uE002\\d*\uE002?");
+  /** Verirrte Zeilenmetadaten mitten in einer Zeile (siehe {@link #zerlege}). */
+  private static final java.util.regex.Pattern MARKEN_REST =
+      java.util.regex.Pattern.compile("\uE002[\\d,]*\uE002?");
 
   /**
    * Fensterhälfte (Zeilen davor/danach) für die lokale Suche nach Ausrichtungs-Clustern. Lokal
@@ -94,10 +97,15 @@
   private static final int MIN_RANDZEILEN = 5;
 
   /**
-   * Mindestbreite (pt) des Stegs zwischen zwei Spalten. Ein Wortzwischenraum misst 2–4 pt, der Steg
-   * einer Zusammenstellung ein Vielfaches davon; dazwischen liegt viel Luft.
+   * Mindestbreite (pt) des Stegs zwischen zwei Spalten, an den Rändern der <em>sichtbaren</em>
+   * Zeichen gemessen (siehe {@link GroessenFilterStripper#aufSpalte}).
+   *
+   * <p>Ausgezählt an den beiden Zusammenstellungen der Beispieldaten: Der schmalste echte Steg
+   * misst dort 6,9 pt (BT-Drs. 20/7619 und 19/24334 übereinstimmend), der breiteste
+   * Wortzwischenraum einer ganzseitenbreiten Zeile über der Blattmitte 5,4 pt. Dazwischen liegt die
+   * Schwelle. Sie war früher 12 pt und trennte damit gerade die engsten Stege nicht mehr.
    */
-  private static final float RINNE_MIN_PT = 12f;
+  private static final float RINNE_MIN_PT = 6f;
 
   private FontgroessenFilter() {}
 
@@ -124,6 +132,28 @@
 
   static String extrahiere(PDDocument dokument, SuperskriptModus superskriptModus, Spalte spalte)
       throws IOException {
+    return klassifiziereZeilenenden(extrahiereZeilen(dokument, superskriptModus, spalte));
+  }
+
+  /**
+   * Eine Ausgabezeile samt ihrer Herkunft im Satzbild.
+   *
+   * <p>Sonst verlässt keine Koordinate diese Klasse. Die Zusammenstellung einer Beschlussempfehlung
+   * braucht sie: Ihre beiden Spalten stehen im Inhaltsstrom verschränkt und lassen sich nur über
+   * Seite und Grundlinie in eine gemeinsame Lesereihenfolge bringen.
+   *
+   * @param seite 1-basierte Seitennummer.
+   * @param grundlinie Grundlinie (pt von oben); {@link Float#NaN}, wenn unbekannt.
+   * @param endX rechtes Ende der Zeile (pt); {@link Float#NaN}, wenn unbekannt.
+   */
+  record Zeile(int seite, float grundlinie, float endX, String text) {}
+
+  /**
+   * Die Zeilen des Dokuments mit ihrer Geometrie. Hat keine Seite eine dominante Brotschrift,
+   * bleibt das Dokument ungefiltert und die Zeilen tragen keine Geometrie.
+   */
+  static List<Zeile> extrahiereZeilen(
+      PDDocument dokument, SuperskriptModus superskriptModus, Spalte spalte) throws IOException {
     var zaehler = new GroessenZaehler();
     zaehler.setLineSeparator("\n");
     var wegwerf = new StringWriter();
@@ -132,7 +162,7 @@
     var schwellen = zaehler.schwellenProSeite();
     if (schwellen.isEmpty()) {
       log.debugf("Keine dominanten Fontgrößen; Kleingedrucktes wird nicht gefiltert.");
-      return wegwerf.toString();
+      return zerlege(wegwerf.toString());
     }
     log.debugf("Brotschriftgrößen (je Seite): %s", schwellen);
 
@@ -142,54 +172,85 @@
     filter.setLineSeparator("\n");
     var ausgabe = new StringWriter();
     filter.writeText(dokument, ausgabe);
-    return klassifiziereZeilenenden(ausgabe.toString());
+    return zerlege(ausgabe.toString());
+  }
+
+  /** Trennt die {@link #ZEILEN_MARKE}-Metadaten wieder vom Text ab. */
+  private static List<Zeile> zerlege(String text) {
+    var roh = text.split("\n", -1);
+    var zeilen = new ArrayList<Zeile>(roh.length);
+    for (var zeile : roh) {
+      int seite = 0;
+      float grundlinie = Float.NaN;
+      float endX = Float.NaN;
+      if (!zeile.isEmpty() && zeile.charAt(zeile.length() - 1) == ZEILEN_MARKE) {
+        int start = zeile.lastIndexOf(ZEILEN_MARKE, zeile.length() - 2);
+        if (start >= 0) {
+          var felder = zeile.substring(start + 1, zeile.length() - 1).split(",");
+          try {
+            seite = Integer.parseInt(felder[0]);
+            grundlinie = Integer.parseInt(felder[1]) / 10f;
+            endX = Integer.parseInt(felder[2]);
+            zeile = zeile.substring(0, start);
+          } catch (NumberFormatException | ArrayIndexOutOfBoundsException e) {
+            seite = 0;
+            grundlinie = Float.NaN;
+            endX = Float.NaN;
+          }
+        }
+      }
+      // Verirrte Metadaten mitten in der Zeile (Seitenwechsel ohne Zeilentrenner) sind wertlos.
+      if (zeile.indexOf(ZEILEN_MARKE) >= 0) {
+        zeile = MARKEN_REST.matcher(zeile).replaceAll("");
+      }
+      zeilen.add(new Zeile(seite, grundlinie, endX, zeile));
+    }
+    return zeilen;
   }
 
   /**
-   * Ersetzt die End-X-Metadaten der Zeilen durch die Umbruch-Klassifikation: Zeilen, die an einem
-   * lokalen Satzspiegelrand enden (Ausrichtungs-Cluster aus mindestens {@link #MIN_RANDZEILEN}
-   * gleich endenden Fensterzeilen), erhalten {@link TextBereiniger#WEICHES_ZEILENENDE}; Zeilen, die
-   * deutlich vor einem solchen Rand enden, {@link TextBereiniger#HARTES_ZEILENENDE}; alles andere
-   * bleibt unmarkiert. Cluster statt Perzentil, weil ein Fenster am Spaltenwechsel des
-   * zweispaltigen alten BGBl beide Spaltenränder enthält — maßgeblich ist der Rand, an dem die
-   * Zeile selbst ausgerichtet ist bzw. der nächste oberhalb ihres Endes.
+   * Hängt an jede Zeile die Umbruch-Klassifikation: Zeilen, die an einem lokalen Satzspiegelrand
+   * enden (Ausrichtungs-Cluster aus mindestens {@link #MIN_RANDZEILEN} gleich endenden
+   * Fensterzeilen), erhalten {@link TextBereiniger#WEICHES_ZEILENENDE}; Zeilen, die deutlich vor
+   * einem solchen Rand enden, {@link TextBereiniger#HARTES_ZEILENENDE}; alles andere bleibt
+   * unmarkiert. Cluster statt Perzentil, weil ein Fenster am Spaltenwechsel des zweispaltigen alten
+   * BGBl beide Spaltenränder enthält — maßgeblich ist der Rand, an dem die Zeile selbst
+   * ausgerichtet ist bzw. der nächste oberhalb ihres Endes.
    */
-  private static String klassifiziereZeilenenden(String text) {
-    var zeilen = text.split("\n", -1);
-    var endX = new float[zeilen.length];
-    Arrays.fill(endX, Float.NaN);
-    for (int i = 0; i < zeilen.length; i++) {
-      var zeile = zeilen[i];
-      if (zeile.isEmpty() || zeile.charAt(zeile.length() - 1) != ENDX_MARKE) {
-        continue;
+  static String klassifiziereZeilenenden(List<Zeile> zeilen) {
+    var markiert = markiereZeilenenden(zeilen);
+    var sb = new StringBuilder();
+    for (int i = 0; i < markiert.size(); i++) {
+      if (i > 0) {
+        sb.append('\n');
       }
-      int start = zeile.lastIndexOf(ENDX_MARKE, zeile.length() - 2);
-      if (start < 0) {
-        continue;
-      }
-      try {
-        endX[i] = Integer.parseInt(zeile, start + 1, zeile.length() - 1, 10);
-      } catch (NumberFormatException e) {
-        continue;
-      }
-      zeilen[i] = zeile.substring(0, start);
+      sb.append(markiert.get(i).text());
+    }
+    return sb.toString();
+  }
+
+  /**
+   * Wie {@link #klassifiziereZeilenenden}, aber zeilenweise. Die Zusammenstellung braucht das: Ihre
+   * beiden Spalten haben verschiedene Satzspiegelränder und müssen deshalb <em>vor</em> dem
+   * Zusammenführen klassifiziert werden — in der gemischten Fassung fände keine Spalte mehr ihren
+   * eigenen Rand wieder, und die Silbentrennung bliebe ungeheilt („An- gabe“).
+   */
+  static List<Zeile> markiereZeilenenden(List<Zeile> zeilen) {
+    var text = new String[zeilen.size()];
+    var endX = new float[zeilen.size()];
+    for (int i = 0; i < zeilen.size(); i++) {
+      text[i] = zeilen.get(i).text();
+      endX[i] = zeilen.get(i).endX();
     }
 
-    // Verirrte Metadaten mitten in der Zeile (Seitenwechsel ohne Zeilentrenner) sind wertlos.
-    for (int i = 0; i < zeilen.length; i++) {
-      if (zeilen[i].indexOf(ENDX_MARKE) >= 0) {
-        zeilen[i] = ENDX_REST.matcher(zeilen[i]).replaceAll("");
-      }
-    }
-
-    for (int i = 0; i < zeilen.length; i++) {
+    for (int i = 0; i < text.length; i++) {
       float x = endX[i];
       if (Float.isNaN(x)) {
         continue;
       }
       var fenster = new ArrayList<Float>();
       for (int j = Math.max(0, i - RAND_FENSTER);
-          j < Math.min(zeilen.length, i + RAND_FENSTER + 1);
+          j < Math.min(text.length, i + RAND_FENSTER + 1);
           j++) {
         if (!Float.isNaN(endX[j])) {
           fenster.add(endX[j]);
@@ -197,19 +258,24 @@
       }
       if (istCluster(fenster, x)) {
         // Die Zeile endet an einem Satzspiegelrand → automatischer Blocksatz-Umbruch.
-        zeilen[i] = zeilen[i] + TextBereiniger.WEICHES_ZEILENENDE;
+        text[i] = text[i] + TextBereiniger.WEICHES_ZEILENENDE;
         continue;
       }
       // Gibt es deutlich oberhalb des Zeilenendes einen Satzspiegelrand, wäre dort noch Platz
       // gewesen → das Zeilenende ist bewusst gesetzt.
       for (float v : fenster) {
         if (v >= x + HART_ABSTAND_PT && istCluster(fenster, v)) {
-          zeilen[i] = zeilen[i] + TextBereiniger.HARTES_ZEILENENDE;
+          text[i] = text[i] + TextBereiniger.HARTES_ZEILENENDE;
           break;
         }
       }
     }
-    return String.join("\n", zeilen);
+    var ergebnis = new ArrayList<Zeile>(zeilen.size());
+    for (int i = 0; i < zeilen.size(); i++) {
+      var zeile = zeilen.get(i);
+      ergebnis.add(new Zeile(zeile.seite(), zeile.grundlinie(), zeile.endX(), text[i]));
+    }
+    return ergebnis;
   }
 
   /**
@@ -365,6 +431,12 @@
     /** End-X (pt) des breitesten behaltenen Laufs der laufenden Zeile; NaN vor dem ersten. */
     private float zeilenEndX = Float.NaN;
 
+    /** Grundlinie (pt von oben) der laufenden Zeile: die tiefste ihrer behaltenen Läufe. */
+    private float zeilenGrundlinie = Float.NaN;
+
+    /** Seite, auf der die laufende Zeile steht. */
+    private int zeilenSeite = 0;
+
     GroessenFilterStripper(
         Map<Integer, Float> schwellen,
         Map<Integer, Float> untergrenzen,
@@ -383,9 +455,16 @@
      * zusammenfasst: Die einander gegenüberstehenden Überschriften beider Spalten („Artikel 1“ und
      * „Artikel 1“) kämen sonst gemeinsam in einer Spalte an.
      *
+     * <p>Gemessen wird ausschließlich an den <em>sichtbaren</em> Zeichen. Der Zwischenraum zweier
+     * Spalten trägt im Textstrom regelmäßig noch Leerzeichen, die fast bis an die nächste Spalte
+     * reichen; nach ihren Rändern gemessen schrumpft ein 7-pt-Steg auf 4,7 pt und wurde für
+     * durchlaufenden Text gehalten. In BT-Drs. 20/7619 riss das die gesperrte Marke des Punktes 14
+     * mitten entzwei („… wird wie folgt gefasst: 14. u“ links, „n v e r ä n d e r t“ rechts).
+     *
      * @return die Zeichen der Spalte, oder {@code null}, wenn der Lauf ganz außerhalb liegt.
      */
-    private List<TextPosition> aufSpalte(List<TextPosition> positionen) {
+    private @org.jspecify.annotations.Nullable List<TextPosition> aufSpalte(
+        List<TextPosition> positionen) {
       if (spalte == Spalte.GANZ || positionen.isEmpty()) {
         return positionen;
       }
@@ -393,28 +472,40 @@
       if (seite == null) {
         return positionen;
       }
+      if (positionen.get(0).getDir() != 0) {
+        // Gedrehter Text gehört keiner Spalte an — er steht quer am Blattrand. Der Randvermerk
+        // „Vorabfassung – wird durch die lektorierte Fassung ersetzt“ der Bundestagsdrucksachen
+        // steht so, mit Koordinaten in seinem eigenen, gedrehten Bezugssystem: Seine Grundlinie
+        // liefe quer durch beide Spalten und zerschnitte deren Zeilenfolge. Beim ungeteilten
+        // Auszug bleibt er erhalten und wird wie bisher vom TextBereiniger entfernt.
+        return null;
+      }
       float mitte = seite.getMediaBox().getWidth() / 2;
 
-      // Wo überschreitet der Lauf die Blattmitte?
-      int uebergang = -1;
-      for (int i = 0; i < positionen.size() - 1; i++) {
-        if (zeichenMitte(positionen.get(i)) < mitte
-            && zeichenMitte(positionen.get(i + 1)) >= mitte) {
-          uebergang = i;
+      // Das erste sichtbare Zeichen jenseits der Blattmitte und das letzte diesseits.
+      int erstesRechts = -1;
+      int letztesLinks = -1;
+      for (int i = 0; i < positionen.size(); i++) {
+        var position = positionen.get(i);
+        if (position.getUnicode().isBlank()) {
+          continue;
+        }
+        if (zeichenMitte(position) < mitte) {
+          letztesLinks = i;
+        } else {
+          erstesRechts = i;
           break;
         }
       }
 
-      if (uebergang < 0) {
+      if (erstesRechts < 0 || letztesLinks < 0) {
         // Der Lauf liegt ganz auf einer Seite der Mitte.
-        boolean links = zeichenMitte(positionen.get(0)) < mitte;
-        return links == (spalte == Spalte.LINKS) ? positionen : null;
+        return (erstesRechts < 0) == (spalte == Spalte.LINKS) ? positionen : null;
       }
 
-      var davor = positionen.get(uebergang);
+      var davor = positionen.get(letztesLinks);
       float luecke =
-          positionen.get(uebergang + 1).getXDirAdj()
-              - (davor.getXDirAdj() + davor.getWidthDirAdj());
+          positionen.get(erstesRechts).getXDirAdj() - (davor.getXDirAdj() + davor.getWidthDirAdj());
       if (luecke < RINNE_MIN_PT) {
         // Kein Spaltensteg, sondern durchlaufender Text über die Blattmitte hinweg: eine
         // ganzseitenbreite Zeile (Vorblatt, Bericht, Seitenkopf). Sie gehört keiner Spalte an und
@@ -422,9 +513,10 @@
         // zweimal.
         return spalte == Spalte.LINKS ? positionen : null;
       }
+      // Die Leerzeichen des Stegs bleiben bei der linken Spalte; der Bereiniger stutzt sie.
       return spalte == Spalte.LINKS
-          ? positionen.subList(0, uebergang + 1)
-          : positionen.subList(uebergang + 1, positionen.size());
+          ? positionen.subList(0, erstesRechts)
+          : positionen.subList(erstesRechts, positionen.size());
     }
 
     private static float zeichenMitte(TextPosition position) {
@@ -462,7 +554,12 @@
       for (var position : positionen) {
         float endX = position.getXDirAdj() + position.getWidthDirAdj();
         zeilenEndX = Float.isNaN(zeilenEndX) ? endX : Math.max(zeilenEndX, endX);
+        // Grundlinie = tiefstes Y des Laufs, wie schon in mitSuperskripten: Hochgestelltes sitzt
+        // höher und darf die Zeile nicht nach oben ziehen.
+        float y = position.getYDirAdj();
+        zeilenGrundlinie = Float.isNaN(zeilenGrundlinie) ? y : Math.max(zeilenGrundlinie, y);
       }
+      zeilenSeite = getCurrentPageNo();
       super.writeString(text, positionen);
     }
 
@@ -536,30 +633,35 @@
       return true;
     }
 
-    /**
-     * Schreibt vor jedem Zeilentrenner das End-X der Zeile als Metadaten für {@link
-     * #klassifiziereZeilenenden}.
-     */
+    /** Schreibt vor jedem Zeilentrenner die Geometrie der Zeile als Metadaten. */
     @Override
     protected void writeLineSeparator() throws IOException {
-      schreibeEndXMarke();
+      schreibeZeilenMarke();
       super.writeLineSeparator();
     }
 
     /**
-     * Die letzte Zeile einer Seite endet ohne Zeilentrenner — ohne Flush würde ihr End-X erst an
-     * der ersten Zeile der Folgeseite landen und diese falsch klassifizieren.
+     * Die letzte Zeile einer Seite endet ohne Zeilentrenner — ohne Flush würde ihre Geometrie erst
+     * an der ersten Zeile der Folgeseite landen und diese falsch beschreiben.
      */
     @Override
     protected void writePageEnd() throws IOException {
-      schreibeEndXMarke();
+      schreibeZeilenMarke();
       super.writePageEnd();
     }
 
-    private void schreibeEndXMarke() throws IOException {
+    private void schreibeZeilenMarke() throws IOException {
       if (!Float.isNaN(zeilenEndX)) {
-        writeString(ENDX_MARKE + Integer.toString(Math.round(zeilenEndX)) + ENDX_MARKE);
+        writeString(
+            "%c%d,%d,%d%c"
+                .formatted(
+                    ZEILEN_MARKE,
+                    zeilenSeite,
+                    Math.round(zeilenGrundlinie * 10),
+                    Math.round(zeilenEndX),
+                    ZEILEN_MARKE));
         zeilenEndX = Float.NaN;
+        zeilenGrundlinie = Float.NaN;
       }
     }
 
diff --git a/src/main/java/eu/mulk/aendggner/aenderung/parse/PatchTextExtraktor.java b/src/main/java/eu/mulk/aendggner/aenderung/parse/PatchTextExtraktor.java
index e756126..daa72c5 100644
--- a/src/main/java/eu/mulk/aendggner/aenderung/parse/PatchTextExtraktor.java
+++ b/src/main/java/eu/mulk/aendggner/aenderung/parse/PatchTextExtraktor.java
@@ -5,8 +5,10 @@
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Path;
+import java.util.List;
 import org.apache.pdfbox.Loader;
 import org.jboss.logging.Logger;
+import org.jspecify.annotations.Nullable;
 
 /**
  * Extrahiert den linearen Text eines Änderungsgesetzes aus einer Eingabedatei.
@@ -79,4 +81,28 @@
   }
 
   public record Spalten(String links, String rechts) {}
+
+  /**
+   * Gewinnt aus der Zusammenstellung einer Beschlussempfehlung die vom Ausschuss beschlossene
+   * Fassung; siehe {@link ZusammenstellungsLeser}.
+   *
+   * @param text die beschlossene Fassung, oder {@code null}, wenn sie sich nicht gewinnen ließ —
+   *     dann nennt {@code warnungen} den Grund.
+   */
+  public record Ausschussfassung(@Nullable String text, List<String> warnungen) {}
+
+  public Ausschussfassung leseZusammenstellung(Quelle quelle) throws IOException {
+    if (DateiTyp.erkenne(quelle.inhalt()) != DateiTyp.PDF) {
+      return new Ausschussfassung(
+          null,
+          List.of(
+              "%s ist keine PDF-Datei; die Spalten einer Zusammenstellung lassen sich nur über die"
+                      .formatted(quelle.name())
+                  + " Koordinaten des Satzbildes trennen."));
+    }
+    try (var dokument = Loader.loadPDF(quelle.inhalt())) {
+      var ergebnis = ZusammenstellungsLeser.lies(dokument, superskriptModus);
+      return new Ausschussfassung(ergebnis.text(), ergebnis.warnungen());
+    }
+  }
 }
diff --git a/src/main/java/eu/mulk/aendggner/aenderung/parse/TextBereiniger.java b/src/main/java/eu/mulk/aendggner/aenderung/parse/TextBereiniger.java
index 1e6c39a..30cefdf 100644
--- a/src/main/java/eu/mulk/aendggner/aenderung/parse/TextBereiniger.java
+++ b/src/main/java/eu/mulk/aendggner/aenderung/parse/TextBereiniger.java
@@ -76,11 +76,6 @@
               + gesperrt(" ersetzt."));
 
   /**
-   * In der Zusammenstellung einer Beschlussempfehlung steht der Vermerk der Ausschussspalte
-   * gesperrt: „u n v e r ä n d e r t“. Er ist kein Fließtext, sondern eine Marke, und wird auf ihre
-   * Normalform gebracht, bevor irgendetwas anderes ihn zu lesen versucht.
-   */
-  /**
    * Der laufende Spaltenkopf der Zusammenstellung („Entwurf“ links, „Beschlüsse des 25.
    * Ausschusses“ rechts) wiederholt sich auf jeder Seite und steht damit mitten in den Befehlen.
    * Erfasst wird auch die ungetrennte Form, die entsteht, solange die Spalten noch nicht getrennt
@@ -90,10 +85,23 @@
       Pattern.compile(
           "\\s*(?:Entwurf\\s*)?(?:Beschlüsse\\s+des\\s+\\d+\\.\\s+Ausschusses)\\s*|\\s*Entwurf\\s*");
 
+  /**
+   * In der Zusammenstellung einer Beschlussempfehlung steht der Vermerk der Ausschussspalte
+   * gesperrt: „u n v e r ä n d e r t“. Er ist kein Fließtext, sondern eine Marke, und wird auf ihre
+   * Normalform gebracht, bevor irgendetwas anderes ihn zu lesen versucht.
+   */
   private static final Pattern UNVERAENDERT_GESPERRT =
       Pattern.compile("u\\s+n\\s+v\\s+e\\s+r\\s+ä\\s+n\\s+d\\s+e\\s+r\\s+t");
 
   /**
+   * Bringt den gesperrten Vermerk auf seine Normalform. Der {@link ZusammenstellungsLeser} braucht
+   * ihn früher als der übrige Bereiniger: Er entscheidet zeilenweise über die maßgebliche Spalte.
+   */
+  static String entsperreUnveraendert(String zeile) {
+    return UNVERAENDERT_GESPERRT.matcher(zeile).replaceAll("unverändert");
+  }
+
+  /**
    * Whitespace einschließlich der Umbruch-Marker des FontgroessenFilters — die kurzen Zeilen des
    * senkrechten Wasserzeichens tragen sie an jedem Zeilenende.
    */
@@ -415,7 +423,13 @@
     return ergebnis;
   }
 
-  private static boolean istKolumnentitel(String zeile) {
+  /**
+   * Ist die Zeile Seitenmöbel (Kopf-/Fußzeile, Spaltenkopf)? Auch der {@link
+   * ZusammenstellungsLeser} fragt danach: Er muss das Möbel loswerden, <em>bevor</em> er die
+   * Spalten zusammenführt — ein Spaltenkopf mitten in einem unveränderten Block würde ihm sonst
+   * einen Wechsel der maßgeblichen Spalte vortäuschen.
+   */
+  static boolean istKolumnentitel(String zeile) {
     return KOPFZEILE.matcher(zeile).matches()
         || SEITENZAHL.matcher(zeile).matches()
         || BUNDESANZEIGER.matcher(zeile).matches()
diff --git a/src/main/java/eu/mulk/aendggner/aenderung/parse/ZusammenstellungsLeser.java b/src/main/java/eu/mulk/aendggner/aenderung/parse/ZusammenstellungsLeser.java
new file mode 100644
index 0000000..69084bc
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/aenderung/parse/ZusammenstellungsLeser.java
@@ -0,0 +1,278 @@
+package eu.mulk.aendggner.aenderung.parse;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.regex.Pattern;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.jboss.logging.Logger;
+import org.jspecify.annotations.Nullable;
+
+/**
+ * Gewinnt aus der Zusammenstellung einer Beschlussempfehlung die vom Ausschuss beschlossene
+ * Fassung.
+ *
+ * <p>Die Zusammenstellung steht zweispaltig: links der Entwurf, rechts die Beschlüsse des
+ * Ausschusses. Die rechte Spalte schreibt aber nur aus, was der Ausschuss <em>geändert</em> hat;
+ * überall sonst steht die gesperrte Marke „u n v e r ä n d e r t“ — und zwar nicht nur je
+ * Gliederungspunkt, sondern auch zeilenweise innerhalb zitierter Blöcke:
+ *
+ * <pre>
+ * links                                  rechts
+ * 13. Die Angaben zu den §§ 34 bis 45 …   13. Die §§ 34 bis 45 werden wie folgt gefasst:
+ * „§ 34 (weggefallen)                     „§ 34 u n v e r ä n d e r t
+ * § 35 (weggefallen)                      § 35 u n v e r ä n d e r t
+ * § 45 (weggefallen)“.                    § 45 u n v e r ä n d e r t
+ * </pre>
+ *
+ * <p>Für sich gelesen ist die rechte Spalte deshalb unbrauchbar: Ihre Anführungszeichen gehen nicht
+ * auf. Maßgeblich ist die <em>Grundlinie</em>: Beide Spalten sind zeilensynchron gesetzt, jeder
+ * Vermerk steht auf der Höhe der Entwurfszeile, die er meint. Über Seite und Grundlinie (aus {@link
+ * FontgroessenFilter.Zeile}) lässt sich die Fassung deshalb Zeile für Zeile zusammensetzen: Wo die
+ * rechte Spalte „unverändert“ vermerkt, gilt die linke, sonst die rechte.
+ *
+ * <p>Ein früherer Versuch, das über die Gliederungspfade statt über die Geometrie zu lösen, ist
+ * gescheitert (45 statt 117 Befehlen), weil er die zeilenweisen Vermerke innerhalb der Zitate nicht
+ * auflösen kann.
+ */
+final class ZusammenstellungsLeser {
+
+  private static final Logger log = Logger.getLogger(ZusammenstellungsLeser.class);
+
+  /**
+   * Die Umbruch-Klassifikation, die {@link FontgroessenFilter#markiereZeilenenden} ans Zeilenende
+   * hängt. Sie gehört in die ausgegebene Fassung, aber in keine Textprüfung.
+   */
+  private static final Pattern ZEILENENDE =
+      Pattern.compile(
+          "[" + TextBereiniger.HARTES_ZEILENENDE + TextBereiniger.WEICHES_ZEILENENDE + "]");
+
+  /** Der Zeileninhalt ohne die Umbruch-Klassifikation. */
+  private static String nurText(String zeile) {
+    return ZEILENENDE.matcher(zeile).replaceAll("");
+  }
+
+  /**
+   * Die Zusammenstellung beginnt unter dieser Überschrift. Davor stehen Beschlussformel und
+   * Ausschussbesetzung, danach der Bericht der Berichterstatter — beides Fließtext ohne Befehle,
+   * beides einspaltig und deshalb ohnehin nicht auflösbar.
+   */
+  private static final Pattern BEGINN = Pattern.compile("\\s*Zusammenstellung\\s*");
+
+  private static final Pattern ENDE = Pattern.compile("\\s*Bericht (?:des|der) Abgeordneten.*");
+
+  /**
+   * Die Marke eines Gliederungspunkts, wie sie beide Spalten an den Zeilenanfang setzen: „13.“,
+   * „b)“, „aa)“, „(2)“, „§ 34“, „Artikel 2“, „Teil 3“ — in Zitaten samt öffnendem
+   * Anführungszeichen.
+   */
+  private static final String MARKE =
+      "„?(?:\\d+[a-z]?\\.|[a-z]{1,3}\\)|\\(\\d+[a-z]?\\)|§+\\s*\\d+[a-z]?"
+          + "|Artikel\\s+\\d+[a-z]?|Teil\\s+\\d+)";
+
+  /**
+   * Der Vermerk, dass der Ausschuss der Entwurfsfassung folgt — für sich allein oder hinter der
+   * Marke des gemeinten Punktes.
+   */
+  private static final Pattern UNVERAENDERT =
+      Pattern.compile("\\s*(" + MARKE + "\\s+)?unverändert[\\s.]*");
+
+  /**
+   * Der Vermerk, dass der Ausschuss den Punkt streicht. Er hat kein Gegenstück in der beschlossenen
+   * Fassung: Sie schweigt an dieser Stelle, und der Entwurfstext darunter entfällt mit ihm.
+   */
+  private static final Pattern ENTFAELLT =
+      Pattern.compile("\\s*(?:" + MARKE + "\\s+)?entfällt[\\s.]*");
+
+  /** Die führende Marke einer Zeile, um sie gegen die der anderen Spalte auszutauschen. */
+  private static final Pattern FUEHRENDE_MARKE = Pattern.compile("^(\\s*)" + MARKE + "\\s+");
+
+  /** Höhenunterschied (pt), bis zu dem zwei Zeilen als auf derselben Grundlinie gelten. */
+  private static final float GRUNDLINIEN_TOLERANZ_PT = 1f;
+
+  private ZusammenstellungsLeser() {}
+
+  /**
+   * @param text die beschlossene Fassung als linearer Text, oder {@code null}, wenn sie sich nicht
+   *     gewinnen ließ — dann nennt {@code warnungen} den Grund.
+   */
+  record Ergebnis(@Nullable String text, List<String> warnungen) {}
+
+  static Ergebnis lies(PDDocument dokument, SuperskriptModus superskriptModus) throws IOException {
+    // Jede Spalte für sich klassifiziert: Ihre Satzspiegelränder liegen verschieden, in der
+    // gemischten Fassung fände keine ihren eigenen wieder.
+    var links =
+        FontgroessenFilter.markiereZeilenenden(
+            FontgroessenFilter.extrahiereZeilen(
+                dokument, superskriptModus, FontgroessenFilter.Spalte.LINKS));
+    var rechts =
+        FontgroessenFilter.markiereZeilenenden(
+            FontgroessenFilter.extrahiereZeilen(
+                dokument, superskriptModus, FontgroessenFilter.Spalte.RECHTS));
+    var warnungen = new ArrayList<String>();
+
+    var hoehen = fasseNachGrundlinieZusammen(links, rechts);
+    int beginn = findeZeile(hoehen, BEGINN);
+    if (beginn < 0) {
+      warnungen.add("Die Beschlussempfehlung enthält keine Zusammenstellung.");
+      return new Ergebnis(null, warnungen);
+    }
+    int ende = findeZeile(hoehen, ENDE);
+    if (ende < 0) {
+      ende = hoehen.size();
+    }
+
+    var fassung = loeseAuf(hoehen.subList(beginn, ende), warnungen);
+    return new Ergebnis(String.join("\n", fassung), warnungen);
+  }
+
+  /** Eine Höhe im Satzbild mit dem, was auf ihr in den beiden Spalten steht. */
+  private record Hoehe(
+      int seite,
+      float grundlinie,
+      FontgroessenFilter.@Nullable Zeile links,
+      FontgroessenFilter.@Nullable Zeile rechts) {}
+
+  /**
+   * Führt beide Spalten über Seite und Grundlinie in eine gemeinsame Lesereihenfolge zusammen.
+   * Seitenmöbel fällt dabei heraus: Der laufende Spaltenkopf („Entwurf“ / „Beschlüsse des 25.
+   * Ausschusses“) stünde sonst mitten in einem unveränderten Block und täuschte {@link #loeseAuf}
+   * einen Wechsel der maßgeblichen Spalte vor.
+   */
+  private static List<Hoehe> fasseNachGrundlinieZusammen(
+      List<FontgroessenFilter.Zeile> links, List<FontgroessenFilter.Zeile> rechts) {
+    record Kandidat(FontgroessenFilter.Zeile zeile, boolean istLinks) {}
+    var kandidaten = new ArrayList<Kandidat>(links.size() + rechts.size());
+    for (var zeile : links) {
+      if (traegtInhalt(zeile)) {
+        kandidaten.add(new Kandidat(zeile, true));
+      }
+    }
+    for (var zeile : rechts) {
+      if (traegtInhalt(zeile)) {
+        kandidaten.add(new Kandidat(zeile, false));
+      }
+    }
+    kandidaten.sort(
+        Comparator.<Kandidat>comparingInt(k -> k.zeile().seite())
+            .thenComparing(k -> k.zeile().grundlinie())
+            // Die linke Spalte zuerst, damit eine Höhe ihre beiden Seiten in fester Ordnung erhält.
+            .thenComparing(k -> !k.istLinks()));
+
+    var hoehen = new ArrayList<Hoehe>();
+    for (var kandidat : kandidaten) {
+      var zeile = kandidat.zeile();
+      var letzte = hoehen.isEmpty() ? null : hoehen.get(hoehen.size() - 1);
+      boolean gleicheHoehe =
+          letzte != null
+              && letzte.seite() == zeile.seite()
+              && Math.abs(letzte.grundlinie() - zeile.grundlinie()) <= GRUNDLINIEN_TOLERANZ_PT
+              && (kandidat.istLinks() ? letzte.links() == null : letzte.rechts() == null);
+      if (gleicheHoehe) {
+        hoehen.set(
+            hoehen.size() - 1,
+            kandidat.istLinks()
+                ? new Hoehe(letzte.seite(), letzte.grundlinie(), zeile, letzte.rechts())
+                : new Hoehe(letzte.seite(), letzte.grundlinie(), letzte.links(), zeile));
+      } else {
+        hoehen.add(
+            new Hoehe(
+                zeile.seite(),
+                zeile.grundlinie(),
+                kandidat.istLinks() ? zeile : null,
+                kandidat.istLinks() ? null : zeile));
+      }
+    }
+    return hoehen;
+  }
+
+  private static boolean traegtInhalt(FontgroessenFilter.Zeile zeile) {
+    var text = nurText(zeile.text());
+    return !text.isBlank() && !TextBereiniger.istKolumnentitel(text);
+  }
+
+  private static int findeZeile(List<Hoehe> hoehen, Pattern muster) {
+    for (int i = 0; i < hoehen.size(); i++) {
+      var links = hoehen.get(i).links();
+      if (links != null && muster.matcher(nurText(links.text())).matches()) {
+        return i;
+      }
+    }
+    return -1;
+  }
+
+  /**
+   * Setzt die beschlossene Fassung Zeile für Zeile zusammen.
+   *
+   * <p>Maßgeblich ist stets die zuletzt in der rechten Spalte vermerkte Entscheidung: Nach einem
+   * „unverändert“ gilt die linke Spalte, nach „entfällt“ oder ausgeschriebenem Text die rechte.
+   * Höhen, auf denen nur die linke Spalte steht, sind daher entweder die Fortsetzung eines
+   * unveränderten Blocks (sie gelten) oder der vom Ausschuss ersetzte Entwurfstext (er entfällt).
+   */
+  private static List<String> loeseAuf(List<Hoehe> hoehen, List<String> warnungen) {
+    var fassung = new ArrayList<String>();
+    boolean linkeSpalteGilt = true;
+    int unveraendert = 0;
+    int gestrichen = 0;
+    int uebernommen = 0;
+    for (var hoehe : hoehen) {
+      var rechts = hoehe.rechts();
+      var links = hoehe.links();
+      if (rechts == null) {
+        if (linkeSpalteGilt && links != null) {
+          fassung.add(links.text());
+        }
+        continue;
+      }
+      var vermerk = TextBereiniger.entsperreUnveraendert(nurText(rechts.text()));
+      var unveraendertMarke = UNVERAENDERT.matcher(vermerk);
+      if (unveraendertMarke.matches()) {
+        linkeSpalteGilt = true;
+        unveraendert++;
+        if (links == null) {
+          warnungen.add(
+              ("Die Zusammenstellung vermerkt auf Seite %d „unverändert“, ohne dass dort eine"
+                      + " Entwurfszeile steht; die Stelle fehlt in der beschlossenen Fassung.")
+                  .formatted(rechts.seite()));
+          continue;
+        }
+        fassung.add(mitMarkeDerAusschussspalte(links.text(), unveraendertMarke.group(1)));
+        continue;
+      }
+      linkeSpalteGilt = false;
+      if (ENTFAELLT.matcher(vermerk).matches()) {
+        // Der Ausschuss streicht den Punkt: Die beschlossene Fassung schweigt hier.
+        gestrichen++;
+        continue;
+      }
+      uebernommen++;
+      fassung.add(rechts.text());
+    }
+    log.debugf(
+        "Zusammenstellung aufgelöst: %d Zeilen aus der Ausschussspalte, %d unverändert übernommen,"
+            + " %d gestrichen.",
+        uebernommen, unveraendert, gestrichen);
+    return fassung;
+  }
+
+  /**
+   * Die Entwurfszeile unter der Marke, die der Ausschuss ihr gibt.
+   *
+   * <p>„Unverändert“ meint den <em>Wortlaut</em>, nicht die Zählung: Streicht der Ausschuss einen
+   * Punkt, rücken die folgenden auf, und seine Marke 5. steht der Nummer 6 des Entwurfs gegenüber.
+   * Maßgeblich ist deshalb die Marke der rechten, der Wortlaut der linken Spalte.
+   */
+  private static String mitMarkeDerAusschussspalte(
+      String entwurfsZeile, @Nullable String markeMitLeerraum) {
+    if (markeMitLeerraum == null) {
+      return entwurfsZeile;
+    }
+    var marke = FUEHRENDE_MARKE.matcher(entwurfsZeile);
+    if (!marke.find()) {
+      return markeMitLeerraum + entwurfsZeile;
+    }
+    // Der Einzug ist der der Entwurfszeile: Er trägt die Ebene, die Marke nur die Zählung.
+    return marke.group(1) + markeMitLeerraum + entwurfsZeile.substring(marke.end());
+  }
+}
diff --git a/src/test/java/eu/mulk/aendggner/EndToEndTest.java b/src/test/java/eu/mulk/aendggner/EndToEndTest.java
index 212e070..55579f1 100644
--- a/src/test/java/eu/mulk/aendggner/EndToEndTest.java
+++ b/src/test/java/eu/mulk/aendggner/EndToEndTest.java
@@ -1024,20 +1024,54 @@
   }
 
   /**
-   * Eine Beschlussempfehlung wird als solche erkannt und mit Begründung übergangen, statt eine halb
-   * aufgelöste Fassung auszugeben. Die Meldung nennt den Entwurf, der stattdessen taugt.
+   * Aus einer Beschlussempfehlung entsteht die Synopse der <em>beschlossenen</em> Fassung: Die
+   * Pipeline löst die zweispaltige Zusammenstellung auf, statt die Datei zu übergehen.
+   *
+   * <p>Gepinnt ist die Zahl der angewandten Befehle. Der große Rest bleibt aus demselben Grund
+   * manuell wie beim Regierungsentwurf daneben (BT-Drs. 20/6875, {@link
+   * #gegGrossesAenderungsgesetz}): Das Beispiel-XML ist die Urfassung des GEG von 2020, geändert
+   * wird eine Fassung von 2023. Maßgeblich ist deshalb der Vergleich mit dem Entwurf — die
+   * Ausschussfassung muss <em>mehr</em> Befehle tragen, denn der Ausschuss hat zwei Artikel
+   * hinzugefügt (BGB und Betriebskostenverordnung).
    */
   @Test
-  void beschlussempfehlungWirdMitBegruendungUebergangen() throws Exception {
+  void beschlussempfehlungLiefertDieAusschussfassung() throws Exception {
     var xml = SAMPLEDATA.resolve("GEG/BJNR172810020.xml");
-    var pdf = SAMPLEDATA.resolve("GEG/BT-Drs-20-7619_Beschlussempfehlung.pdf");
-    assumeTrue(Files.exists(xml) && Files.exists(pdf), "GEG-Beispieldaten fehlen");
+    var empfehlung = SAMPLEDATA.resolve("GEG/BT-Drs-20-7619_Beschlussempfehlung.pdf");
+    var entwurf = SAMPLEDATA.resolve("GEG/BT-Drs-20-6875_Regierungsentwurf.pdf");
+    assumeTrue(
+        Files.exists(xml) && Files.exists(empfehlung) && Files.exists(entwurf),
+        "GEG-Beispieldaten fehlen");
+
+    var ausEmpfehlung = Pipeline.erzeugeSynopse(xml, List.of(empfehlung), null, false);
+    var ausEntwurf = Pipeline.erzeugeSynopse(xml, List.of(entwurf), null, false);
+
+    assertThat(ausEmpfehlung.anzahlAngewandt()).isEqualTo(67);
+    assertThat(ausEmpfehlung.anzahlAngewandt() + ausEmpfehlung.anzahlManuell())
+        .as("die Ausschussfassung trägt mehr Befehle als der Entwurf")
+        .isGreaterThan(ausEntwurf.anzahlAngewandt() + ausEntwurf.anzahlManuell());
+    // Die Quellenzeile muss sagen, welche der beiden Spalten gilt.
+    assertThat(ausEmpfehlung.html()).contains(", Ausschussfassung]");
+  }
+
+  /**
+   * Derselbe Weg auf einer zweiten Beschlussempfehlung — dem Dritten Bevölkerungsschutzgesetz
+   * (BT-Drs. 19/24334) —, damit der Leser nicht am GEG-Heft hängt.
+   *
+   * <p>Zwei Befehle bleiben hier unerkannt, beide wegen Setzfehlern der amtlichen Drucksache: In
+   * Nummer 16 b) fehlt der Schlusspunkt („… eingefügt“), und Artikel 3 Nummer 1 b) trägt ein
+   * überzähliges schließendes Anführungszeichen. Beides ist zeichengenau so übernommen.
+   */
+  @Test
+  void beschlussempfehlungBevoelkerungsschutzgesetz() throws Exception {
+    var xml = SAMPLEDATA.resolve("IfSG/BJNR104510000.xml");
+    var pdf = SAMPLEDATA.resolve("IfSG/1924334.pdf");
+    assumeTrue(Files.exists(xml) && Files.exists(pdf), "IfSG-Beispieldaten fehlen");
 
     var ergebnis = Pipeline.erzeugeSynopse(xml, List.of(pdf), null, false);
 
-    assertThat(ergebnis.anzahlAngewandt()).isZero();
-    assertThat(ergebnis.html()).contains("Beschlussempfehlung");
-    assertThat(ergebnis.html()).contains("Drs. 20/6875");
+    assertThat(ergebnis.anzahlAngewandt()).isEqualTo(47);
+    assertThat(ergebnis.html()).contains(", Ausschussfassung]");
   }
 
   /**
diff --git a/src/test/java/eu/mulk/aendggner/aenderung/parse/ZusammenstellungsLeserTest.java b/src/test/java/eu/mulk/aendggner/aenderung/parse/ZusammenstellungsLeserTest.java
new file mode 100644
index 0000000..8e994a6
--- /dev/null
+++ b/src/test/java/eu/mulk/aendggner/aenderung/parse/ZusammenstellungsLeserTest.java
@@ -0,0 +1,92 @@
+package eu.mulk.aendggner.aenderung.parse;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import org.apache.pdfbox.Loader;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Die Auflösung der Zusammenstellung einer Beschlussempfehlung am Beispiel der GEG-Novelle (BT-Drs.
+ * 20/7619). Geprüft wird nicht die Befehlszahl — das tut der {@code EndToEndTest} —, sondern jede
+ * der vier Entscheidungen, die der Leser zeilenweise trifft.
+ */
+class ZusammenstellungsLeserTest {
+
+  private static final Path EMPFEHLUNG =
+      Path.of("src/main/resources/sampledata/GEG/BT-Drs-20-7619_Beschlussempfehlung.pdf");
+
+  private static String fassung() throws Exception {
+    try (var dokument = Loader.loadPDF(EMPFEHLUNG.toFile())) {
+      var ergebnis = ZusammenstellungsLeser.lies(dokument, SuperskriptModus.ENTFERNEN);
+      assertThat(ergebnis.warnungen()).isEmpty();
+      assertThat(ergebnis.text()).isNotNull();
+      return TextBereiniger.bereinige(ergebnis.text());
+    }
+  }
+
+  /** Wo die Ausschussspalte ausgeschrieben ist, gilt sie — nicht der Entwurf daneben. */
+  @Test
+  void ausgeschriebeneAusschussfassungVerdraengtDenEntwurf() throws Exception {
+    assumeTrue(Files.exists(EMPFEHLUNG), "GEG-Beispieldaten fehlen");
+    var fassung = fassung();
+
+    assertThat(fassung).contains("13. Die §§ 34 bis 45 werden wie folgt gefasst:");
+    assertThat(fassung)
+        .as("die Entwurfsfassung desselben Punktes darf nicht danebenstehen")
+        .doesNotContain("Die Angaben zu den §§ 34 bis 45");
+  }
+
+  /**
+   * „Unverändert“ holt den Wortlaut aus der Entwurfsspalte — auch zeilenweise innerhalb eines
+   * Zitats, wo die Ausschussspalte für sich gelesen ihre Anführungszeichen nicht schlösse.
+   */
+  @Test
+  void unveraendertHoltDenWortlautAusDerEntwurfsspalte() throws Exception {
+    assumeTrue(Files.exists(EMPFEHLUNG), "GEG-Beispieldaten fehlen");
+    var fassung = fassung();
+
+    assertThat(fassung).contains("„§ 34 (weggefallen)");
+    assertThat(fassung).contains("§ 45 (weggefallen)“");
+    assertThat(fassung).doesNotContain("unverändert");
+  }
+
+  /**
+   * „Unverändert“ meint den Wortlaut, nicht die Zählung: Der Ausschuss streicht die Entwurfsnummer
+   * 5, seine eigene Nummer 5 ist die Nummer 6 des Entwurfs — mit dessen Wortlaut.
+   */
+  @Test
+  void umnummerierterPunktBehaeltDenWortlautUndErhaeltDieNeueMarke() throws Exception {
+    assumeTrue(Files.exists(EMPFEHLUNG), "GEG-Beispieldaten fehlen");
+    var fassung = fassung();
+
+    assertThat(fassung)
+        .contains("„5. die Anforderungen an den Einbau von Heizungsanlagen bei Nutzung von fester");
+    assertThat(fassung).doesNotContain("6. die Anforderungen an den Einbau von Heizungsanlagen");
+  }
+
+  /** Ein gestrichener Punkt hinterlässt nichts — weder den Vermerk noch den Entwurfstext. */
+  @Test
+  void gestrichenerPunktHinterlaesstNichts() throws Exception {
+    assumeTrue(Files.exists(EMPFEHLUNG), "GEG-Beispieldaten fehlen");
+    var fassung = fassung();
+
+    assertThat(fassung).doesNotContain("bb) entfällt");
+    assertThat(fassung)
+        .as("der vom Ausschuss gestrichene Entwurfstext gehört nicht in die beschlossene Fassung")
+        .doesNotContain("„1. eine Umwälzpumpe nach § 64");
+  }
+
+  /**
+   * Der quer am Blattrand stehende Vorabfassungs-Vermerk hat keine Grundlinie im Satzspiegel; er
+   * würde die Zeilenfolge zerschneiden und bleibt deshalb draußen.
+   */
+  @Test
+  void gedrehterRandvermerkKommtNichtInDenText() throws Exception {
+    assumeTrue(Files.exists(EMPFEHLUNG), "GEG-Beispieldaten fehlen");
+
+    assertThat(fassung()).doesNotContain("lektorierte");
+  }
+}
