Die Prüfung läuft fortan bei jedem Push von selbst

Gebaut und geprüft wurde bislang von Hand: „./mvnw verify“ und, seltener,
„./mvnw -Pwasm package“ nebst „reuse lint“. Ein Bruch fiel damit erst dem auf,
der zufällig baute — und gerade der Wasm-Bau, der eine andere Java-Fassung
voraussetzt als der gewöhnliche, wird am seltensten angefaßt.

Der neue Arbeitsablauf .github/workflows/ci.yml fährt bei jedem Push nach master
und bei jedem Pull Request drei Läufe nebeneinander: Bau und sämtliche Tests auf
einem Temurin-JDK 25 (Spotless und Enforcer laufen mit, weil sie an die Phase
„verify“ hängen), die Herstellung der Browserfassung auf Oracle GraalVM — die
Community Edition trägt Web Image nicht — samt deploy/webpaket.sh, und die
Lizenzauszeichnung nach REUSE. Binaryen wird dem Wasm-Lauf vorab eingerichtet,
damit wasm-opt tatsächlich läuft und die 25-MiB-Grenze an dem gemessen wird, was
ausgeliefert würde. Das Webpaket und die ausführbare Archivdatei bleiben als
Artefakte abrufbar, die Testberichte nur im Fehlerfall. Nachzuladen ist nichts:
Der Beispielkorpus liegt im Repository und ist allein von „git archive“
ausgenommen.

§ 17 des Handbuchs erhält hierzu die Absätze 4 und 5; das Fassungsverzeichnis
führt den Tag fort.

Geprüft: „./mvnw --batch-mode verify“ geht auf (58 s); der Wasm-Befehl des
Laufes ergibt örtlich „target/web ist auslieferbar“ (wasm-opt: 19 845 039 ->
17 392 218 Bytes); „reuse lint“ weist 224 von 224 Dateien als vollständig
ausgezeichnet aus.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019asn2GWjyjGotivHpYchfi
Change-Id: Ib9a7f676859529cc7c1253234ce7cc0175267b51
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..369f3e9
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,109 @@
+# SPDX-FileCopyrightText: 2026 Matthias Andreas Benkard <code@mail.matthias.benkard.de>
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+# Selbsttätige Prüfung nach README § 17. Drei Läufe nebeneinander:
+#
+#   1. „pruefung“        — ./mvnw verify: Kompilat, sämtliche Tests (Akzeptanz- und
+#                          Korpuslauf eingeschlossen), Spotless und Enforcer.
+#   2. „browserfassung“  — der Wasm-Bau nach § 14 Abs. 5. Er braucht Oracle GraalVM,
+#                          nicht die Community Edition: Web Image ist nur dort enthalten.
+#   3. „lizenzauszeichnung“ — reuse lint nach § 16.
+#
+# Der Beispielkorpus (src/test/resources/sampledata) liegt im Repository; das
+# gewöhnliche checkout genügt, nachzuladen ist nichts.
+
+name: CI
+
+on:
+  push:
+    branches: [master]
+  pull_request:
+  workflow_dispatch:
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.ref }}
+  cancel-in-progress: true
+
+permissions:
+  contents: read
+
+jobs:
+
+  pruefung:
+    name: Bau und Prüfung (JDK 25)
+    runs-on: ubuntu-latest
+
+    steps:
+      - uses: actions/checkout@v4
+
+      - name: Java einrichten
+        uses: actions/setup-java@v4
+        with:
+          distribution: temurin
+          java-version: '25'
+          cache: maven
+
+      - name: mvnw verify
+        run: ./mvnw --batch-mode --no-transfer-progress verify
+
+      - name: Ausführbare Archivdatei aufbewahren
+        uses: actions/upload-artifact@v4
+        with:
+          name: aendggner-jar
+          path: |
+            target/aendggner-*.jar
+            target/libs/
+          retention-days: 14
+
+      # Nur im Fehlerfall: sonst wäre bei jedem grünen Lauf ein Bericht abzulegen,
+      # den niemand ansieht.
+      - name: Testberichte im Fehlerfall aufbewahren
+        if: failure()
+        uses: actions/upload-artifact@v4
+        with:
+          name: surefire-berichte
+          path: target/surefire-reports/
+          retention-days: 14
+
+  browserfassung:
+    name: Browserfassung (GraalVM Web Image)
+    runs-on: ubuntu-latest
+
+    steps:
+      - uses: actions/checkout@v4
+
+      # Binaryen liefert wasm-opt. Fehlt es, bleibt das Modul unnachoptimiert
+      # (webpaket.sh warnt nur), und die Prüfung gegen die 25-MiB-Grenze von
+      # Cloudflare Workers misst nicht das, was ausgeliefert würde.
+      - name: Binaryen einrichten
+        run: |
+          sudo apt-get update
+          sudo apt-get install -y binaryen
+
+      - name: Oracle GraalVM einrichten
+        uses: graalvm/setup-graalvm@v1
+        with:
+          distribution: graalvm
+          java-version: '25'
+          cache: maven
+
+      # Die Tests laufen im Job „pruefung“; hier geht es um den Übersetzungsweg
+      # (native-image --tool:svm-wasm) und um deploy/webpaket.sh.
+      - name: mvnw -Pwasm package
+        run: ./mvnw --batch-mode --no-transfer-progress -Pwasm package -DskipTests
+
+      - name: Webpaket aufbewahren
+        uses: actions/upload-artifact@v4
+        with:
+          name: aendggner-web
+          path: target/web/
+          retention-days: 14
+
+  lizenzauszeichnung:
+    name: Lizenzauszeichnung (REUSE)
+    runs-on: ubuntu-latest
+
+    steps:
+      - uses: actions/checkout@v4
+
+      - uses: fsfe/reuse-action@v5
diff --git a/FASSUNGEN.txt b/FASSUNGEN.txt
index 269cd7a..9f17e99 100644
--- a/FASSUNGEN.txt
+++ b/FASSUNGEN.txt
@@ -21,6 +21,58 @@
 
 
 ════════════════════════════════════════════════════════════════════════════════
+ Fassung vom 31. August 2026,
+ zuletzt geändert durch die am 31. August 2026 vorgenommenen Änderungen
+════════════════════════════════════════════════════════════════════════════════
+
+Die Prüfung nach § 17 des Handbuchs läuft fortan selbsttätig: Ein Arbeitsablauf
+für GitHub Actions baut und prüft bei jedem Push und bei jedem Pull Request
+(Artikel 1). Das Handbuch weist dies aus (Artikel 2).
+
+
+Artikel 1
+Selbsttätige Prüfung
+
+Es wird der Arbeitsablauf „.github/workflows/ci.yml“ eingeführt. Er wird
+ausgelöst durch Push nach „master“, durch jeden Pull Request und auf Anforderung
+von Hand (workflow_dispatch); für denselben Verweis wird jeweils nur der jüngste
+Lauf zu Ende geführt (concurrency). Ihm sind allein Leserechte erteilt.
+
+(1) Der Lauf „pruefung“ baut und prüft auf einem Temurin-JDK der Fassung 25 mit
+    „./mvnw verify“. Damit sind neben den Einzel- und Akzeptanzprüfungen auch der
+    Korpuslauf (§ 6d), der Formatierer (Spotless) und die Mindestfassung des
+    Bauwerkzeugs (Enforcer) erfaßt, weil beide an die Phase „verify“ gebunden
+    sind. Die ausführbare Archivdatei nebst „target/libs“ wird als Artefakt
+    aufbewahrt, die Surefire-Berichte allein im Fehlerfall.
+
+(2) Der Lauf „browserfassung“ stellt die Browserfassung mit „./mvnw -Pwasm
+    package -DskipTests“ her. Er richtet hierfür Oracle GraalVM ein
+    (graalvm/setup-graalvm, „distribution: graalvm“); die Community Edition
+    trägt Web Image nicht (§ 14 Absatz 5). Vorab wird Binaryen eingerichtet,
+    damit „deploy/webpaket.sh“ die Nachoptimierung durch wasm-opt tatsächlich
+    vornimmt und die Grenze von 25 MiB an dem mißt, was ausgeliefert würde;
+    ohne Binaryen bliebe es bei einer bloßen Warnung. Das Verzeichnis
+    „target/web“ wird als Artefakt aufbewahrt. Die Tests bleiben hier
+    ausgesetzt; sie laufen im Lauf nach Absatz 1.
+
+(3) Der Lauf „lizenzauszeichnung“ prüft die Auszeichnung nach der
+    REUSE-Spezifikation (fsfe/reuse-action) und entspricht damit dem bisher von
+    Hand geführten „reuse lint“ (§ 16).
+
+Die drei Läufe hängen nicht voneinander ab. Nachzuladen ist nichts: Der
+Beispielkorpus liegt im Repository und ist nur von „git archive“ ausgenommen.
+
+
+Artikel 2
+Fortschreibung des Handbuchs
+
+§ 17 des Handbuchs (README.md) erhält die Absätze 4 und 5. Absatz 4 bezeichnet
+den Arbeitsablauf, seine drei Läufe und die Aufbewahrung der Artefakte; Absatz 5
+nennt die Voraussetzung des Wasm-Laufes (Oracle GraalVM) und stellt klar, daß der
+Beispielkorpus nicht nachzuladen ist.
+
+
+════════════════════════════════════════════════════════════════════════════════
  Fassung vom 29. August 2026 (zweite Fassung des Tages),
  zuletzt geändert durch die am 29. August 2026 vorgenommenen Änderungen
 ════════════════════════════════════════════════════════════════════════════════
diff --git a/README.md b/README.md
index c960a80..6248c61 100644
--- a/README.md
+++ b/README.md
@@ -1119,6 +1119,26 @@
 auch den Kopf: Standangabe und angewandte Hefte müssen ihn überstehen, sonst
 verlöre die Kette bei jedem Schritt ihr Gedächtnis (§ 6a Absatz 4).
 
+(4) Die Prüfung nach Absatz 1 läuft überdies selbsttätig: Bei jedem Push nach
+`master` und bei jedem Pull Request fährt GitHub den Arbeitsablauf
+`.github/workflows/ci.yml` in drei nebeneinanderlaufenden Läufen. Der erste baut
+und prüft auf einem JDK 25 (`./mvnw verify`), wobei Spotless und der Enforcer
+ohne weiteres Zutun mitlaufen, weil sie an die Phase `verify` gebunden sind. Der
+zweite stellt die Browserfassung nach § 14 Absatz 5 her
+(`./mvnw -Pwasm package`) und durchläuft damit auch `deploy/webpaket.sh` samt
+seiner Prüfungen — Nachoptimierung durch `wasm-opt`, Größe des Quelltextarchivs,
+25-MiB-Grenze je Datei (§ 15 Absatz 1). Der dritte prüft die Lizenzauszeichnung
+(`reuse lint`, § 16). Das Webpaket (`target/web/`) und die ausführbare
+Archivdatei bleiben als Artefakte des Laufes vierzehn Tage lang abrufbar; die
+Testberichte werden nur im Fehlerfall aufbewahrt.
+
+(5) Der Wasm-Lauf nach Absatz 4 verlangt dieselbe Voraussetzung wie die
+Herstellung von Hand, nämlich Oracle GraalVM und nicht die Community Edition
+(§ 14 Absatz 5); eingerichtet wird es mit `graalvm/setup-graalvm` unter der
+Angabe `distribution: graalvm`. Der Beispielkorpus ist dabei nichts
+Nachzuladendes: Er liegt im Repository, und `.gitattributes` nimmt ihn allein von
+`git archive` aus (§ 14 Absatz 8).
+
 ## Lizenz
 
 Der Quelltext steht unter der GNU Affero General Public License, Version 3 oder