Status (2026-09-04): lebend. Nachschlagewerk über die Begriffe, die in
docs/, in Issues/PRs und in der Admin-Oberfläche vorkommen — über 300 Einträge, rund 57 000 Token.Diese Datei liest man nicht am Stück. Sie ist die Nachschlage-Instanz: Einstieg ist der alphabetische Schnellindex, der jeden Begriff seinem Themenblock zuordnet (§1 Schrift · §2 Architektur & Datenmodell · §3 Mess- und Fit-Vokabular · §4 Metriken & Benchmarks · §5 Werkbank & Prozess · §6 Extern/Forschung · §7 Öffentliche Seiten). Für den Einstieg in eine Sitzung steht seit 2026-09-04 die Kurzfassung
kurzglossar.mdauf der Pflichtlektüre — 77 Begriffe, je ein bis zwei Sätze, jeder mit dem Sprung hierher; sie ersetzt dieses Glossar nicht, sie ersetzt nur das Am-Stück-Lesen.Was ein Eintrag verspricht. Einen allgemeinverständlichen Teil ohne Vorkenntnisse und, wo es etwas zu verankern gibt, den Modul-, Formel- oder Konstantennamen zum Weitergraben. Kein API-Verzeichnis: aufgenommen ist, was ein Leser in Prosa, Issue oder UI antrifft.
Nachzieh-Pflicht: jedes Doc und jeder PR, der einen neuen Fachbegriff oder eine neue Kennzahl prägt, legt im selben Zug einen Eintrag hier an — Themenblock und Schnellindex (Regel auch in
CLAUDE.md§ „Working guardrails“,.github/copilot-instructions.mdund den Skills/write-docs+/open-pr). Erreicht der Begriff danach Code, die Agenten-Dateien oder PR-Beschreibungen, folgt der Kurzeintrag im Kurzglossar (Schwelle und Ausschlüsse stehen in dessen Kopf).
Dieses Projekt hat über die Läufe hinweg eine eigene Sprache entwickelt — teils Paläografie („Schwellzug“, „Duktus“), teils Architektur („Laufform“, „Bibliothekseinheit“), teils Hausmaße aus einzelnen Messrunden („gen_chamfer“, „Bézier-Handle-Floor“, „degenerierte Solves“). Wer neu dazukommt — Mensch oder KI — trifft diese Wörter im Fließtext, ohne dass sie dort noch einmal erklärt werden.
Wie dieses Glossar gedacht ist: jeder Eintrag hat einen allgemeinverständlichen Teil (keine Vorkenntnisse nötig) und, wo es etwas zu verankern gibt, einen technischen Nachsatz mit dem Formel-, Modul- oder Konstantennamen. Der Nachsatz ist bewusst Anker-Vokabular: einen Eintrag in einen beliebigen KI-Chat kopiert, hat man genug Stichworte, um tiefer zu graben („Erklär mir Tikhonov-Regularisierung“, „Was ist eine Chamfer-Distanz“), ohne dass dieses Repo die halbe Numerik-Vorlesung mitliefern muss.
Was es nicht ist: keine API-Referenz und keine Vollzählung aller Bezeichner. Aufgenommen ist, was ein Leser in Prosa, Issue oder UI antrifft und nicht raten können soll.
Die Ziffer nennt den Themenblock unten: §1 Schrift & Paläografie · §2 Architektur & Datenmodell · §3 Mess- und Fit-Vokabular · §4 Metriken & Benchmarks · §5 Werkbank & Prozess · §6 Extern/Forschung · §7 Öffentliche Seiten.
- A —
add_header-Vererbungsfalle §2 · Anker · Sample · Schritt §4 · Abdeckungsmatrix §4 · abgeschnittener Anstrich §4 · Absetzen §1 · Absprung (Lotse) §4 · Arm-Datei (humanbench) §4 · Abstandsprofil (Werkbank) §5 · Aggregat §2 · AIoU §6 · Allograph §1 · Analysis-by-Synthesis §2 · Anker §2 · Anker im leeren Papier §4 · Anheftung (Eigenhand) §5 · Anstrich/Auslauf §1 · Apex-Übergabe (apex_handover) §2 · Auftragskorb §5 · Auftragskorb-Protokoll §5 · Ausbau-Quote (→ Bestandsbericht) §5 · Ausgangsschrift §1 · Ausreißer §4 · Austritts-Trim (exit_trim) §2 - B — Bandzugfeder §1 · Bbox §2 · Beleg (Eigenhand) §5 · bench_loss §4 · Bereich daneben §4 · Berührung (Struktur-Zähler) §4 · Bestandsbericht §5 · Bestätigung A/B (→ Referenzsatz) §4 · Bewertungsdurchgang §4 · Bézier-Handle-Floor §3 · Biasing §6 · Bibliothekseinheit §2 · bindend §5 · Binnenflächen-Bedingung §3 · blinde Wiederholung §4 · Bogen (Eigenhand) §5 · Bogen-Kappe §4 · bogengleich §3 · Bot-Site (
bot_fetch) §2 · Bowl-Exit-Tuck §2 - C — CER §6 · Chamfer-Distanz §4 · Changelog-Fragment §5 · Chart §2 · Chart-Saat §4 · Chor (geplant) §4 · Chronik (tracebench) §4 · Cusp-Connector §3
- D — dconn §4 · Deckung §3 · Deckungslücke §3 · Doppel-X-Duplikat §4 · Drei Rollen (Tafel · Platte · Eigenhand) §2 · Duell-Ansicht §4 · Duell-Namen §4 · degenerierte Solves §3 · Degeneriewächter §3 · d_end (verworfen) §4 · Dice §4 · Dissektion §2 · doff §4 · dspan §4 · DTW §6 · dtw_xh §4 · Duktus §1 · Duktus-Prior §1 · Durchstoß-Kriterium §4
- E — Echtheitsfrage §4 · EDT §3 · Eigenhand-Buchführung §5 · Eigenhand-Erfassung §5 · Einrichtungs-Wizard §5 · Endblende (Laufform) §2 · Entdrillung §4 · Entwurfsnetz des Wizards §5 · Ernte §2 · Ernte-Fixpunkt §4 · Erstbeleg-Quote (→ Bestandsbericht) §5 · extrapoliertes Landmark-Ziel §3
- F — Fassung (Eigenhand) §5 · Feder-Entfaltung §3 · Federprobe §7 · Federtypen §1 · Federwinkel §1 · Fehler-Taxonomie §4 · Fehlerschicht (
apiErrorText) §5 · Feinschliff (geplant) §4 · Fenster-Versatz §4 · FID §6 · Fixture-Wurzel §4 · Form-Abstand (Laufform) §2 · Frame-Gate (frame_stale) §4 · Fremdtinte §3 · Frozen-Reference-Regel §4 · Fuge §1 · Fußwende §2 - G — G1-/G2-Stetigkeit §6 · gefüllte Ringe §4 · gen_chamfer §4 · grid_step_crop_px §4 · Gewackel §4 · Girlande §2 · Glätte-Sensor §2 · Gleichzug §1 · Gleichzug-Audit §4 · glyph_key §2 · Gradientenzerlegung §4 · Grundstrich/Haarstrich §1 · Grundtafel §7 · gut (
G) §4 · Gute-Fortsetzung §4 - H — H0–H5 §5 · Hand §2 · HTG §6 · HTR §6 · Huber-Kappung §3 · humanbench §4 · HWD §6
- I — IndexNow §2 · Ink gap §3 · Instance §2 · Isochronie §6 · Iterationsdeckel §3
- J — Junction-Pinch §4 · Junction-Verschiebung §3
- K — k0-Protokoll §4 · Karten-Abdrift §4 · Karten-Soll-Vollständigkeit §4 · Kettenfit §3 · Kill-Kriterium §3 · klassenbewusste Korrespondenz §3 · Klassenregel §2 · Knick §4 · Knick am Rand §4 · komplett daneben §4 · Komposition §2 · Komposition voller Länge §2 · Konnektor §2 · Kopf-Gate (Laufform) §2 · Kopplungshöhe §1 · Kopplungs-Stub §3 · Korb-Notiz §5 · Korrespondenz-Kappe §3 · Kreuzungs-Landmarke §3 · Kompromisswinkel §2 · Kringel-Exit §2 · Kringel-Landmarke §4 · Kurzglossar §5
- L — Labs §4 · Landmarken-Auftrag §5 · Landmarken-Erkennung §5 · Landmarken-Linse §5 · Landmarken-Term §3 · Laufform §2 · Laufform-Lücke §2 · Laufform-Topologie-Wächter §3 · Lineal-Soll-Budget §4 · Lotse (Arbeitstitel) §4 · laufform_dev_xh §4 · L-BFGS-B §6 · LDTW §6 · lebend §5 · Lese-Budget §5 · like-for-like Gate §3 · Lesart §1 · Lesart prüfen §7 · Lesart-Schlüsselversion §1 · Lese-Quiz §7 · Lesefalle §1 · Lesetafel §7 · Ligatur §1 · Lineatur §1 · loss §4
- M — M1–M4 (Kettenfit-Kennzahlen) §3 · M0–M7 (MVP-Meilensteine) §5 · M4-Fit §3 · MAD §4 · Marke §4 · Marken-Claim-Trennung §3 · Marken-endständige Assembly §4 · matched arc §3 · MDN §6 · meas §4 · Messboden §4 · Messjournal §5 · Mindestbelegung (Eigenhand) §5 · Mittellinien-Öffnungsweite (
D0) §4 - N — Nachbarbindung §4 · Nachfahr-Stand §5 · Naht §3 · Naht-Anteil §3 · Nahtverhandlung (
seam_negotiation) §2 · Naht-Winkel (seam_deg) §4 · Natürlichkeitsmetrik §4 · Nib-gekoppelte Clearance §2 · Nullprobe §4 - O — Offenbacher §1 · Öffnungsweite (→ Mittellinien-Öffnungsweite) §4 · Open-Core-Moat §2 · Origin-Geheimnis §2 · Ortsmarker §4 · Ortsprüfung §4 · Override §2
- P — Paar-Aggregat §2 · Paar-Editor §5 · paariger Blindvergleich §4 · pair_loss §4 · Passmarken §5 · Pfeilhöhe (Sagitta) §3 · Plateau-Anker §4 · Platte (→ Drei Rollen) §2 · Platzierungsschranke §3 · Postkarte (Federprobe) §7 · Prerender-Pfad (Crawler) §2 · Prior-Landerichtung §2 · Priming §6 · Produktions-Init (
connector_init) §4 · Provenance §2 · Provenienz-Stempel §4 · Prüfstein §4 - Q — Quelle §2
- R — R1–R5 §5 · Radierer §5 · Rastersuchlauf §3 · Ratsche (Ratschen-Budget) §3 · Re-Baseline §4 · Rechteck-Reparatur §5 · Referenzsatz (nachgefahren) §4 · Registrierung §2 · Regel-Fix vor Override §5 · Render-Kontext §2 · Report-Only-Woche §2 · Report-Spalte §4 · reproduced §5 · Reservierungs-Veto §4 (→ Lineal-Soll-Budget) · Residualprofil §4 · resolution §5 · Restart-Klasse (
CAP_RESTART_BASES) §2 · Retrace §1 · Retrace-Guard §3 · Retrace-Segment §4 · Rettungsweg §5 · Route G §4 · Rückgabe an Autor §5 · Rückhaltemenge §4 - S — Same-Hand-Disziplin §4 · Säulenabgang (
stem_depart) §2 · Schienen-Auslauf §3 · Schräglage §1 · Schreib-Karte §2 · Schreibtafel §7 · Schriftgrößen-Leiter §7 · Schriftkunde (Seite) §7 · Schleifenbereich §2 · Schleifen-Registrierung §2 · Schleifen-Schluss (→ Zwei-Züge-Modell) §4 · Schleifen-Sehne §4 · Strichtrennung (stroke_separation, → Zwei-Züge-Modell) §4 · Schnittband §5 · Schnittmarken §5 · Schwellzug §1 · Score §4 · Segment-Attribution §4 · Sehnen-Schwelle §3 · Sektion §2 · Shaping §2 · Sieb-Disziplin (→ Siebung) §5 · Siebung §5 · Sigma-Lognormal §6 · Skelett §3 · Slant-Spalte §4 · Slot §2 · Specimen §2 · Spike-Verhältnis §4 · Spitzfeder §1 · Spline-Basis-Median §2 · Sprung-Gate (Laufform) §2 ·stage(work_items) §5 · Stamm-Rückpass §2 · Stand-Block §5 · Status-Vokabular §5 · Stehendes Setup §5 · Streifen (Eigenhand) §5 · Streifenkartei §5 · Streifenplan §5 · Stiftmarke §5 · St-Ligatur §1 · Stub §3 · Stufen-Doktrin §5 · Style §2 · Sütterlin §1 - T — Tafel §2 · tail_adapt/head_adapt §3 · tail_stub_delta §3 · Template §2 · Tikhonov-Regularisierung §3 · Tintenabstand §4 · Tintenboden §7 · Tinten-Evidenz-Maske §3 · Tintenfolger §3 · Tintenlücke §3 · Tinten-Zuweisung per Strecke §3 · Topologie-Reparatur §3 · Topologie-Verlust (Kringel) §4 · Topologie-Wächter §3 · tracebench §4 · Trajektorien-Recovery §6 · Trefferfläche (
hitArea) §5 · Triage-Pflicht §5 · Typo-Boden §5 - U — Umbruch der Federprobe §7 · Unantastbare Lineatur §7 · Unstetigkeits-Sensor §4 · Unvollständige Wortprobe §5
- Ü — Übergang §2 · Übergangs-Generator §2 · Übergangsraum §5 · Überlappungsterm §3 · Übungsblatt §7 · understanding §5
- V — Variante §2 · Verbinder-Mitschnitt §4 · Vereinfachungs-Gate §5 · Verfahrensseite §4 · Vier Augen (geplant) §4 · Vereinigungsfenster §3 · Verlässlichkeitsschranke §4 · Verschmelzungs-Anzeiger §4 · Verworfen §5 · Vorkommensschranke §2 · Vorlage §2 · Vorregistrierung §4 · Vorschub-Kalibrierung §2 · Vorschrift §1
- W — W1–W6 §5 · Wackler §4 · Warp §3 · Werkbank §5 · wordbench/glyphbench/pairlab/chainbench §4 · work_items §5 · Wort-Ausschnitt (Eigenhand) §5 · Wort-Editor §5 · Wortrunde (humanbench) §4 · Wort-Tintenlücke §2 · Wort-Trace §2 · Wortvorrat §5 · Wurzel-Digest (
root_digest) §4 - X — x-Höhe (
xh) §1 - Z — Zeichenbreiten-Mittel (
AVG_ADVANCE_UNITS) §7 · Zeilen-Gate (Laufform) §2 · Zeilenmarke §7 · Zelle einsetzen §5 · zirkuläres Kriterium §4 · zonale Rückweisung (zonal) §3 · „Zug um Zug“ §7 · Zwei Stillen (Leerzustands-Regel) §5 · Zwei-Drittel-Gesetz §6 · Zwei-Züge-Modell §4 · Zögling (geplant) §4
Duktus (ductus) — die Art, wie ein Buchstabe geschrieben wird:
Reihenfolge der Striche, Richtung, wo die Feder abgesetzt wird. Nicht die
fertige Form auf dem Papier, sondern der Weg dorthin. Zwei Buchstaben
können identisch aussehen und einen völlig verschiedenen Duktus haben.
Technisch: deutsche Fließtext-Schreibung mit k (Duden), Code-Identifier
bleibt ductus → sprachregelung.md §2 · allgemein.md §3
Duktus-Prior — die zentrale Idee des Projekts: Weil aus einem Foto nicht ablesbar ist, welcher Ast einer Kreuzung zu welchem Strich gehört und was zuerst geschrieben wurde, gibt man dieses Wissen vorher vor — als von Hand autorisierten Duktus je Buchstabe. „Prior“ ist der statistische Begriff für Vorwissen, das man in eine Schätzung einbringt. → architektur.md §2
Allograph — zwei verschiedene Schreibformen desselben Buchstabens, die
beide korrekt sind, aber an verschiedenen Stellen stehen. Prominentestes
Beispiel: das lange ſ (im Wortinneren) und das runde s (am Wortende) sind
verschiedene Buchstabenformen mit verschiedenem Duktus, nicht dasselbe s
mit anderem Anschluss. Im Repo sind Allographe daher getrennte Glyphen
(longs vs. s), nicht Varianten. → architektur.md §3 ·
orthographie-regeln.md §1
Lesart — ein echtes Wort, das ein gelesenes Wort in der deutschen
Schreibschrift ebenso gut sein könnte: gleiche Länge, jeder abweichende
Buchstabe ein dokumentierter Verwechsler (Lesefalle) des gelesenen. Die
Lesart-Seite (/lesen/vergleichen) bietet sie zur Vermutung des Lesers
an, gereiht nach der Summe der Verwechsler-Abstände (ein dokumentiertes
Paar = 1), Bankwörter vor Wörterbuch. Kein Buchstabentausch ohne Wort
dahinter (Autor, 2026-08-30). Im Repo: core/lesarten (Schlüssel
lesart_key = jeder Buchstabe durch seine Verwechsler-Klasse ersetzt,
rank_readings), Tabelle lesart_forms, GET /lesarten?text=.
Lesart-Schlüsselversion (key version) — die Versionsnummer der
Verwechsler-Tabelle, mit der die Wörter in lesart_forms einsortiert
wurden. Ein Wort ist nur unter dem Schlüssel auffindbar, unter dem es
gespeichert wurde: Kommt ein Paar hinzu (zuletzt g/p, 2026-09-04),
liegen alle davon betroffenen Wörter der lebenden Generation im falschen
Eimer, bis das Wörterbuch neu geladen ist. Die Version erzwingt genau
das — sie geht in den Inhalts-Hash des Builds ein, den der Server gegen
den lebenden vergleicht, also ist derselbe Wortbestand unter geänderter
Tabelle ein neuer Build und wird nicht mehr als „schon live" (409)
abgewiesen. Technisch: core/lesarten::LESART_KEY_VERSION mit
key_signature() (Version + Tabelle, geht in den sha256 von
tools.lesarten.sync) und key_marker() (steht als eigenes Wort im
Quell-Label des Builds; is_current_fold() vergleicht es mit dem
eigenen, und die API meldet eine ältere Generation als stale in
GET /lesarten/dictionary). → Lesefalle §1 · orthographie-regeln.md §3
Lesefalle — ein Buchstabenpaar, das sich in der deutschen
Schreibschrift so ähnelt, dass Leseanfänger es regelmäßig vertauschen,
und das ein benennbares Merkmal trennt — meist ein einziges: n und u
nur der u-Bogen, e und n die Enge der Züge, i und j die Unterlänge,
g und p die geschlossene Schleife gegen den geraden Abstrich; bei
ſ und f sind es zwei: oben die Schleife des f gegen die Spitze des ſ,
dann der Querstrich, den nur das f hat;
dazu die Positionsregel des runden s (Silben-/Wortende) und die
Versalien-Cluster L/K/R, N/M, B/V, für die der Katalog kein einzelnes
Merkmal nennt. Im Repo: der Katalog app/src/sections/quiz/lesefallen.ts
(Sätze in locales/de/quiz.ts, play.rules), aus dem das Lese-Quiz nach
einem Fehlgriff die Regel zeigt — gezeigte Form gegen geratenen
Buchstaben, richtungsbewusst, und für Paare ohne dokumentiertes Merkmal
bewusst keine Erklärung. Die Schriftkunde-Seite führt dieselben Fallen
unter „Buchstaben-Besonderheiten“. → orthographie-regeln.md §1/§3 ·
vision.md Ziel 4
Ligatur — eine auf der Lehrtafel als eigene Einheit gelehrte
Buchstabenverbindung. Der geschlossene Satz im Projekt: ch · ck · tz
· ſt · St · qu · ß. Sie werden als eigene Glyphen mit eigenem Duktus
gespeichert („enumerieren, nicht generieren“) — im Gegensatz zu beliebigen
Buchstabenpaaren, deren Verbindung erzeugt wird. Fehlt der Canonical eines
Clusters, zerfällt der Slot beim Shaping in seine Einzelbuchstaben
(Rückfall, ch · ck · tz · ſt · St · qu); ß bleibt davon
ausgenommen und ATOMAR — sein ſs/ſz-Zerfall ist selbst eine
Allographen-Frage, und ein naiver Split schriebe mitten im Wort ſſ.
→ architektur.md §4 · write-api.md „Pipeline“ · „St-Ligatur“
St-Ligatur — das eine GROSS-Cluster des geschlossenen Ligatur-Satzes
(Korb #9, 2026-08-30): die 1922er Sütterlin-Vorlage schreibt das große S
ohne Absetzen in das kleine t weiter, während andere Groß-Paare (Sc …)
das S absetzen und an der Grundlinie neu ansetzen. Glyph-Key St; erkannt
wird exakt großes S vor kleinem t (STEIN/sT zerfallen nie, eine Fuge
dazwischen blockiert das Cluster). Bis der Autor die Tafel-Form im Wizard
nachgefahren hat, greift der Ligatur-Zerfall: der Slot schreibt sich als
S + t mit generiertem Übergang, exakt wie vor der Aufnahme in den Satz.
core/shaping.py (_LIGATURES) · TS-Zwilling app/src/domain/glyphs.ts
(COMB). → „Ligatur“ · architektur.md §4
Fuge (morpheme boundary) — die Nahtstelle in einem zusammengesetzten
Wort (Donners·tag, Aus·flug). Sie ist orthographisch relevant, weil dort
das runde s steht, obwohl es mitten im Wort sitzt. Da die volle Regel noch
nicht implementiert ist, gibt es einen manuellen Marker: ein | im
Eingabetext erzwingt das Schluss-s und verhindert, dass eine Ligatur über
die Fuge greift (Donners|tag).
Technisch: core/shaping.py::FUGE, Zwilling app/src/domain/shaping.ts
→ orthographie-regeln.md §1.2
Lineatur — das Liniensystem im Schulheft. Vier Linien mit deutschen Namen, die im Repo (Code-Kommentare, UI, Docs) durchgängig gelten: Oberlinie · Mittellinie · Grundlinie · Unterlinie; die drei Räume dazwischen heißen Oberlänge · Mittellänge · Unterlänge. Das Verhältnis der drei Zonen ist ein Schriftmerkmal (Sütterlin 1:1:1, Offenbacher 2:3:2, Kurrent 2:1:2). → allgemein.md §1
Vorschrift — auf einem Übungsblatt die vorgeschriebene Musterzeile, die
der Lernende in den Leerzeilen darunter nachschreibt. Auf der Seite: der
Übungstext des Übungsblatts (/schreiben/uebungsblatt), zeilenweise in der
nachgeschriebenen Vorlage gesetzt — komponiert wie in der Federprobe
(GET /write/word), auf die Zeilen der gewählten Lineatur gelegt
(Mittelband = x-Höhe), darunter auf Wunsch eine graue Kopie zum Nachspuren
und Leerzeilen zum Nachschreiben; was nicht auf das Blatt passt, wird
benannt statt gezeichnet. Technisch:
app/src/lib/uebungstext.ts (placeText), Browser-Hälfte
sections/worksheet/useWorksheetText.ts.
x-Höhe (xh) — die Höhe der Mittellänge, also eines Buchstabens ohne
Ober- und Unterlänge (klassisch: die Höhe des x). Sie ist die
Maßeinheit des ganzen Projekts: Anker, Abstände, Toleranzen und fast
alle Kennzahlen stehen in x-Höhen, nicht in Pixeln — nur so sind
verschieden große Scans vergleichbar. „0,19 xh“ heißt: 19 % der
Mittellängenhöhe.
Schräglage (slant) — wie schräg die Schrift steht. Messkonvention
im ganzen Repo: Winkel des Abstrichs zur Grundlinie, 90° = senkrecht.
Sütterlin steht senkrecht (90°), Kurrent um 1900 bei 60–70°, die
Loth-Tafel von 1866 gemessen bei ~50°. Feld slant_deg. → allgemein.md §2
Schwellzug (pressure-driven stroke-width modulation) — das An- und Abschwellen der Strichbreite bei der elastischen Spitzfeder: Druck spreizt die Federzinken, der Abstrich wird dick, der Aufstrich bleibt haarfein. Charakteristisch für Kurrent.
Gleichzug — das Gegenteil: gleichbleibende Strichstärke ohne Druckwechsel, geschrieben mit einer Redis-/Gleichzugfeder. Charakteristisch für Sütterlin — Ludwig Sütterlin wählte sie bewusst, damit Kinder nicht auch noch Druck dosieren müssen.
Grundstrich · Haarstrich — Grundstrich (= Abstrich, abwärts) ist der breite Hauptstrich, Haarstrich (= Aufstrich, aufwärts) die feine Linie. Bei der Spitzfeder ist das ein Druck-, bei der Bandzugfeder ein Richtungsunterschied. → allgemein.md §3
Absetzen (pen lift) — die Feder vom Papier abheben. Ein Buchstabe
kann aus mehreren Zügen bestehen (das u hat zwei Abstriche mit einem
Absetzen dazwischen); die Engine darf über ein Absetzen nie eine Linie
ziehen.
Technisch: flacher raw_path mit pen_up-Markern + stroke_starts in
trace_meta; Kanonisierung, Diagnose und Fit behandeln jeden Zug einzeln.
Anstrich · Auslauf — der kleine Zustrich, mit dem ein Buchstabe beginnt (Anstrich), und der Ausläufer, mit dem er endet (Auslauf). Im verbundenen Wort werden sie nicht gespeichert, sondern vom Composer aus dem Slot-Kontext gesetzt — am Wortanfang bleibt der Anstrich stehen, in der Wortmitte geht er im erzeugten Übergang auf. → architektur.md §3/§4
Retrace (Rückzug) — die Feder fährt auf derselben Linie zurück, die sie gerade gezogen hat (typisch beim langen ſ, beim t, beim f). Für die Bildanalyse ein Problemfall: zwei Striche liegen als eine Tintenspur übereinander. → qualitaetsmetrik.md §5
Kopplungshöhe (coupling) — auf welcher Höhe ein Buchstabe an seinen
Nachbarn andockt: unten an der Grundlinie oder oben im Mittelband. Eine
Eigenschaft des Buchstabens, aber sie steht in der Klassenregel, nicht im
Template: core/compose.py::HIGH_COUPLE_BASES koppelt Rundkörper
(e/a/o/c/d/g/q) oben am Scheitel, Arkadenbuchstaben (n/m/i/u) unten über die
Grundlinien-Girlande. Das früher pro Glyph autorierte Feld
entry/exit.coupling wurde von nichts gelesen und ist entfernt.
→ architektur.md §3
Federtypen — Spitzfeder (elastisch, Breite kommt aus dem Druck →
Schwellzug, Kurrent) · Bandzugfeder / Breitkantfeder (breite,
schräg gehaltene Schneide, Breite kommt aus der Richtung, Offenbacher) ·
Redisfeder / Gleichzugfeder (runder Schreibkopf, Breite konstant,
Sütterlin). Im Code entscheidet der width_resolver des Stils, welches
Modell beim Rendern gilt. → federmodelle.md §1
Federwinkel (nib angle, alpha) — der Winkel, in dem die Schneide
einer Bandzugfeder zur Schreiblinie steht. Bei der Offenbacher lehrt Koch
konstante 15° — daraus folgt das ganze Breitengesetz der Schrift.
Technisch: w(φ) = W·|sin(φ−α)| + t·|cos(φ−α)| in
core/widths.py::BroadNib; alpha ist die gelehrte Konstante und wird
nie pro Quelle gefittet. → federmodelle.md §2
Ausgangsschrift — die an der Schule gelehrte Norm-Schreibschrift. Das Projekt kennt drei: Kurrent (bis ~1900 gebräuchlich, schräg, Spitzfeder) · Sütterlin (1911, senkrecht, Gleichzug, 1:1:1) · Offenbacher (Rudolf Koch 1927, Bandzugfeder, 2:3:2). Achtung Begriffsfalle: „Sütterlin“ wird umgangssprachlich für jede alte deutsche Schreibschrift benutzt. → schriftkunde/allgemein.md §5
Analysis-by-Synthesis — die Grundmethode: Statt aus dem Bild eine Form herauszulesen, wird eine bekannte Form so lange an das Bild angepasst, bis sie passt. Das Bild liefert Geometrie und Strichbreite, das Duktus-Modell liefert Strichreihenfolge und Kreuzungsauflösung. → architektur.md §2
Bibliothekseinheit — der Schlüssel, unter dem eine kanonische Form
liegt: (style, glyph, variant). Also: welche Schriftfamilie, welche
Glyphe, welche gelehrte Formvariante. Die Wortposition gehört seit dem
Positions-Rückbau (Redesign R2, Migration 0017) nicht dazu — sie ist
Render-Kontext, keine eigene Zeile. → architektur.md §3
Style (Grundvorlage / Schriftfamilie) — Kurrent · Sütterlin ·
Offenbacher. Trägt die Voreinstellungen der Schrift: width_resolver,
default_slant_deg, default_style_ratio. Tabelle styles.
Hand — ein Schreiber. Die zentrale Trennlinie der Statistik: über
Hände wird nie gemittelt. Eine gerenderte Schrift hängt immer an genau
einer Hand; fremde Hände sind Vergleichsmaterial, nie Vorbild. Tabelle
hands, Referenzhand des Projekts: suetterlin-1922-norm.
→ handmodell-stufenplan.md §2/§5
Quelle (source) / Vorlage — die Herkunft der Bytes: eine
Lehrtafel (kind: chart) oder ein Manuskript. Im Admin heißt sie
„Vorlage“, und alles im Admin gehört zu genau einer gewählten Vorlage
— deshalb ist die Vorlagen-Auswahl der Eingangsschritt. Tabelle sources.
Tafel · Chart · Chart-Zelle — die gedruckte Buchstabentafel eines Lehrbuchs (Loth 1866, Sütterlin-Leitfaden 1922, Koch 1928, Petzendorfer 1889) und die einzelne Zelle darin, aus der ein Buchstabe geschnitten wird. „Chart-Zeile“/„Tafel-Form“ = die aus der Zelle autorisierte Grundform (Variante 0), im Gegensatz zur gemessenen Laufform. Welche Aufgabe eine Tafel gegenüber Platte und Eigenhand hat, steht unter Drei Rollen.
Drei Rollen (Tafel · Platte · Eigenhand) — die Aufgabenteilung der
drei Sorten Schriftmaterial, mit denen das Projekt arbeitet
(Autor-Entscheid 2026-09-07). Die Tafel (gemeinfreie Lehrtafel: Loth
1866, Petzendorfer 1889, Sütterlin-Ausgangsschrift 1922, Koch 1928) ist
das Historische — sie liefert die Geometrie der kanonischen Templates
und die Belege der Schriftkunde. Die Platte ist der gedruckte Bogen
mit ganzen, geschriebenen WÖRTERN derselben Vorlage (Sütterlin 1922,
Abb. 19/20): Ground Truth fürs Nachfahren und der eingefrorene
Referenzsatz, gegen den optimiert wird — Maßstab, nicht Auslieferung.
Die Eigenhand ist die mit echter Feder geschriebene Hand des Autors;
sie wird die ausgelieferte Schreibhand der öffentlichen Seiten (Hero,
Federprobe, Übungsblatt; beim Lese-Quiz ist die didaktische Unterfrage
offen), sobald ihr Bestand Alphabet und Übergänge deckt — weil sie
hochauflösend, mit erfasstem Setup und beliebig nachlieferbar ist und
vollständig dem Autor gehört. Ob später noch historische Alltagsschriften
als vierte Sorte dazukommen, ist ausdrücklich offen.
Technisch: die Rollen sind keine Schema-Größe — Tafel und Platte sind
zwei Abbildungen DERSELBEN Quelle (data/sources/suetterlin-1922/, die
Wortvermessung als Sidecar words.json), die Eigenhand wird eine eigene
hands-Zeile (Stufe H5).
→ concepts/vision.md § „Drei Rollen: Tafel · Platte · Eigenhand“ ·
proposals/eigenhand-erfassung.md §2
Bbox — die Zuschnitt-Konfiguration einer Chart-Zelle: Rechteck,
Radierer-Striche, gemalte Tinte, Lineatur-Kalibrierung, eingesetzte
Spender-Zellen (patches), Anzahl der Anker, locked. Tabelle bboxes.
Technisch: core/chart.py ist das Lade- und Zuschnitt-Modul —
crop_with_mask komponiert den freihändigen Radierer (mask_strokes),
die eingesetzten Spender-Zellen (patches) und den manuellen
Tinte-Pinsel (ink_strokes) in den Ausschnitt.
Template — die kanonische Form einer Glyphe: Anker (die Stützpunkte
der Mittellinie), half_widths (das gemessene Breitenprofil),
raw_path (der von Hand gezeichnete Stylus-Pfad), entry/exit/advance.
Tabelle templates.
Anker (anchors) — die Stützpunkte, aus denen die Mittellinie eines Buchstabens besteht (Voreinstellung ~120 pro Glyphe). Fast alle Messungen des Projekts sind „pro Anker“ — Median pro Anker, MAD pro Anker, Auslenkung pro Anker.
Variante (variant) — eine zweite, von der Norm ebenfalls sanktionierte Form desselben Buchstabens (auf Lehrtafeln als „A = A“ notiert). Kein Fehler und keine Abweichung, sondern eine eigene Template-Zeile. Reserviert: Variante 100 = Laufform.
Laufform — die aus echten Wortvorkommen gemessene Form eines
Buchstabens, wie er im fließenden Wort wirklich aussieht (breiter,
geneigter, verformter als die isolierte Tafelform). Sie liegt als
Template-Variante 100 und wird nur in fließenden Läufen benutzt.
Technisch: LAUFFORM_VARIANT = 100 (core/database/models.py),
Composer-Zugriff über laufform_by_key; entsteht als Ableitung aus
den Aggregaten via POST /hands/{id}/aggregates/apply-laufform.
→ handmodell-stufenplan.md H1
Laufform-Lücke — der Zustand eines Glyphen OHNE gespeicherte
Laufform-Variante: die Komposition setzt die rohe Chart-Form ein, und
die Schicht, die per Architektur die Hand-Breite trägt, schweigt.
Stand aug19: 15 der 34 Fixture-Glyphen der Sütterlin-1922-Root
(alle Versalien, dazu ae · b · f · k · s · ue · v) — der aug19
diagnostizierte Haupt-Anteil der „Karten-Form-Decke" der Lotse-Route
(G-Kopf, W-Apexe, k-Kringel liegen alle in der Lücke). Technisch:
Glyph ohne variant=100-Zeile; Lücken-Schluss-Arm LF1 →
messjournal.md §14 („Laufform LF1")
Endblende (Laufform) — die Chart-Rückblendung an den FREIEN
STRICHENDEN einer Laufform-Zeile: über ein Bogen-Fenster W vom
Strichende blendet die Zeile zur Chart-Geometrie zurück, starr am
Fensterrand angehängt (eine rein verschobene Laufform bleibt
Fixpunkt). Zwei Modi: full (LF5, der ganze Rest) und transverse
(LF6, nur der Quer-Anteil zur Chart-Endrichtung — der Längs-Anteil ist
die Ausdehnung der Hand). Anlass: die gefitteten Endanker driften zur
Nachbar-Tinte (t-Anker 0 zum Kringel, K-Endanker auf den Anstrich des
u), und die Grammatik liest ihre Tangenten genau dort. Beide Modi
am Wort-Lineal verworfen (aug29): bei gut belegten Buchstaben sind
die Laufform-Enden die Hand, nicht Drift. Technisch:
core/laufform.py::blend_stroke_ends, Knopf LAUFFORM_END_WINDOW
(0 = aus), Stempel trace_meta.laufform.end_window/end_mode;
Kandidaten-Karten: tools/laufform/endblend.py → messjournal.md
§14 („Laufform LF5"/„LF6"), Rettungswege tintenfolger.md §7.9
Prior-Landerichtung — die Regel-Idee (Übergänge J1, aug29),
dass die Grammatik B's LANDErichtung (Klassen-Entscheidung
Align/Flanke/Sameslant/Ritt, Steigung der Pass-through-Linie) am
ersten Zug der CHART-Zeile misst, wenn ein Slot seine Laufform
rendert — die Geometrie bleibt Laufform, nur die Richtung kommt vom
Duktus-Prior. Gemessen (a) grün (−0,0010), aber die Zielstelle (n→t)
unverändert, weil die Kopplung das t nicht erreicht
(ALIGN_MAX_ENTRY_Y, Haken-Segment im Kandidaten-Scan) — nicht
adoptiert, wird in J2 („Anstrich-Verlängerung in den Schaft")
mitgemessen. → messjournal.md §14 („Übergänge J1"/„J2")
Kopf-Gate (Laufform) — die dritte Prüfung des Zeilen-Gates (§14
LF9, aug29): der KOPF einer Laufform-Zeile — die Landerichtung ihres
ersten Zugs über dasselbe Bogenfenster, mit dem die Übergangs-Grammatik
landet (TANGENT_WINDOW_UNITS), gemessen auf der GERENDERTEN
Mittellinie (die Anker-Polylinie liest die dichten, eingerollten
Kapitalen-Köpfe bis 33° falsch) — darf die Richtung der Tafelzeile um
höchstens LAUFFORM_HEAD_DEVIATION_MAX = 15° verlassen, kein Override.
τ ist aus der Doktrin abgeleitet, nicht aus den Daten: das halbe
Align-Band (25–55°) der Grammatik — ein Kopf, der weiter abdreht,
ändert die Übergangsklasse, die die Grammatik an der Landung
entscheidet (J1-Befund), und widerspricht dem, was die Kanonisierung
verspricht („the tangents stay": die Zeile trägt die Eintrittstangente
der Tafel als Metadatum). Gefunden am Korb-#7-t: Anker 0 der n=4-Zeile
liegt RECHTS von Anker 1, der Kopf startet mit 104° gegen 37° Tafel —
der Rückwärts-Schlenker im Wort, den das Sprung-Gate nicht sieht (t
2,11 < 2,95). Auf der Root vom 29.08.: t 46°, E 48°, K 41°, f 28°, v
27°, k 17° über τ (alle am 29.08. in Prod gelöscht), m mit 14,9° die
knappste vertraute Zeile darunter.
Technisch: core/laufform.py (head_deviation, head_gate),
Skip-Grund head_deviation mit head_deviation/head_max,
Inventar-Spalte head° → messjournal.md §14 („Laufform LF9")
Glätte-Sensor — die Kennzahl, die das Zittern einer Laufform-Zeile
zum ersten Mal benennt (§14 LF11, sep02): wie oft die GERENDERTE
Mittellinie ihre Krümmung umkehrt, je x-Höhe Bogenlänge. Jeder Zug wird
auf 0,02-xh-Schritte resampelt (ein Drittel des Nib-Radius), der
Drehwinkel je Schritt gebildet und jeder Vorzeichenwechsel gezählt, bei
dem mindestens eine der beiden Drehungen über 3° liegt — das trennt die
Zacke vom Rundungsrauschen. Federabsätze zählen nie, wie beim
Sprung-Gate. Der Sensor musste gebaut werden, weil KEIN eingefrorenes
Lineal die Größe sieht: Wort-Bench und Tintenfolger resampeln den
Zickzack weg, bevor sie werten — die Zeilen der Root zackten mit 6,9
gegen 0,2 der Tafel, ohne dass eine Zahl je darauf reagiert hätte.
Berichtsspalte, kein Gate. Technisch: core/laufform.py
(zigzag_rate, smoothness_gap, ZIGZAG_STEP_UNITS,
ZIGZAG_TURN_MIN_DEG), Inventar-Spalte zig →
messjournal.md §14 („Laufform LF11")
Spline-Basis-Median — die glatte Zwillingsform des Per-Anker-Medians
(§14 LF11, sep02): statt jeden der 120 Anker einzeln zu medianisieren
— wobei nichts im Modell Nachbarn koppelt und das Eigenrauschen des
Schätzers als Zickzack in die geschriebene Zeile durchschlägt — wird
jedes Vorkommen je Zug per kleinster Quadrate auf eine geklammerte
kubische B-Spline projiziert, der Median über die KONTROLLPUNKTE
genommen und an den Ankerparametern der Tafel zurück ausgewertet.
Gemeinsamer Parameter ist die Bogenlänge der TAFELZEILE (damit alle
Vorkommen auf dieselbe Basis projizieren), die Ecken des Duktus-Priors
werden Knoten der Vielfachheit 3 (damit eine Ecke Ecke bleibt), und ein
Zug ohne Platz für die Basis behält den Per-Anker-Median und sagt es.
Ein Knopf: der Knotenabstand Δs; gemessen auf {0,08 · 0,16 · 0,32} xh,
bestanden hat 0,16. Technisch:
core/aggregate.py::spline_basis_median, Kandidaten-Karten trocken über
tools/laufform/smoothrow.py; aggregate_instances bleibt bis zu einer
Adoption beim Per-Anker-Median → messjournal.md §14 („Laufform LF11")
Schleifenbereich — der Anker-Indexbereich [start, end), über den
eine TAFELZEILE eine Schleife schließt: gelesen an den Selbstschnitten
ihrer gerenderten Mittellinie (der grobe Ankerzug übersieht eine
Schleife, die die gezeichnete Spline schließt) und über die Bogenlänge
auf die Anker zurückgerechnet — nicht über die Nähe, denn an einer
Kreuzung liegen die zwei Stränge nebeneinander und ein
Nächster-Punkt-Suchlauf verwechselt sie. Er wird an der TAFEL bestimmt,
aus demselben Grund, aus dem die Spline-Basis ihren Parameter dort
holt: nur ein vorkommens-UNABHÄNGIGER Bereich ist einer, auf dem ein
Median über den Stapel definiert ist. Ein zweimal gekreuztes Segment
begrenzt drei Gebiete, nicht zwei — das dritte ist der Kringel des p
—, überlappende Bereiche werden zur Hülle verschmolzen (eine Schleife,
eine Korrektur). Technisch: core/aggregate.py::loop_ranges →
messjournal.md §14 („Laufform LF13")
Schleifen-Registrierung · schleifen-treue Zeile — der Schritt vor
dem Median, der verhindert, dass Form gegen LAGE verrechnet wird (§14
LF13, sep06; Rettungsweg (5) der Kringel-Diagnose). Ein elementweiser
Median über Kurven, deren Schleifen sich uneins sind — wo sie sitzen,
wie groß sie sind, wo entlang der Schleife welcher Anker gelandet ist
—, liefert eine Schleife, die enger ist als jede einzelne. Die
Registrierung holt jedes Vorkommen je Schleifenbereich per ÄHNLICHKEIT
auf die Median-Schleife des Stapels (die Verschiebung auf den
Median-Schwerpunkt, der isotrope Faktor auf den Median-Radius), mit
Gewicht 1 auf der Schleife und linearem Auslauf über ein
Bogenlängen-Fenster daneben — die Form von blend_stroke_ends.
Median-Verschiebung 0 und Median-Faktor 1 per Konstruktion: die
Registrierung führt keinen freien Parameter und kein Ziel außerhalb des
Stapels ein, die Zeile bleibt, wo sie war, und die Schleife behält den
Median-RADIUS des Stapels. Eine Schranke auf die ÖFFNUNGSWEITE ist das
nicht — der Radius ist ein skalarer Stellvertreter, und der
nachfolgende punktweise Median kann bei anisotrop uneinigen Schleifen
ein Loch erzeugen, das weiter ist als jedes einzelne Vorkommen; auf der
sep05-Wurzel steht das Z 0,034 xh über seinem Vorkommens-Median, das
w 0,024, und den gespeicherten Zeilen passiert dasselbe. Es ist also
eine Eigenschaft des elementweisen Medians, nicht dieses Schritts.
Gemessen
und NICHT adoptiert (Gates (a) und (c) rot); Schalter
LAUFFORM_LOOP_WINDOW, Default 0 = aus und byte-gleich. Technisch:
core/aggregate.py::align_loops / loop_faithful_median,
Kandidaten-Karten über tools/laufform/smoothrow.py --loop-window →
messjournal.md §14 („Laufform LF13")
Form-Abstand (Laufform) — der vierte, GEMESSENE und (Stand
sep01) NICHT adoptierte Sensor der Zeilen-Gate-Familie (§14 LF10):
wie weit eine Laufform-Zeile die Bahn ihrer Tafelzeile verlässt, je
Anker in Nib-Radien der Tafel. Beide Zeilen werden mit dem Sample-Plan
der Tafel gerendert; je Anker der kürzeste Abstand zur gerenderten
Mittellinie DESSELBEN Zugs der Gegenseite, in beide Richtungen getrennt
(Zeile→Tafel, Tafel→Zeile — kein symmetrisches Mittel); Gate-Größe das
schlechtere p90 der beiden Richtungen (form_p90), Median und Maximum
als Empfindlichkeitsprüfungen, dazu der index-weise Abstand
|Zeile_i − Tafel_i| (er trägt den Längs-Anteil, den LF5/LF6 als Breite
der Hand bestätigt haben; der Linien-Abstand ist gegen Gleiten entlang
des Zugs blind, absichtlich). Gebaut für die Form-Drift OHNE Sprung
(v, E, P, k), die das Sprung-Gate durchlässt. Gemessen sep01 auf dem
Neuexport: τ_form = 1,40 (w — die enger sitzende Schlussschleife, Breite
der Hand), die Referenzzeile P liegt mit 1,01 darunter — der Sensor
misst Geometrie treu, die Abweichung des P liegt im Band der vertrauten
Zeilen; was das Auge an P liest, ist kein Abstandsbetrag. Bleibt
Berichts-Spalte der Bestandsaufnahme, kein Schreibpfad liest sie.
Technisch: core/laufform.py::form_distance, Inventar-Spalten
form/f-med/f-max + τ_form, --laufform DATEI.json für
Kandidaten-Zeilen → messjournal.md §14 („Laufform LF10"),
tintenfolger.md §7.9
Zeilen-Gate (Laufform) — die drei Prüfungen, die eine
Laufform-Zeile bestehen muss, bevor sie in den Schreibweg kommt (§14
LF7/LF8/LF9, aug29), auf BEIDEN Schreibpfaden (manueller PUT …/laufform wie apply-laufform): (1) der Boden
LAUFFORM_MIN_OCCURRENCES (n ≥ 3), nur durch die ausdrückliche
Autor-Aussage ?min_occurrences=N in der Anfrage zu senken; (2) das
Sprung-Gate: die Sprung-Ratio der Zeile (anchor_spike_ratio,
„Anker im leeren Papier" — derselbe Detektor wie am Ernte-Gate, dort
auf dem Einzelfit) darf LAUFFORM_SPIKE_RATIO_MAX = 2,95 nicht
übersteigen, kein Override; (3) das Kopf-Gate (eigener Eintrag):
der Kopf der Zeile darf die Landerichtung der Tafel um höchstens 15°
verlassen. Doktrin-Satz dazu: ein Wort-Gewinn am
Pixel-Lineal ist KEIN Aufnahmekriterium für eine Zeile — so kam das
n=1-K in den Schreibweg. Vorher gemessen und verworfen: die
Natürlichkeits-Lücke N(Chart) − N(Zeile) über die §5-Terme (LF7 — sie
verfehlt das K, weil der Anker-Median-Jitter der vertrauten Zeilen den
Glätte-Term stärker trifft als große Wellen); sie bleibt Berichts-Spalte
der Bestandsaufnahme (tools/laufform/inventory.py). τ ist
datengetrieben: Maximum der vertrauten Zeilen (n ≥ 3) auf der Root,
aufgerundet — nie von Hand gesetzt. Der Boden galt bis sep04 nur im
Moment des Schreibens: eine Karte durfte eine zu dünne Zeile bis vor den
PUT tragen, und eine Zeile, die einmal drin war, prüfte niemand nach.
Seit LF12 zieht ihn tools/laufform/smoothrow.py --floor schon beim
Bauen der Karte, und die Bestandsaufnahme flaggt ihn („unter dem Boden")
— gefunden hat die Lücke der Audit vom 2026-09-02 (Befund 35).
Technisch: core/laufform.py
(anchor_spike_ratio, spike_gate, row_naturalness), Skip-Grund
anchor_spike mit spike_ratio/spike_max → messjournal.md §14
(„Laufform LF7"/„LF8"/„LF12")
Schreib-Karte — die Laufform-Kandidaten-Karte in GENAU der
Gestalt, die ein DB-Write erzeugen würde: die zu schreibenden Zeilen
über der eingefrorenen Root, mit den Autor-Ausschlüssen (aug26:
h behält seine Zeile, W bekommt keine, G/h-Chart-Fallback heißt
„keine Zeile"), gemessen auf allen Gates, bevor eine Zeile die DB
sieht. Der Begriff trennt „die Karte, die gemessen wurde" (LF3b
aug19, nicht mehr auf der Platte) von „der Karte, die geschrieben
wird" — eine neu gerechnete Karte ist nicht automatisch die
freigegebene. Technisch: gepatchte Fixture-Root
(templates_laufform.json ersetzt, sonst byte-gleich) + Payload
{glyph_key: {anchors, n_occurrences}} für PUT …/templates/{key}/laufform → messjournal.md §14 („Laufform
LF3b-W")
Instance (Vorkommen / occurrence) — ein beobachtetes Auftreten
einer Glyphe auf einer Vorlage, samt seinem Fit-Ergebnis. Die Rohdaten der
Statistik: viele Instanzen ergeben ein Aggregat. Tabelle instances;
Schwestern: pair_instances (ein sezierter Übergang) und word_instances
(ein nachgefahrenes ganzes Wort). Vorkommen wirken nie direkt auf das
Rendering.
Aggregat — die verdichtete Statistik einer Hand je
(glyph_key, variant): Median-Anker (= die Laufform-Quelle), MAD-Hülle,
gepoolte Kennzahlen, n_instances. Tabelle aggregates, Rechenkern
core/aggregate.py, Neuaufbau über POST /hands/{id}/aggregates/rebuild.
Vorkommensschranke (LAUFFORM_MIN_OCCURRENCES = 3) — die Mindestzahl
an Vorkommen, aus denen ein Median in den Schreibpfad übernommen werden
darf. Keine Geschmacksgrenze, sondern die Stelle, ab der der Median
überhaupt arbeitet: bei n = 2 ist er das Mittel der beiden, ein einzelner
ausgerissener Fit-Anker landet also mit halber Amplitude in der
geschriebenen Form — genau so bekam das Sütterlin-S seinen Zacken oben
rechts. apply-laufform erzwingt die Schranke serverseitig (Skip-Grund
below_min_occurrences, absenkbar über ?min_occurrences=); das Sehen
eines dünnen Medians bleibt erlaubt, dafür steht die Aggregat-Schranke
min_n getrennt daneben (Standard 1, Issue #273). Doktrin wie beim
Auftragskorb-Protokoll: eine Regel, die die API durchsetzt, statt sie
einem Client zu glauben. Spiegel im SPA: LOW_N in laufformPreview.ts.
Paar-Aggregat (pair_aggregates) — dasselbe eine Ebene höher, je
(hand, left_key, right_key): Median-Versatz und per-Punkt-Median der
gemessenen Verbindungslinien plus gepoolte QC. Bewusst ohne
Apply-Schritt — die Paar-Statistik ist rein lesend, das Rendering rührt
sie nicht an. kind wird dabei gepoolt: ein Wort-Join (Abb. 19) und
ein Paar-Drill (Abb. 20) landen in EINER Aggregat-Zeile, weil beide
derselbe Übergang derselben Hand sind; das Wort-/Paar-Platten-Histogramm
bleibt in der gepoolten QC stehen, damit die Mischung sichtbar ist.
Migration 0023. → handmodell-stufenplan.md H2
glyph_key — der Schlüssel einer Glyphe als bare Basis: a, longs,
ch. Seit Redesign R2 ohne Positions-Suffix (früher a-medial).
Slot — eine Position im komponierten Wort. Das Shaping wandelt Text in
eine geordnete Liste von Slots (je ein glyph_key plus Render-Kontext);
Vorkommen, Segment-Bewertungen und Übergänge werden über
(specimen_id, slot) zugeordnet.
Shaping — Text → geordnete Glyph-Schlüssel: Lang-s-/Rund-s-Regel,
Fugen-Marker, Ligatur-Erkennung, Positionszuweisung, Ziffern und
Satzzeichen als nicht verbindende Glyphen — dazu der Ligatur-Zerfall
als Rückfall, wenn der Canonical eines Clusters fehlt: die
Teilbuchstaben erben die Wortposition des Clusters (erster initial,
letzter final, dazwischen medial), ß bleibt atomar
(core/shaping.py::decompose_ligature_slot — nur noch Python, der
TS-Zwilling hat seinen Zerfall mit dem serverseitigen Compose-Umzug
abgegeben). Das Shaping existiert zweimal —
core/shaping.py (maßgeblich) und app/src/domain/shaping.ts (nur noch
fürs Quiz); ein gemeinsames Fixture hält beide synchron.
Komposition (compose) — Slots → fertiges Wort: Buchstaben auf die
Grundlinie setzen, Abstände wählen, Übergänge erzeugen, Diakritika
zurückstellen. core/compose.py ist die einzige Kompositionsquelle,
gepinnt durch das goldene Paritäts-Fixture tests/fixtures/compose_golden.json.gz.
Wort-Tintenlücke (word ink gap) — die Regel, dass der Abstand
zwischen zwei Wörtern zwischen der Tinte gemessen wird und nicht
zwischen den Ankern. Der Wortvorschub SPACE_ADV rückt nur den Cursor
(Ende des Endstrichs → Eintrittspunkt des nächsten Buchstabens) weiter;
mehrere Sütterlin-Majuskeln tragen ihren Bogen aber weit LINKS ihres
eigenen Ursprungs (K −1,64 · C −1,42 · F −1,16 · G/Q/O/A ≈ −0,8 ·
I −0,45 · X −0,18 xh, im Join-Band gemessen), und ein Wortende auf w/v
lässt seinen Bogen rechts des Cursors stehen. „Die Federprobe“ schrieb
das F deshalb IN das „Die“ hinein (Autorenmeldung 2026-09-05). Der
Composer nimmt am Wortanfang darum den weiter rechts liegenden der
beiden Werte: Anker-Vorschub oder Tintenboden. Der Boden 0,43 xh liegt
unter jeder Grenze, die der Anker-Vorschub heute schon breit genug
schreibt (die engste ist 0,4395 nach einem End-t, der Regelfall 0,4777)
— nur die Grenzen darunter bewegen sich.
Technisch: core/compose.py::WORD_INK_GAP neben SPACE_ADV,
Guards in tests/test_compose_spacing.py. → write-api.md
Übergang · Konnektor (connector) — der Verbindungsstrich zwischen
zwei Buchstaben. Doktrin: „Übergänge sind Konsequenz, keine Daten“ —
sie werden aus exit-Tangente des linken und entry-Tangente des rechten
Buchstabens erzeugt, nicht gesammelt. Sonst bräuchte man eine
Bigramm-Datenbank für alle ~900 Buchstabenkombinationen.
→ architektur.md §4
Übergangs-Generator (§4-Generator) — die erzeugende Logik dahinter:
eine kubische Bézierkurve zwischen Austritt und Eintritt, mit
Klassenregeln für die Sonderfälle. Er ist und bleibt der Default.
Technisch: CONNECT_SAMPLES = 24 Stützpunkte, Guards für hohe Exits,
Bogen-Exits, rückwärts zeigende Exits.
Klassenregel — eine Regel, die für eine ganze Klasse von Übergängen
gilt (alle d-Schleifen-Exits, alle Deckstrich-Bögen, alle r-Arme). Das
Leitprinzip der Optimierung: eine Klassenregel hebt viele Paare, ein
Override repariert eine Stelle. Die Klassen sind im Code als
Buchstabenmengen ausbuchstabiert, und diese Konstanten sind die Quelle —
die Liste hier ist ihr Inhaltsverzeichnis (core/compose.py, Stand
2026-09-04: 15 positive Mengen plus eine Ausschlussmenge):
| Klasse | Konstante | gilt für |
|---|---|---|
| Bowl-Exit-Tuck | BOWL_EXIT_TUCK_BASES |
b · c · d · o |
| Arkaden-Eintritt | ARCADE_ENTRY_BASES |
m · n |
| hohe Kopplung | HIGH_COUPLE_BASES |
e · a · o · c · d · g · q · ae · oe |
| Oberlängen-Neigung | ASCENDER_LEAN_BASES |
d |
| Schleifen-Exit | LOOP_EXIT_BASES |
d · s |
| Säulenabgang (opt-in) | STEM_DEPART_BASES |
d |
| Kringel-Exit | KRINGEL_EXIT_BASES |
b · o · B |
| Arm-Fusion | ARM_FUSE_BASES |
die hohe Kopplung + r · i |
| gleichschräge Kopplung | SAMESLANT_COUPLE_BASES |
n · m · i · u |
| Unterlängen-Ritt | DESCENDER_RIDE_BASES |
c · t |
| Bar-Exit | BAR_EXIT_BASES |
t · f |
| Deckbogen-Austritt | COVER_ARCADE_EXIT_BASES |
o · b · v · w |
| Deckbogen-Eintritt | COVER_ARCADE_ENTRY_BASES |
n · m · i · r |
| Schleife in Rundform | LOOP_ROUND_ENTRY_BASES |
e · a · o |
| Restart-Klasse | CAP_RESTART_BASES |
S · O · K · P |
Austritts-Trim (adoptiert sep06) |
EXIT_TRIM_EXCLUDED_BASES (Ausschluss) |
alle Basen AUSSER Schleifen-, Kringel- und Bar-Exit |
Dazu die Klassen ohne eigene Buchstabenmenge, weil ihre Bedingung geometrisch ist: Girlande · Gabel-Join · Cusp-Connector · Kapital-Übergabe · Arkaden-Diagonale · Apex-Übergabe.
Apex-Übergabe (apex_handover, APEX_HANDOVER_MIN_RISE /
APEX_HANDOVER_MAX_APPROACH_DEG) — die Klassenregel für den langen
ungeschlungenen Anstrich: ein Buchstabe, dessen erster Zug in EINEM
Strich vom tiefen Fuß bis in die Oberlänge steigt, ohne dabei eine
Schleife zu schreiben, übergibt den Übergang in gebundener Stellung an
seinem Scheitel statt an seinem Anstrichfuß — der Verbinder ist die
Gerade dorthin, der gespeicherte Anstrich darunter fällt weg
(Centerline und Silhouette, über die ENTRY_COUPLE_Y-Maschinerie). Die
Klasse ist geometrisch und nicht als Buchstabenmenge ausbuchstabiert,
damit sie auf einer Laufform-Zeile und auf einer anderen Hand ebenso
greift: gemessen auf der Tafel 1922 fallen t, ſ, k und ß hinein
(Hub 1,171–1,296 gegen 0,467 für den größten Nichtmitglied-Anstrich;
Anlauf in den Scheitel ≤ 98° gegen ≥ 163° für die geschlungenen
Oberlängen h/l/b/f). Umsetzung des Autor-Entscheids A4 zu Befund 33 des
Audits — gemessen sep04 und verworfen (Paar-Lineal +0,002420,
Verdopplungen 13 → 17); der Schalter steht standardmäßig aus, die
Zahlen und die Rettungswege stehen in messjournal.md §14 „Übergänge
J5". Nicht zu verwechseln mit der Arm-Fusion, die ebenfalls am
Scheitel koppelt, aber an dem des kurzen Deckstrich-Kamms.
Säulenabgang (stem_depart, STEM_DEPART_BASES,
STEM_DEPART_Y) — die Exit-Klasse des d, und die Umsetzung von
Weg (b) des Auslauf-Entscheids A4: der Übergang wird GENERIERT statt
gespeichert. Nach der Schleifenrückkehr hört der Übergang nicht an der
Selbstkreuzung auf (die die Tafel bei 1,17 schreibt), sondern reitet
die Säule des d — dessen eigene, schon geschriebene Tinte — bis auf
die gemessene Abgangshöhe 0,96 hinunter und startet dort. 0,96 ist der
Median der 17 von pairlab verfolgten Platten-Abgänge (Band 0,824–1,118,
elf verschiedene Folger); dass er über alle Folger konstant ist, ist
das Argument für den Generator und gegen eine Variantentrennung
verbunden/terminal — eine gespeicherte Bigramm-Tabelle müsste elf
Folger aufzählen, um dasselbe zu sagen. Gemessen sep04: alle Gates
grün (Wörter −0,000100 · Paare −0,001441, Abgangshöhe 10/10 und 8/8
im Platten-Band); der Schalter steht bis zum Autor-Ja trotzdem aus, weil
ein geänderter compose_word-Default jede öffentliche
/write/word-Antwort ändert. Was der Säulenabgang NICHT repariert: die
Kreuzungshöhe selbst (Platte gebunden 0,968, wortfinal 1,211; Tafel
starr 1,176) ist Buchstabenform und bleibt der Wizard-Fall.
Restart-Klasse (CAP_RESTART_BASES) — die Versalien, deren
Verbinder mit einem vorangestellten Rückzug beginnt: die Feder fährt
den eigenen Bogen zurück und setzt an der Grundlinie an wie zu einem
frischen Anstrich, statt vom Duktus-Ende aus weiterzulaufen. Tafelform
für S · O · K · P. Wer in der Klasse steckt, ist eine gemessene
Aussage über die Vorlage, keine Vereinfachung: das B hat sie
aug30 verlassen, weil sein autorisierter Duktus auf Mittellinienhöhe
in einem steigenden Abgang endet — der Retrace lief diese Fortsetzung
sinnlos zurück (Korb #8). Die Naht-Winkel-Spalte zählt Verbinder dieser
Klasse aus und meldet sie getrennt, weil ihr „Abgang“ eine gewollte
180°-Kehre ist.
Technisch: core/compose.py::CAP_RESTART_BASES, cap_retrace in
compose_word → messjournal.md §14 „Übergänge Korb-Runde aug30“
Vorschub-Kalibrierung (advance calibration) — die Runde, in der
die Abstände zwischen zwei Buchstaben nicht mehr geraten, sondern aus
den gemessenen Joins der Platte nachgezogen wurden: 218 sezierte
Übergänge der Worttafel liefern je Klasse, wie weit die Hand vorschiebt,
und die Klassenregeln bekommen diese Werte statt gewählter Konstanten.
Adoptiert wurden vier Stücke (Bowl-Tuck · w/v-Rückwärts ·
longs-Ausnahme · Balken-Steigung) plus der align/nested-Floor der
Folgerunde; die „Arkaden-Luft“ fiel als Beleg-Varianz durch. Die Runde
ist der Grund, warum das Wort-Lineal von 0,110983 auf 0,108091 fiel —
der größte Einzelsprung der Kompositions-Arbeit.
Technisch: core/compose.py (Welle 2, PR #361/#363) →
messjournal.md §14 „Welle 2 · P1“ und „Welle 2 · P2“
Girlande — die tief durchhängende Verbindung, die von einem Exit in
den nächsten Arkaden-Eintritt (n, m, i, u) fällt — das rhythmische
Grundmuster der verbundenen Schrift.
Technisch: GARLAND_* in core/compose.py.
Kringel-Exit — die Klassenregel für Buchstaben, deren Bogen in der
kleinen Schluss-Schleife (dem Kringel) endet und deren Chartzelle daraus
noch einen steigenden Koppel-Stub herausschlägt (b, o) — Tafelform wie
t's langer Balken. Im gebundenen Kontext wird der Stub am Self-Crossing
der Schleife (dem Knoten, ~0,77 xh) gekappt — Mittellinie UND Silhouette —
und der Übergang verlässt den Kringel nahezu eben; ein Knoten-Abgang
zählt dabei nicht als r-Arm (keine Arm-Fusion). Wortfinal bleibt die
Chartform vollständig. Anlass: Korb #5 („Säbel" b→e — der Generator
setzte über dem Kringel einen zweiten Scheitel, den die Platte nie
schreibt).
Technisch: KRINGEL_EXIT_BASES + _last_ink_crossing in
core/compose.py.
Austritts-Trim (exit_trim) — die A-seitige Spiegelregel zum
entry_trim: der Sägezahn-Austritt von e/n/m/u/i behält in der Chartzelle
einen Abschluss-Flick (die letzten 0,05 xh drehen beim e von 45° auf
9° ab, beim i sogar nach unten), während der Composer seine
Austrittsrichtung über 0,12 xh liest und den Verbinder daran ausrichtet —
die Tinte am Saum läuft dadurch 13–42° flacher als der abgehende Strich
(Audit-Befund 19 vom 2026-09-02, sichtbar am Naht-Winkel). Die Regel
schneidet den Stummel von der Spitze her bis zu der Stelle zurück, an der
die Gerade zum unveränderten Kopplungspunkt die eigene Laufrichtung
des Stummels fortsetzt, und zeichnet den Übergang als eben diese Gerade —
Mittellinie UND Silhouette, Boden der Suche ist die Fußwende
(das letzte lokale y-Minimum des Zuges; der Buchstabenkörper wird nie
angeschnitten). Anders als Schleifen-, Kringel- und Balken-Exit greift sie
NACH der Platzierung, damit die Spationierung als experimentelle Kontrolle
unberührt bleibt. Status: ADOPTIERT, Standard AN seit 2026-09-06
(Autor-Entscheid A37) — der Weg dahin ging über beide Instrumente: am
Lineal fiel der Arm (dconn gegen die dissezierten Hand-Verbindungen sank
nur in 20 %, artefaktbereinigt 51 %, statt der geforderten 60 %; Gate (b)
rot, messjournal.md §14 „Übergänge J4/J4b"), und die blinde Wortrunde 5
entschied ihn mit 34 : 2 für den Trim (§14 „Übergänge J4 sep06"). Preis
und Nutzen sind beziffert: seam_dep +7,59° → −0,70° (absolut 12,67 →
2,30) gegen word_loss +0,000581, Paare byte-gleich. Ein Lauf mit
--no-exit-trim ist seither die pre-adoption Basis, ein Arm wie jeder
andere.
Technisch: EXIT_TRIM_WINDOW, EXIT_TRIM_TOL_DEG,
EXIT_TRIM_MIN_KINK_DEG, _exit_trim_index, _cut_exit_stub in
core/compose.py; Bench-Schalter --no-exit-trim.
Fußwende — das letzte lokale y-Minimum eines Zuges: die Stelle, an der
die Feder ihren Abstrich beendet und in den Austritts-Stummel hochdreht.
Strukturelle Untergrenze des Austritts-Trims — weiter zurück wird nie
geschnitten, sonst verlöre der Buchstabe seinen Körper statt seiner
Tafelform.
Technisch: _foot_turn_index in core/compose.py (nicht zu verwechseln
mit _loop_return_foot, dem Schleifenfuß des Schleifen-Exits).
Nahtverhandlung (seam_negotiation, Übergänge J6) — die Regel, die
den Naht-Winkel nicht mehr einer Seite überlässt: an jedem Ende eines
generierten Übergangs lesen Buchstabe und Verbinder ihre Richtung über
dieselben 0,05 xh und drehen beide auf den Kompromisswinkel zu — der
Buchstabe höchstens 8° über seine letzten bzw. ersten 0,3 xh, der Verbinder
den REST über höchstens 45 % seines eigenen Bogens. Beide zeigen danach über
dieses Fenster in dieselbe Richtung (beim Mittelwert, solange der Deckel die
halbe Uneinigkeit deckt, sonst bei der gedeckelten Richtung des Buchstabens);
gemeint ist also die Richtung auf der Augen-Skala, nicht die exakte
Endsegment-Tangente — was auf dieser feineren Skala übrig bleibt, misst Gate
(a1) des J6-Eintrags. Was der Deckel nicht deckt, trägt der Verbinder als
glatte Krümmung statt als Knick. Anlass ist die Autorenregel vom
2026-09-06 („in der letzten Kurve wird etwas weiter gedreht oder im
Eingang, so dass sich beide Seiten auf einen Kompromiss einigen"). Gedreht
wird als ebener Twist um den Nahtpunkt — Mittellinie und Silhouette
mit demselben Feld, weil eine über die Bogenlänge gerechnete Zuordnung die
Silhouette dort zerreißt, wo ein Zug seine eigene Tinte kreuzt (der
Schleifenfuß des d). Der Nahtpunkt selbst ist der Drehpunkt: keine
Kopplungshöhe und keine Platzierung bewegt sich, was diese Regel von den
gescheiterten P3-Eintrittsregeln unterscheidet. Über 45° Uneinigkeit hält
sie die Hände weg — das ist eine Kehre, die der Duktus schreibt.
Status: opt-in, Standard aus, nicht adoptiert (messjournal.md §14
„Übergänge J6").
Technisch: SEAM_NEGOTIATE_WINDOW, SEAM_NEGOTIATE_CAP_DEG,
SEAM_NEGOTIATE_BLEND, SEAM_MAX_JUMP_DEG, SEAM_CONNECTOR_BLEND_RATIO,
_negotiate_seam, _seam_shares, _twist_about_seam in
core/compose.py; Bench-Schalter --seam-negotiation
(+ --seam-negotiation-max-jump für den engeren Arm J6b), Runden-Schalter
gleichen Namens an tools/humanbench/wordarm.py.
Kompromisswinkel — der Winkel, auf den sich die beiden Enden an einer
Naht einigen: der zirkuläre Mittelwert der beiden Richtungen, die dort
zusammentreffen. Kann eine Seite sich nicht bewegen (ein Zug, der kürzer
ist als die Blendlänge, würde sonst sein anderes Ende wegschwenken; ein
Verbinder, der zu kurz ist, um eine Drehung zu tragen), nimmt die andere
den ganzen Betrag — gedeckelt bleibt nur der Buchstabe. Der Name ist
wörtlich der des Autors; sein Zusatz „ob es wirklich 30, 40 oder
vielleicht 35 Grad ist, ist nicht so wichtig" ist die Begründung dafür,
dass der Deckel eine Schranke und keine Kalibrierung ist.
Technisch: _seam_shares in core/compose.py.
Bowl-Exit-Tuck — die klassenbewusste Clearance nach einem
geschlossenen Rundkörper-Ausgang (b/c/d/o): die Hand rückt den
Folgebuchstaben an den Kessel heran (gemessen +0,20 xh Überschuss der
einheitlichen Clearance über 218 sezierte Joins, b +0,42 · o +0,30 ·
c +0,25 · d +0,12), die Klassen-Clearance erlaubt deshalb BERÜHRUNG
der Tintenspalten (0,0) — bewusst nicht die volle gemessene
Überlappung (−0,06), die im Wortkontext kollidierte (Welle 2 · P1,
aug15: der gebundene Tuck hält −0,018 pair_loss bei neutralen
Wörtern). Schwester-Befund, ehrlich NICHT adoptiert: die
Arkaden-Luft (n/m brauchen laut Dissektion +0,18 mehr Raum, die
Wordbench widerspricht).
Technisch: BOWL_EXIT_TUCK_BASES/BOWL_EXIT_CLEARANCE in
core/compose.py; Messung messjournal.md §14 „Welle 2 · P1".
Nib-gekoppelte Clearance — jede Tinten-Clearance der Platzierung
nicht als x-Höhen-Betrag gelesen, sondern in Nib-Radien der Feder,
die gerade schreibt: scale = max(1; half / 0,07251), wobei 0,07251 die
chart-gepoolte Halbbreite ist, AN der jede dieser Konstanten kalibriert
wurde. Der Gedanke: eine schwerere Feder füllt denselben Skelett-Abstand
mit mehr Tinte, ein fester x-Höhen-Betrag schrumpft also in Nib-Radien,
sobald die Feder wächst. Die Klemmung nach unten ist Absicht — was eine
LEICHTERE Feder mit dem Abstandsrhythmus der Hand tun sollte, hat nie
jemand gemessen. Vorregistriert, gemessen und NICHT adoptiert
(sep05): bei Halbbreite 0,097 bleiben die Gleichzug-Verdopplungen bei
21, weil acht der neun neuen Stellen der Deckungs-Join NEBEN dem Körper
sind, in den er landet — Platzierung verschiebt beide gemeinsam —, und
die neunte eine gewollte Arm-Fusion ist, die unter jeder Clearance liegt. Bleibt als
ausgeschalteter Schalter stehen, weil die Regel für einen künftigen
Feder-Wechsel die richtige Form hat.
Technisch: CLEARANCE_REF_HALF + _clearance_scale und der Parameter
nib_clearance von compose_word (core/compose.py), Schalter
--nib-clearance an tools/humanbench/wordarm.py; Messung
messjournal.md §14 „Ink-Clearance an die Feder sep05".
Stamm-Rückpass (versetzt) — die generierte Brücke, mit der die
Komposition den t-Deckstrich OHNE Absetzen anschließt (Welle 1 · K1b,
aug15): vom Stammfuß zurück hinauf zum Balkenstart, um 0,06 xh nach
rechts ausgebuchtet, damit die Strukturzähler ZWEI Pässe sehen — wie
die Hand, deren Aufstrich 0,05–0,07 xh rechts des Abstrichs liegt.
Nur Mittellinie, keine Silhouette (das cap_retrace-Muster); auf dem
outline-gestützten Render-Pfad bleibt die gedruckte Tinte dadurch
unverändert. Der Balkenstrich verliert seinen Lift; der Auslauf
durchsticht Abstrich UND Rückpass, womit unter/mit ihre
Hand-Zählungen erreichen.
Technisch: BAR_RETRACE_BULGE_UNITS (+ _MAX_DX/_MIN_RISE) in
core/compose.py; Messung messjournal.md §14 „Welle 1 · K1b".
Override (Paar-Override, glyph_pairs) — eine für genau ein
Buchstabenpaar hinterlegte, wörtlich übernommene Verbindung, die den
Generator für dieses Paar ersetzt. Bewusst die sparsame Ausnahme: nur
approved-Zeilen erreichen den Composer, links-nach-rechts-Vorrang, und
der Regel-Fix geht immer vor. Migration 0018 (Redesign R3).
Provenance (Herkunft einer Zeile) — woher eine gespeicherte
Geometrie stammt: harvested (vom Ernte-Werkzeug aus einer Vorlage
gezogen) · authored (vom Menschen von Hand gezeichnet/nachgefahren) ·
traced (von der Engine automatisch nachgefahren). Wichtige Regel: eine
authored-Zeile wird von einer neuen Ernte nie überschrieben.
Specimen — eine konkrete Wort- oder Paar-Probe auf einer Vorlage, mit
der gemessen wird. Für Sütterlin: die 63 Wörter der Abb. 19, die 33
Buchstabenpaare der Abb. 20 und — als eigenes Kontext-Set, andere Hand! —
die 106 Wörter der Abb. 22. Vermessen im committeten Sidecar
data/sources/suetterlin-1922/words.json (Rechteck + aus der Tinte
gemessene Grund-/Mittellinie je Zeile).
Registrierung (registration) — das Aufeinanderlegen von gemessenem Ausschnitt und gerechneter Geometrie: Skala aus der gemessenen Lineatur, Translation begrenzt gewählt. Bewusst begrenzt, damit sich ein Experiment nicht durch Verschieben besser rechnen kann.
Render-Kontext (render context) — alles, was ein Render einer Quelle
auflöst, bevor es zeichnet: Stil, Lineatur-Verhältnis, Schräglage,
width_resolver, der quellen-gepoolte Gleichzug-Nib und die gepoolte
Feder. Seit dem Nib-Präzisions-Umbau als eigener admin-gegateter Read
verfügbar — GET /sources/{id}/render-context, unrundet, wo die
öffentlichen /write-Payloads dieselben Zahlen auf vier Dezimalen gerundet
tragen. Sein einziger Zweck: ein serviertes Payload bit-genau offline
reproduzieren zu können (der Fixture-Nachbau, fetch_fixtures.py); das
Manifest-Feld nib_precision ("exact" · "4dp-readback" · "none")
sagt, welche Nib-Quelle ein Fixture-Root bekam, und das Verify-Gate zieht
seine Toleranz daraus. Sein Laufform-Zwilling laufform_precision
("stored" · "reconstructed") sagt, ob der Root die gespeicherten
Variante-100-Zeilen wortwörtlich trägt (Einzeltemplate-GET mit
?variant=, Issue #311) oder den Aggregat-Nachbau, auf den ein älteres
Deployment erkennbar zurückfällt. → write-api.md
Ernte (harvest) — der Lauf, der aus den eingefrorenen Vorlagen
Messergebnisse macht und sie als Entwürfe über die admin-gegatete API
schreibt: tools/laufform/harvest.py (Buchstaben-Vorkommen + Laufformen +
Wortspuren), tools/pairlab/harvest.py (Paar-Overrides + pair_instances).
Ohne --apply entsteht nur ein Report — die Freigabe bleibt Menschensache.
Sektion · Dissektion — das Auseinandernehmen eines echten Vorkommens
in seine Bestandteile: beide Buchstaben unabhängig eingepasst, der echte
Verbindungszug aus dem Skelett verfolgt, Platzierungsfehler von Formfehler
getrennt. Werkzeug: tools/pairlab.
Wort-Trace — die nachgefahrene Schreibspur eines ganzen Specimen-Worts
im Registrierungs-Rahmen dieses Worts, plus Slot-Labels. Zusammen mit dem
Ausschnitt die vollständige „Lern-Schablone“. Tabelle word_instances.
Open-Core-Moat — die bewusste Trennung: Code ist MIT, die gelernten
Daten sind es nicht. Autorisierte Duktus-Templates, Laufformen und
Vorkommens-Statistik (= der DB-Inhalt) sind außerhalb der Lizenz
reserviert. Technisch durchgesetzt: Bench-Fixtures gitignored,
Ernte-Artefakte nie committet, und seit 2026-08-28 JEDER API-Read, der
den Bestand trägt, admin-gegatet — Templates, Vorkommen, Bboxen,
Paar-Overrides, Hände, Statistik-Schicht, Eigenhand; die Trennlinie
öffentlich/reserviert hält tests/test_api_public_surface.py für jede
GET-Route fest. Die Crawler-Politik der Seite ist davon unabhängig offen
(ai-train=yes): Der Moat ist die Datenbank, nicht die Webseite.
→ quellen-und-rechte.md §5, crawler-richtlinie.md §2
Komposition voller Länge — die Einheit, in der der ENGE Token-Bucket vor
/write/word seit dem 2026-09-04 zählt (composition_cost,
api/rate_limit.py): Ein Token kauft 160 komponierte Zeichen — die
Obergrenze der Route selbst —, ein kürzerer Text kostet anteilig weniger,
mindestens ein Achtel Token. Die konfigurierten Zahlen bleiben (60/min, Burst
20), sie lesen sich nur nicht mehr als „60 Anfragen": Was 2026-09-01 gemessen
wurde (0,80 s TTFB, 1,65 MB für 155 Zeichen), skaliert mit dem TEXT, nicht mit
der Anfrage — dieselbe Zeile kostet gleich viel, ob sie am Stück oder in vier
Teilen kommt. Sichtbar wurde das an der → Postkarte (Federprobe): Sie bricht in
bis zu ~57 geschriebene Zeilen um, jede eine eigene Kompositionsanfrage, und
sprengte pro Anfrage gezählt mit EINEM Seitenaufruf den Burst; nach Länge
gezählt kostet sie 3 bis 7 Token (die Untergrenze greift, sobald eine Zeile
unter 20 Zeichen fällt). Der Missbrauchsfall bleibt unberührt (eine Anfrage
voller Länge kostet weiter genau ein Token), die ANZAHL der Anfragen begrenzt
weiterhin der weite Bucket.
write-api.md „Ratenbegrenzung“.
Origin-Geheimnis — der gemeinsame Wert zwischen dem Cloudflare-Edge und
dem API-Dienst, der die direkte *.run.app-Adresse zumacht. Beide
Cloud-Run-Dienste stehen mit ingress=all im Netz (kein Load Balancer — er
kostete mehr im Monat als das Projekt), die API antwortete also auf zwei
Adressen: über Cloudflare und daran vorbei. Alles, was am Edge durchgesetzt
wird — Rate-Limiting-Regel, WAF, Cache —, war damit über eine URL umgehbar.
Eine Transform-Rule stempelt seit 2026-09-02 den Header
X-Origin-Secret auf jeden Request, den Cloudflare für
api.kurrentschrift.ink weiterreicht; alles ohne ihn bekommt 403 —
vor dem Limiter, vor require_admin, vor jeder DB-Abfrage. Es ist
keine Authentifizierung: der Header sagt „durch die Vordertür", nicht
wer da kommt. Eine Ausnahme, gemessen beim Rollout: ein
Worker-Subrequest an einen Host DERSELBEN Zone läuft an den Transform-Rules
vorbei, deshalb stempelt der Apex-Worker vor dem Admin-Weg selbst
(infra/cloudflare/). Ohne gesetzte ORIGIN_SECRET-Env ist die Prüfung aus,
und genau das ist der Rollback (Env entfernen und die neue Revision
promoten); ausgenommen bleiben /health (der Deploy-Smoke probt die
run.app-Tag-URL) und /seo-proxy/… (Crawler-Pfad). /health
meldet als origin_gate das Urteil für den fragenden Request (off ·
off-seen · ok · missing · mismatch, nie den Wert); off-seen heißt
„Header kommt an, Prüfung noch aus" und ist das Messmittel, mit dem jeder Weg
in den Dienst bestätigt wird, bevor scharf geschaltet wird — es ist der
Grund, warum der Worker-Befund vor und nicht nach dem Scharfschalten auffiel.
Zweite Tür, seit 2026-09-04 im Repo (noch aus): Der App-Dienst steht
ebenso offen und reicht auf der run.app-URL jeden Crawler-UA über
@seo_proxy an die API weiter, wo der Edge rechtmäßig stempelt — das
API-Gate kann den Umweg also gar nicht sehen. app/origin-gate.conf.template
ist dieselbe Mechanik in nginx (map-Ketten → $origin_gate_status,
if ($origin_gate_deny) { return 421; } → eigene 403-Seite); ausgenommen ist
allein /_health, das das Urteil im Header X-Origin-Gate meldet. Der Worker
braucht dort nichts, weil er jeden Pfad an den API-Host schickt.
Technisch: api/origin_gate.py, core/config.py::origin_secret,
infra/cloudflare/kurrentschrift-api-proxy.js,
app/origin-gate.conf.template, tests/test_app_origin_gate.py.
→ frontend-stack.md §5, quellen-und-rechte.md §5, infra/cloudflare/README.md
Report-Only-Woche — die Woche, in der eine neue
Content-Security-Policy als Content-Security-Policy-Report-Only
ausgeliefert wird: Sie blockiert nichts, sondern lässt den Browser jede
Quelle melden, die sie verboten hätte. Danach wird sie scharf geschaltet,
indem der Header-Name um -Report-Only gekürzt wird — eine Zeile.
Der Umweg ist kein Zögern, sondern die Antwort auf eine Asymmetrie: Eine zu
enge Policy fällt auf der öffentlichen Seite sofort auf, in der Werkbank
aber erst dem Autor — und die kann kein automatischer Durchgang öffnen, weil
sie hinter Cloudflare Access liegt. Die Woche ist nur so viel wert wie die
Meldungen, die sie erzeugt: Ziel der Meldung ist POST /csp-report auf dem
API-Host, der zählt und loggt und nichts schreibt; jede gemeldete
Verletzung ist ein Befund, der vor dem Scharfschalten in die Policy gehört
(oder abgestellt wird). Gemeldet wird per report-uri, und nur so: Die
naheliegende Fassung deklariert daneben report-to (Reporting-API) — und
genau das ließ Chromium im Durchgang vom 2026-09-02 report-uri ignorieren
und dann gar nichts liefern. Für diese Seite ist sie vorbei: Sie lief vom
2026-09-02 bis zum 2026-09-05 (davon 40 Stunden auf dem Nonce-Pfad), erzeugte
keine Meldung aus dem eigenen Code, und die Policy ist seit dem 2026-09-05
scharf — report-uri blieb stehen, das Feld disposition trennt seither
report von enforce.
Technisch:
app/security-headers.conf, api/routers/csp.py,
tests/test_csp_policy.py. → frontend-stack.md §6
add_header-Vererbungsfalle — nginx vererbt Antwort-Header nicht über
Ebenen hinweg: Sobald ein location-Block einen eigenen add_header setzt
(und sei es nur ein Cache-Control), fallen sämtliche auf Server-Ebene
gesetzten Header für diesen Block still weg. Kein Fehler, keine Warnung —
nur eine URL, die als einzige ohne CSP und ohne nosniff ausgeliefert wird.
Deshalb stehen die Header dieses Projekts in einer eigenen Datei, die im
Server-Block und in jedem location mit eigenem add_header per
include gezogen wird; wer irgendwo einen add_header ergänzt, ergänzt die
include-Zeile daneben. Technisch: app/security-headers.conf,
app/nginx.conf; gehalten von
tests/test_csp_policy.py::test_every_nginx_location_with_its_own_header_reincludes_the_snippet.
→ frontend-stack.md §6
Prerender-Pfad (Crawler) — Crawler und KI-Agenten (kein JavaScript)
bekommen je öffentliche Route eine zur Build-Zeit aus dem Locale-Katalog
gerenderte HTML-Seite statt der leeren SPA-Hülle; Menschen bekommen
unter derselben URL die App. Erkannt am User-Agent ($is_bot-Map in
app/nginx.conf, wortgleich mit anyplot), bedient vom API-Host
(/seo-proxy/{route} liest app/prerender/*.html). Jede Seite trägt
Head (Canonical, OG, JSON-LD), den Text in DOM-Reihenfolge, die
Site-Nav, Stand (Sitemap-lastmod) und den Rechtehinweis in-band; erste
Zeile ist der Marker <!-- kurrentschrift.ink prerender -->. Löste am
2026-08-28 den Markdown-Spiegel der Schriftkunde (/schriftkunde.md,
2026-08-27, eine Seite) ab. Technisch: app/src/lib/seo/prerender.ts
(Renderer) + app/scripts/build-prerender.mjs (prebuild) +
api/routers/seo.py; Wächter prerender.test.ts,
tests/test_api_seo_proxy.py und täglich
.github/workflows/bot-serving-check.yml. → frontend-stack.md §6,
crawler-richtlinie.md §3
IndexNow — das freie, offene Push-Protokoll von Bing und Yandex
(mitgenutzt von Seznam, Naver, Yep): Statt auf den nächsten Crawl zu
warten, meldet die Seite geänderte URLs per POST an api.indexnow.org;
Google nimmt nicht teil und liest weiter die Sitemap. Der Nachweis, dass
die Meldung vom Host stammt, ist eine öffentliche Schlüsseldatei
app/public/kurrentschrift-indexnow-….txt (nginx liefert sie wie die
anderen Maschinendateien direkt aus). Gemeldet wird bei jedem Push auf
main, der app/** berührt — dieselben Pfade wie der Cloud-Build-Trigger
deploy-app — die komplette Sitemap (zehn URLs), weil bei zehn Seiten die
Sitemap die natürliche Einheit ist. Seit 2026-09-02, auf Empfehlung der
Bing Webmaster Tools. Technisch:
.github/workflows/indexnow-submit.yml. → crawler-richtlinie.md §3
Bot-Site (bot_fetch) — die zweite Plausible-Site
bots.kurrentschrift.ink, auf der die Seitenabrufe von Crawlern und
KI-Assistenten landen — nie auf der Besucher-Site, weil jedes
Plausible-Event einen „Besucher" erzeugt und die menschlichen Zahlen
sonst aufblähen würde (anyplots Befund: ~40 % zu viel). Ein Event
bot_fetch je Abruf auf dem Prerender-Pfad, serverseitig aus der
API-Middleware, mit den Eigenschaften assistant (Anbieter: claude,
chatgpt, gemini, google …), kind (warum abgerufen wurde —
user_directed = ein Mensch hat seinen Assistenten gebeten, die Seite
zu öffnen, also ein Leser; index, search, training, inspection =
Maschinen bauen einen Korpus), path und status (der Abruf wird
aufgezeichnet, nicht der erfolgreiche Lesevorgang — eine 404 ist ein
Signal, kein Seitenaufruf). Dazu seit 2026-08-28 das Event
asset_fetch für die Einzel-Abrufe der API — Buchstabe oder Wort als
SVG/JSON, Tafel-Ausschnitt — mit asset, source und key
(glyph_key bzw. angefragter Text): welche Buchstaben und Wörter
Assistenten zeigen wollten. Drei Fallen, die die Events schweigend
verschwinden lassen: ein Bot-User-Agent (→ Events laufen unter dem
neutralen kurrentschrift-server/1.0, die Identität steckt in den
Props), eine Hosting-IP als Besucher — Plausible verwirft
Google-Cloud-Adressen, und genau die ist auf dem Crawler-Pfad
cf-connecting-ip (→ nginx reicht den Crawler in X-Forwarded-For
durch, visitor_ip nimmt die ERSTE gültige weitergeleitete Adresse) —
und der Edge-Cache (→ /seo-proxy antwortet no-store, sonst zählt
nur der erste Abruf). Taxonomie AI_AGENTS wortgleich mit
anyplot. Technisch: api/analytics.py, api/request_context.py, die
Middleware record_bot_fetch in api/main.py; aktiv nur in Produktion
(BOT_ANALYTICS überschreibt). → frontend-stack.md §6,
crawler-richtlinie.md §3
Pfeilhöhe (sagitta) — wie weit ein Zug von der geraden Verbindung
seiner Endpunkte abweicht: der größte Abstand eines Punktes des Zuges zu
seiner Sehne, in x-Höhen. Das Verhältnis Pfeilhöhe/Sehne ist damit ein
maßstabsfreies Maß für „wie gebogen“ — 0 heißt Lineal-Strich. Zwei Stellen
im Projekt beziffern sie — beide von Hand, kein Code rechnet sie: die
Dissektion der Tafelzellen für den konkaven Anstrich der Apex-Klasse (t 0,180 ·
ſ 0,136 · k 0,187 · ß 0,175 xh; die Werte stehen als gemessene Zahlen im
Kommentarblock über APEX_HANDOVER_MIN_RISE in core/compose.py — die
Konstante selbst prüft den ANSTIEG des Zuges, nicht seine Pfeilhöhe), und die
humanbench-Wortrunde sep05, die damit beziffert hat, was das Auge an der
Apex-Übergabe verworfen hat (die erzeugte Übergabe kommt auf 0,001–0,002 xh
bei 1,67–1,84 xh Sehne). Seit sep06 rechnet sie auch Code: als bow_median /
bow_join des Unstetigkeits-Sensors, über einer Sehne von zwei
Federbreiten — der Rettungsweg 2 der Runde 6 (tintenfolger.md §7.9),
gegangen.
M4-Fit — die elastische Anpassung eines Templates an echte Tinte:
Das kanonische Template wird auf das Skelett eines Vorkommens gewarpt,
wobei Strichstruktur und Ecken erhalten bleiben. Heißt so nach dem
Meilenstein M4 der MVP-Roadmap, in dem die Routine entstand — nicht zu
verwechseln mit der Kettenfit-Kennzahl M4 (unten).
Technisch: core/fit.py::fit_template_to_instance /
fit_glyph_to_crop, Tikhonov-regularisiert, L-BFGS-B mit analytischem
Gradienten.
Tikhonov-Regularisierung — der mathematische Trick, der einen Fit
davon abhält, sich beliebig zu verbiegen: zur Datenanpassung wird ein
Strafterm addiert, der große Abweichungen von der Ausgangsform bestraft.
Der Fit „darf sich anschmiegen, aber nicht verwandeln“. (Anderswo:
Ridge-Regression, L2-Regularisierung.)
Technisch: REFINE_LAMBDA_REG in core/fit.py.
Skelett (skeleton) — die auf ein Pixel Breite ausgedünnte Mittellinie
der Tinte (skimage.skeletonize). Zusammen mit der EDT
(euclidean distance transform, distance_transform_edt), die an jedem
Punkt den Abstand zum nächsten weißen Pixel = die halbe Strichbreite
liefert, sind das die beiden Kanäle, aus denen jede Messung kommt.
Deckung (coverage) — die Gegenrichtung des Fits: Nicht nur „liegt
mein Template auf Tinte?“ (das ist die Geometrie-Richtung), sondern „ist
jede Tinte von meinem Template erklärt?“. Ohne Deckungsterm kann ein Fit
sich auf einen Teilstrich zurückziehen und dort perfekt sitzen.
Technisch: Energien e_geo (Template → Skelett), e_cov (Skelett →
Template) und e_wid (Breiten); Konvergenz-Schwellen
core/fit.py::CONVERGED_GEO_RMSE_UNITS (0,08 xh) und
CONVERGED_COVERAGE_RMSE_UNITS (0,10 xh); Punktbudget
MAX_COVERAGE_POINTS (300 pro Glyphe).
Deckungslücke — der Abzug, den die Sütterlin-Natürlichkeitsmetrik
aus dem Deckungs-Gate bildet: components.coverage = 1 − gate. Höher =
schlechter, genau umgekehrt zur → Deckung und zum gate selbst.
Wichtig für die Deutung: Das Gate ist ein Produkt aus drei Faktoren
(gate = dice · q_chamfer · q_geo), die Lücke also ein
zusammengesetzter Abzug aus Überlappung (Dice), Randabstand
(Chamfer) und Mittellinien-Lage (Geo-RMSE) — nicht allein der Anteil
verfehlter Tinte. Ein hoher Wert sagt „das Tor ist zu", nicht welcher
der drei Faktoren es zugezogen hat; dafür stehen die Einzelmaße im
Diagnose-Block. Der eigene Name
(Autor-Entscheid 2026-09-03) löst eine Falle in der Werkbank auf: Im
Diagnose-Block standen „Deckung (IoU): 0.105“, „Deckungs-Gate: 0.01“ und
„Deckung 0.99“ drei Zeilen auseinander — dieselbe Größe einmal positiv
und einmal als Abzug, unter einem Wort; die 0.99 las sich wie eine
hervorragende Deckung und war der maximal mögliche Abzug. Seither heißt
nur der Abzug „Deckungslücke“; „Deckung (IoU)“ und „Deckungs-Gate“
behalten ihr Wort, weil sie die positive Richtung messen. Die Kurzform
auf den Buchstabenkarten trägt zusätzlich das Präfix „Abzüge:“, damit die
Zahlenreihe auch ohne die Balkenlegende ihre Richtung nennt.
Technisch: core/quality_suetterlin.py (gate → components.coverage);
Beschriftung app/src/locales/de/wizard.ts (optimize.cat.coverage),
Kurzform app/src/sections/admin/quality/scoreParts.tsx
(ScoreBreakdownInline). → qualitaetsmetrik.md §5
Warp — das elastische Verbiegen einer Form beim Fit (im Gegensatz zum bloßen Verschieben). Merksatz aus der Ernte: „shapes, not placements“ — gespeichert werden zentrierte Formen; wo ein Buchstabe stand, ist ein eigener, unregularisierter Parameterblock und darf nicht als Formfehler bestraft werden.
Rastersuchlauf · Platzierungsschranke — vor dem elastischen Fit wird
ein Buchstabe durch eine begrenzte Gittersuche grob auf die Tinte
geschoben (±0,6 xh horizontal, ±0,20 xh vertikal:
FIT_DX_UNITS/FIT_DY_UNITS in tools/pairlab/analyze.py). Landet das
Optimum auf dem Rand dieses Fensters (at_bound), ist das ein
Warnzeichen: die richtige Stelle lag vermutlich außerhalb.
Kettenfit (chain fit) — die Idee, Buchstabe → Verbinder →
Buchstabe als EINE durchlaufende Feder zu fitten statt als zwei
unabhängige Buchstaben plus nachträglich zerlegten Verbindungsstrich.
Motiv: Wo zwei Buchstaben sich berühren, liefert die nachträgliche
Zerlegung gar nichts — genau dort, wo verbundene Schrift am
verbundensten ist. Stufe A (Paar-Maßstab) ist gebaut und gemessen; Stufe B
(Wort-Maßstab) ist freigegeben. Reine Messschicht, ändert kein
Rendering. Auf der Duell-Seite trägt seit 2026-08-16 die GEWACHTE
Variante (Struktur-Wächter, Arm ⑨) das Label Kette — Owner-
Entscheid: fit-erfundene Kreuzungen sind nie richtig (→ Duell-Namen).
Technisch: tools/pairlab/chain.py + chainbench.py
→ uebergaenge-befund.md §5c · Issue #278
Tintenfolger (ink follower) — die geplante Verfeinerungsstufe ÜBER
dem Kettenfit: der Kettenfit liefert Topologie, Strichfolge und
Kreuzungsauflösung als Initialisierung, dann wird die Form-Regularisierung
Richtung Vorlage GELÖST (der Tikhonov-Term wird im Rebuild zum
Proximal-Term relativ zum Chain-Optimum, kein Chart-Prior mehr) und die
Bahn dicht auf das gemessene Skelett gezogen — „Geometrie ganz aus der
Tinte, Ordnung ganz aus dem Prior“. Maßstab ist der nachgefahrene
Referenzsatz (§4), nie das eigene Residual. Kein neues System, kein
GPU, kein Fremdmodell; Ausgabe ist eine Wortbahn (Inspektionsschicht),
nie eine Messung. Technisch: tools/pairlab/follow.py
(follow_word_chain/follow_case, Gewichte PROVISORISCH bis zur
§14-Arm-Kalibrierung) → proposals/tintenfolger.md ·
bildsynthese-und-stiftbahn.md §6
Fremdtinte (foreign ink) — Tinte im Wort-Crop, die das Wort nie
geschrieben hat und die die eingefrorene Binarisierung trotzdem behält:
Papierflecken, Durchschein der Rückseite (Galoppieren: sechs
Fragmente, halb so dunkel wie die Schrift), Reste der Nachbarzeile.
Für den Kettenfit/Folger ist jede solche Komponente zugleich Zugfeld-
Magnet und Coverage-Ziel — die Nadeln „ins Papier" (zwei w-Fuß,
Galoppieren) enden messbar darauf. Gemessener Fund (2026-08-20, 90
Nicht-Haupt-Komponenten der 63 Fixtures): FLÄCHE trennt Fremdtinte nicht
von echten Marken, DUNKELHEIT trennt vollständig (rel 0,74–0,92 gegen
0,01–0,38). Nicht zu verwechseln mit der eigenen Marke als Magnet
(die-2: der i-Punkt zieht die Körperbahn) — dunkel, echt, und vom
Darkness-Filter bewusst behalten. Technisch:
tools/pairlab/ink_evidence.py → messjournal.md §14 „Kette K-C"
Tinten-Evidenz-Maske (ink-evidence mask, Kette K-C) — die Maßnahme
gegen Fremdtinte: vor Seed-Fenstern und Solve wird jede Nicht-Haupt-
Komponente der Maske, deren Median-Grau näher am Papier als an der
Haupttinte liegt (paper_fraction 0,5 = Mitte der gemessenen Lücke, kein
Knopf), aus skel und width_map des Falls gelöscht; die größte
Komponente ist das Wort und bleibt immer. Aus — oder nichts zu droppen —
heißt derselbe WordCase (Identität), darum sind Wörter ohne Fremdtinte
byte-identisch. Ändert NUR, was den Fit zieht; das Bench-Lineal
(ref_mask, AIoU, Zähler) bleibt eingefroren — die Torpfosten stehen.
Nach dem aug20-Sechs-Gates-Pass und dem Autor-Go als Kette v4
adoptiert (aug21): FollowWeights.ink_evidence und
HarvestOptions.ink_evidence sind seither DEFAULT an (auch im
chain-Provider des Tracebench); Archäologie-Pfad --no-ink-evidence
bzw. ink_evidence=False = der Vor-v4-Stand, byte-identisch.
Drop-Liste je Wort in meta.ink_evidence. Technisch:
tools/pairlab/ink_evidence.py, Einsatz in follow_derived und
harvest.chain_word_strokes → messjournal.md §14 „Kette K-C"
(Messung) + „Kette v4" (Re-Baseline)
Tinten-Zuweisung per Strecke (per-stroke ink assignment, Kette
K-E) — der Autor-Ansatz nach K-C: nicht WELCHE Tinte zieht, sondern
WEN sie ziehen darf. Heute sehen alle Samples eines Ketten-Runs EIN
Distanzfeld und EINEN Coverage-Topf — jede Tinte zieht das nächste
Sample, egal zu welcher Strecke (Strich) es gehört; so zieht in
die-2 der eigene i-Punkt die d-Schleife (die V-Nadel), und dasselbe
plattgezogen ist der Verdacht hinter den verbliebenen unechten
Retrace-Zonen an kleinen Kringeln. Stufe 1 = Marken-Claim-Trennung
(eindeutige Zuweisung per Duktus); Stufe 2 = Kringel (braucht den
Duktus-Prior als Verbrauchs-Zuordnung: jeder Tinten-Punkt wird von
genau einer Strecke verbraucht), nur bei haltender Stufe 1.
Gemessen aug21 (K-E1 + Ein-Faktor-Konversion K-E2): beide per
aiou-Gate verworfen — die benannten Ziele heilen (die-2s V-Nadel
weg), aber vier diffuse Körper-Deckungs-Risse hängen an denselben
Kanälen wie die Heilung; Stufe 2 nicht eröffnet, Wege §7.9
(humanbench · Distanzfeld-NUR-Claim). Technisch:
tools/pairlab/chain.py (Feld-Aufbau in
fit_word_chain/_prepare_fields) → messjournal.md §14
„Kette K-E"/„Kette K-E2", tintenfolger.md §7.3 A9/K-E
Marken-Claim-Trennung (mark-claim separation, K-E Stufe 1) —
die eindeutige Hälfte der Tinten-Zuweisung per Strecke: eine
Marken-Strecke (Strich eines Buchstaben-Segments, dessen Init das
Assembler-Kriterium diacritic_stroke_units erfüllt — i-Punkt,
u-Bogen; der t-Querbalken nicht) CLAIMT die dunkle
Nicht-Haupt-Komponente im 0,6-xh-Marken-Radius des Lineals. Ein
Claim schaltet beide Zug-Kanäle um: die Komponente verlässt Feld und
Coverage-Topf der Körper-Samples, die Marken-Samples lesen
ausschließlich ihre Komponente. Ohne Claim ändert sich nichts —
Marken ohne Tinte suchen wie heute, Körper-Bruchstücke bleiben
Körper-Evidenz. EIN Knopf mark_claim (--mark-claim), nach den
aug21-Messungen (K-E1 · K-E2) declared-off geblieben — verworfen
per aiou-Gate bei spektakulärer die-2-Heilung; der Code trägt die
K-E2-Form (Breitenfelder ungeteilt). Technisch:
tools/pairlab/chain.py, Knopf in FollowWeights/HarvestOptions
→ messjournal.md §14 „Kette K-E"/„Kette K-E2"
Topologie-Wächter (structure guard) — Arm ⑨ des Tintenfolgers:
eine Runden-AKZEPTANZREGEL statt einer Kraft. Vor der ersten Runde
wird das Struktur-Budget der Initialisierung gemessen (die
v2.1-Klassenzählung Kreuzungen · Retrace-Zonen · Berührungen ·
Überlagerungen, mit den Zählern des Lineals auf der assemblierten
Bahn); eine gelöste Runde wird nur akzeptiert, wenn keine Klassenzahl
ihr Budget übersteigt — sonst wird sie mit halbierten Reisebudgets neu
gelöst (höchstens zweimal) und danach auf die Vorrunden-Geometrie
zurückgewiesen (structure_rejected). Trennt die Distanz-Gewinne des
Form-Release von seinen Struktur-Erfindungen, statt beide gemeinsam am
Veto scheitern zu lassen; der Owner-Satz dahinter: Kringel, Kreuzungen
und Retraces sind duktus-fix. Technisch:
tools/pairlab/follow.py::structure_class_counts +
FollowWeights.structure_guard (default False = byte-identisch),
STRUCTURE_GUARD_MAX_RETRIES → messjournal.md §14 (Arm ⑨).
Nicht zu verwechseln mit dem Laufform-Topologie-Wächter (unten) —
gleicher Geist (Duktus-Topologie ist unantastbar), andere Schicht.
zonale Rückweisung (zonal, K0-Z) — die Reparatur des
Topologie-Wächters an seiner teuersten Eigenschaft: er verwirft eine
Runde atomar. Eine Runde bündelt aber oft eine erlaubte
Soll-Reparatur mit einer verbotenen Erfindung, und beim Voll-Revert
fällt die Reparatur mit. Die zonale Rückweisung lokalisiert stattdessen
die Verletzungen (Positions-Diff gegen die Vorrunde), pinnt die Anker im
Radius 0,55 xh um jede und löst EINMAL nach — der Rest der Runde
bleibt. guard_outcome protokolliert je Wort, was passierte
(accept · zonal · revert-init), und genau daran ist die Wirkung
belegt: 26 der 31 bewegten Wörter waren unter dem alten Wächter ein
Runde-1-Rollback auf den Init. Radius 0 reproduziert das alte
Verhalten byte-identisch. Technisch:
tools/pairlab/follow.py, --structure-guard-zone <xh>,
FollowWeights.structure_guard_zone_units (Default 0,55 seit Kette v5)
→ messjournal.md §14 „Kette K0-Z aug20“ und „Kette v5 aug26“
Ratsche (Ratschen-Budget, structure_guard_ratchet, K0-Z-R) —
die zweite Reparatur derselben Schicht: das Struktur-Budget des
Wächters bleibt nicht auf dem Stand der Initialisierung stehen, sondern
zieht nach jeder akzeptierten Runde Richtung Soll nach — wie eine
Ratsche, die nur in eine Richtung greift. Ohne sie darf eine Runde eine
Klassenzahl beliebig oft wieder verschlechtern, solange sie unter dem
alten Init-Budget bleibt; mit ihr ist jeder erreichte Struktur-Gewinn
die neue Obergrenze. Zusammen mit der zonalen Rückweisung und dem
Kompositions-Soll bildet sie den Wächter-Stack, der seit Kette v5
(aug26) der Default ist. Technisch:
tools/pairlab/follow.py, --no-structure-guard-ratchet schaltet sie
ab → messjournal.md §14 „Kette K0-Z-R aug20“ und „Kette K0-S
aug21“
Schienen-Auslauf (tail runout) — die erste adoptierte Konstante
der Route Lotse und ein Owner-Fund, kein geplanter Arm: am ENDE eines
Wortes hört die Tinte auf, aber die Karte läuft weiter; ohne Deckel
folgt der Ritt der Karte ins Leere und schleppt einen Schwanz hinter
sich her. Der Auslauf begrenzt, wie weit der Ritt nach dem letzten
Tinten-Sample noch der Karte folgen darf. Adoptiert bei 1,0 —
er allein senkte den dtw-Median der Route von 0,119 auf 0,101 und ein
Einzelwort von 0,343 auf 0,087. Technisch:
tools/inkpilot/pilot.py::TAIL_RUNOUT_MAX_UNITS →
messjournal.md §14 „Route Lotse aug16“, Ledger:
verfahren-lotse.md
Laufform-Topologie-Wächter (LF2) — die Schichtungs-Regel auf der
Laufform-Ebene: eine Laufform-Zeile, die eine GEZÄHLTE Chart-Kreuzung
ihres Glyphen löscht, überschreibt den Duktus-Prior statt ihn zu
weiten und wird nicht komponiert (Fallback rohe Chart-Form). Der
aug19-Sweep fand genau zwei gespeicherte Verlierer (h: 2 → 0 in
jedem Slot · p: 1 → 0) und der LF1-Lauf einen frischen (G-Draft) —
der rohe Anker-Median bügelt Schleifenschlüsse glatt
(„Median-Verengung": der Annäherungs-Spalt der Schenkel schrumpft,
und der v2.1-Retrace-Filter kippt das tangentiale X). Als
Voll-Entfernung gemessen und verworfen (Tinten-Preis, Marken-Kipp);
als WRITE-PATH-Prinzip bleibt er stehen. → messjournal.md §14
(„Laufform LF2"), Nachfolger: Topologie-Reparatur (LF3)
Topologie-Reparatur (Chart-Rückblendung, LF3) — die Konversion
des Laufform-Topologie-Wächters von Filter zu Konstruktion: verliert
eine Laufform-Form (gespeicherte Zeile oder Lücken-Draft) eine
gezählte Chart-Kreuzung, blenden die Anker im festen 0,5-xh-Fenster
um die verlorene Kreuzung minimal zur Chart-Geometrie zurück —
t per Bisektion als kleinstes t ∈ [0, 1], das die Zählung
wiederherstellt (linearer Falloff, deterministisch); scheitert auch
t = 1, fällt das Glyph auf die Chart-Form zurück. Breite bleibt
Laufform, Topologie bleibt Chart. → messjournal.md §14
(„Laufform LF3")
Junction-Verschiebung (junction displacement) — der dokumentierte Fehler des Skelett-Branch-Points als Kreuzungs-Marke: Thinning verschiebt ihn um bis zu die lokale Strichbreite (±2–4 px bei xh ≈ 30) und spaltet eine echte Kreuzung oft in ZWEI Y-Junctions, deren Brücke 1,2–1,7 Strichbreiten lang ist (auf den Dev-Wörtern gemessen). Ein Term, der eine Bahn-Kreuzung auf den rohen Branch-Point zieht, zieht sie deshalb an die falsche Stelle. → das extrapolierte Landmark-Ziel.
extrapoliertes Landmark-Ziel — die Korrektur der
Junction-Verschiebung im Tintenfolger: Um den Branch-Point werden die
einlaufenden Skelett-Äste GEODÄTISCH verfolgt (Dijkstra auf dem
Skelett, Junction-Cluster absorbiert, Konfluenzen blockiert statt
verschweißt — die euklidische Annulus-Variante verschweißt auf
kursiver Tinte die Schenkel), der junction-verzerrte Kern (2×
Halbbreite) ausgeschlossen, je Ast eine TLS-Richtung gefittet, Äste
per Gute-Fortsetzung gepaart (Krümmungs-basierte Toleranz) und der
Schnittpunkt der Fortsetzungen als Ziel genommen — mit isotroper
Unsicherheit ≈ lokale Halbbreite als 1/σ²-Gewicht (Pre-Whitening des
bestehenden Operators, kein neuer Term). Verweigert ehrlich:
Touch-Points (2 Schenkel) und T-Junctions (3) sind BY DESIGN keine
Kreuzungsziele — auf den Dev-Wörtern sind das 12 von 21
Korrespondenzen (→ die Korrespondenz-Kappe), die Kappe jedes
Landmark-Effekts, solange die Korrespondenz nicht klassenbewusst wird.
Technisch: tools/pairlab/follow.py::extrapolated_targets
→ messjournal.md §14 (Arm ⑥)
Korrespondenz-Kappe — der Befund, der die Arme ⑤/⑥ des
Tintenfolgers überragt: 12 der 21 Landmark-Korrespondenzen der
Dev-Wörter zeigen auf Tinte, die GAR KEINE Kreuzung trägt (5
Touch-Points, 7 T-Junctions) — die BAHN kreuzt sich dort, die Tinte
berührt sich nur. Solange die Korrespondenz diese Klassen nicht kennt,
zieht jeder Landmark-Zug an der Hälfte der Ziele in eine Struktur, die
es nicht gibt; das deckelt jeden möglichen Effekt des Terms, wie stark
er auch gewichtet wird. → die klassenbewusste Korrespondenz.
Technisch: messjournal.md §14 (Arme ⑤+⑥, aug14)
klassenbewusste Korrespondenz — die vorregistrierte Antwort auf die
Korrespondenz-Kappe (Arm ⑥b): die Landmark-Korrespondenz kennt die
KLASSE ihres Tinten-Ziels. Zeilen, deren Verfeinerungsgrund eine
By-Design-Nichtkreuzung der Tinte ist (touch_point · t_junction),
bekommen Gewicht 0 über das bestehende Pre-Whitening (√w skaliert
Operator-Zeile UND Ziel — die Zeile zieht nichts und kostet nichts),
statt weiter am rohen Branch-Point zu ziehen; die 1/σ²-Gewichte der
überlebenden Zeilen renormieren auf Mittel 1. Die Walk-Fehlschläge
(few_branches · no_continuation_pair · …) bleiben Ziele — dort KANN
die Tinte eine Kreuzung tragen. Folger-seitig; chain.py und die
eingefrorene landmarks.py bleiben unberührt. Technisch:
tools/pairlab/follow.py::classed_targets (Modus
extrapolated_classed), LANDMARK_NONCROSSING_REASONS
→ messjournal.md §14 (Arm ⑥b)
Retrace-Guard — die Ausnahme im Tintenfolger, die dessen blinden
Fleck deckt: Über doppelt beschriebener Tinte belohnen BEIDE Datenterme
den Kollaps zweier Pässe auf eine Linie (Reverse-Coverage ist von einem
Pass befriedigt, der Ridge-Pull von beiden auf dem Grat), und das
Einzige, was sie unterscheidet, ist der Form-Prior — den die Stufe
gerade löst. Der Guard erkennt Retrace-Zonen deshalb auf der
INIT-Bahn (derselbe Detektor wie der tracebench-Zähler) und lässt die
betroffenen Anker ihr VOLLES Chain-λ behalten, als per-Anker-
Reg-Gewicht statt als Bound — nur so koexistiert λ_prox = 0 (die erste
Sprosse von Arm ①) mit stehendem Guard. --no-retrace-guard existiert,
um den Guard selbst zu MESSEN, nie als Betriebsmodus. Technisch:
tools/pairlab/follow.py::apply_retrace_guard →
proposals/tintenfolger.md §3
Iterationsdeckel (iteration cap) — die Obergrenze, wie viele
Optimierungsschritte ein Fit machen darf, bevor er abgebrochen wird. Klingt
nach einer Sicherheitsleine, ist aber eine stille Falle: Wird der Deckel
erreicht, meldet der Optimierer trotzdem ein Ergebnis — nur ist es eine
Momentaufnahme eines noch laufenden Abstiegs, kein konvergiertes Resultat.
Solche Zwischenstände fallen durch das Konvergenz-Gate, ihr Vorkommen wird
verworfen, und wo genau der Abbruch landet, verschiebt sich mit dem
Startwert — daher waren Ernten über eine Init-Änderung hinweg nicht
reproduzierbar. Lehre: Ein Fit-Ergebnis ist erst dann eines, wenn man weiß,
warum der Solver aufgehört hat.
Merkregel: Ein Deckel, der überhaupt bindet, ist der falsche Knopf — der
Solver hört ohnehin bei seinem eigenen Kriterium auf, also kostet ein hoher
Deckel nur dort etwas, wo er gebraucht wird.
Technisch: der Kettenfit hat mit CHAIN_MAX_ITER (Default 8100) ein
EIGENES Budget statt core.fit.DEFAULT_MAX_ITER (300) — 300 ist ein
Pro-Glyph-Budget, eine Wortkette trägt ~820 freie Parameter. Gemessen
(Median 1211 Iterationen, p90 2518, Maximum 4215): bei 300 war der Deckel in
91 % der Solves der bindende Stopp, bei 2700 in 10 %, bei 8100 in keinem —
für +5 % Rechenzeit, ohne dass sich ein einziges Gate-Urteil ändert.
fit_meta["hit_iteration_cap"] und die Spalte im --diag-csv machen den
Zustand lesbar; KS_CHAIN_MAX_ITER sweept ihn.
Überlappungsterm (overlap term, Exklusivität) — der Energieterm des
Kettenfits, der die physikalische Aussage kodiert: eine Feder schreibt
denselben Zug nicht zweimal. Nötig wurde er durch einen Befund der
Runde 2: Das Objektiv prüfte die Vereinigung aller Segmente gegen die
Vereinigung der Tinte und war für die Zuordnung blind — ein Buchstabe,
der die Tinte des Verbinders schluckt, und ein Verbinder, der den
Buchstabenstrich nachfährt, sahen beide nach guter Deckung aus. Die
Beckensonde bewies: die gestapelte Lösung war in jedem Term billiger
(5/5 Fälle). Der Term bestraft Sample-Paare verschiedener Segmente, die
näher beieinander liegen als ein Haarstrich breit ist; ausgenommen sind nur
die Nahtbänder benachbarter Segmente (die gemessene Stub-Zone, in der die
Hand wirklich Tinte teilt) — Buchstabe-auf-Buchstabe ist nie ausgenommen.
Wirkung, gemessen im vorregistrierten A/B: die vier Grenzfall-Flags des
Konnektor-Wächters heilen mechanisch (der Naht-Anteil verschwindet aus der
Lösung selbst), +4 Vorkommen, null neue Flags.
Technisch: tools/pairlab/chain.py — CHAIN_OVERLAP_RADIUS_UNITS (0,15),
CHAIN_OVERLAP_SEAM_EXEMPT_UNITS (0,4, aus der Init-Geometrie, damit der
Gradient exakt bleibt), CHAIN_OVERLAP_WEIGHT (0,2, per Sweep + A/B;
KS_CHAIN_OVERLAP_WEIGHT überschreibt). Paarmenge pro Evaluation per
KD-Baum, stückweise konstant in den Parametern — dieselbe f.ü.-exakte
Behandlung wie die Deckungszuordnung.
Binnenflächen-Bedingung (counter constraint, R3c) — dasselbe
Zwei-Züge-Modell, aber als Term IM Solve statt als Nachbearbeitung
dahinter. Die Aussage ist unverändert: keine Stützstelle darf näher als
w_pen an einer Binnenfläche stehen, die die Platte offen hält. Der
Unterschied ist, wo sie steht — ein quadratischer Hinge auf dem
vorzeichenbehafteten Abstandsfeld dieser Binnenflächen, den der
Folger in jeder Runde sieht, normiert wie der Tinten-Term (e_geo) und
über den Sampling-Operator auf die viel dünner besetzten Anker
zurückgefaltet. Der Anlass ist gemessen: R3 und R3b haben die punktweise
Fassung ausgemessen und gezeigt, dass ihre Treffgenauigkeit und ihre
Glätte an EINER Blendenlänge hängen — eine Nachbearbeitung kann per
Konstruktion nicht glatter sein als ihr Raster, ein Solver rechnet den
Ausgleich. Zwei Bestandteile des Vorgängers entfallen deshalb
ausdrücklich: keine Blende (die Anker sind die Glättung) und keine
Abnahmeregel „Schleifen-Schluss" (der Topologie-Wächter weist eine
Runde, die eine Init-Kreuzung verliert, ohnehin zurück). Der
Geltungsbereich bleibt dagegen R3s — offen × klein/mittel —, und
ein Kalibrierlauf sagt warum: eine GROSSE Schleife der Kette ist genauso
zu eng wie eine kleine, die Bedingung bindet dort also am stärksten und
kauft trotzdem nichts, weil drei Viertel eines großen Lochs jede Feder
überleben. Innerhalb der Binnenfläche läuft
das Feld negativ weiter, wo der Schub verweigern musste: eine
Stützstelle im Loch bekommt eine wohldefinierte Kraft nach außen statt
einer Verweigerung.
Technisch: tools/pairlab/counterfield.py (Feld + Geltungsbereich über
das Slot-Lineal von zweizuege.catalogue_targets), Term
counter_weight/counter_smooth/counter_target_px in
tools/pairlab/chain.py, Schalter --counter-constraint
(FollowWeights.counter_constraint, Vorgabe AUS). Er tritt NUR in den
Folger-Runden ein — fit_word_chain bleibt unberührt, also ist jeder
andere Verbraucher der Kette byte-gleich.
→ messjournal.md §14 („Kette R3c Binnenflächen-Bedingung im Solve
sep07“) · → Zwei-Züge-Modell
Feder-Entfaltung (pen deconvolution, R4) — dieselbe Aussage über
die Tinte ein drittes Mal, und diesmal an der EVIDENZ statt an der Bahn
(Zwei-Züge-Modell) oder am Objektiv (Binnenflächen-Bedingung). Der
Tinten-Term des Folgers ist die Distanztransformation des Skeletts
der eingefrorenen Maske, das Skelett ist also der Attraktor jeder
Stützstelle — und um eine kleine Binnenfläche ist es nicht der Federweg,
sondern die Klumpenachse zweier verschmolzener Kapseln
(→ Verschmelzungs-Anzeiger). Die Entfaltung räumt genau diese Achse aus
dem Attraktor: jedes Skelettpixel, das näher als w_pen an einer
offen-Binnenfläche des Katalogs liegt, fällt weg, und an seine Stelle
tritt die Niveaulinie w_pen + 0,5 px desselben Loch-Abstandsfeldes,
auf die Tinte beschnitten und nur so weit um das Loch herum, wie die
weggefallenen Pixel reichten (der radiale Schatten). Das ist eine
Konstruktion und keine Anpassung — jeder Punkt der Niveaulinie liegt eine
Federhalbbreite vom Loch entfernt, also trägt die korrigierte Schleife die
Erwartung Loch + 2·w_pen per Bauart, und es gibt keine Blendenlänge zu
wählen, weil der Solver glättet.
Drei Verweigerungen statt Knöpfe: keine Tinte erfinden (die
Niveaulinie wird auf die Maske beschnitten, der Schnitt wird gezählt);
die Schleife nie verlieren (umschließt das korrigierte Skelett die
Binnenfläche nicht mehr, wird DIESE Schleife zurückgenommen — R3s
Abnahmeregel, auf die Evidenz verlegt, wo sie eine Schleife kostet und
nicht eine Runde); nichts weiten, was schon stimmt. Voraus ging die
Raster-Diagnose (sep07): der Fixture-Ausschnitt ist ein
unskalierter Schnitt der Platte (30–33 px je x-Höhe) und der zweite
committete Scan derselben Platte trägt für sie ~5 % weniger, eine globale
50-%-Niveaulinie liest bei 1× dieselbe Binnenfläche wie die adaptive
Maske und bei 4× bikubischem Grau eine kleinere, und der
Verschmelzungs-Anzeiger überlebt die schärfere Lesung — die Verschmelzung
ist Tinte, kein Raster, und deshalb ist die Entfaltung der Weg und
nicht ein schärferes Bild.
Technisch: tools/pairlab/counterevidence.py
(unfold_pen_at_counter · counter_evidence_case), Schalter
--counter-evidence (FollowWeights.counter_evidence, Vorgabe AUS). Sie
ersetzt das Skelett des Falls an derselben Stelle wie die
Tinten-Evidenz-Maske (K-C), damit Saatfenster, Solve-Felder und
Deckungsziele EINE Evidenz lesen; das eingefrorene ref_mask/ref_skel
des Lineals bleibt unberührt.
→ messjournal.md §14 („Kette R4 Feder-Entfaltung sep07“) ·
→ Binnenflächen-Bedingung · → Zwei-Züge-Modell · → Verschmelzungs-Anzeiger
Kreuzungs-Landmarke (crossing landmark) — eine Selbstkreuzung der
Buchstaben-Ankerlinie, die als Ortsmarke der Struktur taugt: zwei
Sehnen, die sich unter mindestens 15° schneiden und (innerhalb desselben
Federzugs) mindestens 0,35 xh Bogenlänge auseinander liegen. 26 der 34
eingefrorenen v0-Zeilen tragen zusammen 43 solcher Landmarken. Der Sinn:
Ein Buchstabe hat eine feste Struktur (Kringel, Kreuzung, Schale in fester
Reihenfolge), und was je Vorkommen und je Übergang wandert, ist deren
Lage — beim Sütterlin-d sitzt die Tinten-Kreuzung mit
Folgebuchstaben 0,243 xh tiefer als am Wortende.
Technisch: core/landmarks.py — landmark_crossings
(LANDMARK_MIN_ANGLE_DEG, LANDMARK_MIN_ARC_SEPARATION_UNITS,
LANDMARK_MERGE_RADIUS_UNITS), von tools/pairlab/landmarks.py
unverändert re-exportiert; ausdrücklich nicht
core.geometry.detect_crossing_passages, das dieselbe Erscheinung für die
Breiten-Kontaminationsliste vermisst und keinen Schnittpunkt liefert
→ qualitaetsmetrik.md §13a
Landmarken-Term (landmark correspondence term) — der Energieterm, der
eine solche Landmarke auf ihr Tinten-Gegenstück zieht: den nächsten
Verzweigungspunkt des Skeletts (ein Skelettpixel mit ≥ 3 Nachbarn im
8er-Umfeld, benachbarte zu einem Schwerpunkt verschmolzen). Er ist der
erste Daten-Term dieser Zielfunktion — dieser Punkt gehört auf jenen
Punkt — und damit kein fünfter Anlauf der vier verworfenen Terme (§7
Biegeenergie, §8 Scharnier, §10 Eckanker, §11d Nachbarbindung), die alle
einen Stellvertreter (Krümmung, Abstand, Steifigkeit) auf einer
zuordnungsblinden Zielfunktion bepreisten. Linearisiert wie jeder andere
Operator der Kette: Sehnenpaar und Sehnenparameter werden am Startzustand
eingefroren, die gefittete Kreuzung ist dann der Mittelwert der beiden
Zweigpunkte und damit linear in vier Ankern (exakter Gradient). Eine
Zuordnung, die nicht entscheidbar ist, wird verworfen statt geraten
(kein Kandidat im Radius, oder der zweitnächste liegt innerhalb der
Eindeutigkeitsmarge).
Technisch: tools/pairlab/chain.py — CHAIN_LANDMARK_WEIGHT
(Standard 0,0, byte-identisch; KS_CHAIN_LANDMARK_WEIGHT),
CHAIN_LANDMARK_TARGET_RADIUS_UNITS (0,55), …_MARGIN_UNITS (0,25),
Energie e_landmark, Gradientenanteil landmark; Sonde
tools/pairlab/landmarklab.py (Skalen-Kalibrierung + Wirkungsmessung)
Naht (seam) — die Stelle, an der im Kettenfit ein Buchstabe endet und der Verbinder beginnt. Kunstgriff: Sie ist kein Strafterm, sondern ein geteilter Ankerindex — der letzte Anker des Buchstabens und der erste des Verbinders sind dieselben Parameter. Damit gilt Stetigkeit per Konstruktion, und die Schnittstelle sitzt überall am gleichen Index statt an einer pro Vorkommen verschiedenen Tintenlücke. Naht-Anteil (seam tail/head share) = wie viel Bogenlänge des Buchstabenendes der Verbinder für sich beansprucht; muss im gemessenen Band von 0,2–0,4 xh bleiben, sonst ist die Segmentierung eine Eigenschaft des Lösers statt der Hand.
Vereinigungsfenster vs. buchstabenlokales Fenster — woran gemessen
wird. Das buchstabenlokale Fenster ist der x-Bereich eines Buchstabens
plus Rand (TRACE_WINDOW_MARGIN 0,15 xh); das Vereinigungsfenster ist die
Vereinigung beider Buchstabenfenster mit geschlossenem Loch dazwischen
— es enthält also die Verbinder-Tinte. Der Kettenfit rechnet im
Vereinigungsfenster (das ist sein Zweck), wird aber benotet im
buchstabenlokalen (das ist der Maßstab, den der unabhängige Fit schon
immer hatte).
like-for-like Gate („gleichnamig messen“) — die Forderung, zwei Verfahren am selben Maßstab zu beurteilen. Konkreter Anlass: Stufe A verglich eine Kette, die gegen Verbinder-Tinte benotet wurde, mit einer Basislinie, die diese Tinte nie sah — der Rückstand war teilweise ein Benotungsartefakt. Erst gleichnamig gemessen wird eine Zahl belastbar.
matched arc · bogengleich — dasselbe Prinzip für Formvergleiche: Zwei Kurven dürfen nur auf dem gemeinsamen Bogen verglichen werden. Der Kettenverbinder besitzt konstruktionsbedingt die Stub-Zonen, der aus der Tinte gelesene beginnt erst an der Tintenlücke — schneidet man beide auf dasselbe x-Intervall, schrumpfte der Abstand um rund drei Viertel (0,046 → 0,011 xh). „Ein Teil der Distanz ist definitorisch, nicht Formfehler.“
Ink gap · Tintenlücke — der tintenfreie Spalt zwischen den
Tintensäulen zweier Buchstaben. Historisch das Kriterium, wo ein
Buchstabe aufhört und der Verbinder anfängt — mit der bekannten Schwäche:
bei Berührung ist es undefiniert (Median-Lücke 0,251 xh, aber in
38 von 248 Vorkommen gar keine).
Technisch: tools/pairlab/analyze.py::_ink_extent_x / _real_join.
Stub · Kopplungs-Stub — die kurzen An- und Absatzstriche, die auf der Lehrtafel an jeder isolierten Buchstabenzelle stehen (Entry-Stub: Anstrich von halber Höhe; Exit-Stub: Grundlinienfuß nach oben). Im verbundenen Wort existieren sie nicht — die echte Feder verlässt die Form am letzten Strukturpunkt. Wer über die Stub-Spitzen hinweg verbindet, baut ein „Shelf“ ins Wortbild. Gemessene Ersatzlänge 0,2–0,4 xh je Seite. → uebergaenge-befund.md §5
tail_adapt · head_adapt — wie weit die echte Feder die Glyphe selbst für den Übergang umschreibt: die Bogenlänge (in xh) ab der Verbindung, über die der letzte Strich von A bzw. der erste Strich von B von der Template-Form abweicht (Schwelle 0,12 xh). Die Zahl beantwortet die Frage „ist der Fehler im Verbinder oder schon im Buchstabenende?“.
tail_stub_delta — die Kennzahl des zugehörigen Kill-Kriteriums: wächst dieser Wert unter einem neuen Verfahren systematisch, zieht das Verfahren die Buchstaben-Auslauf-Enden mit — dann ist die gemeinsame Optimierung das Problem statt die Lösung. (Gemessen wurde das Gegenteil: −0,006 xh.)
Huber-Kappung — ein robustes Fehlermaß: kleine Abweichungen zählen
quadratisch, große nur noch linear. Wirkung: ein Tintenklecks oder eine
fremde Spur im Messfenster kann den Fit nicht mehr beliebig ziehen.
Technisch: CHAIN_COVERAGE_CAP_UNITS = 0.30 xh in tools/pairlab/chain.py.
Bézier-Handle-Floor — ein konkreter Bug-Fund, der zur stehenden
Redewendung wurde. Der Verbinder-Generator berechnet die Länge seiner
Bézier-Griffe (die Kontrollpunkt-Hebel, die die Kurvenform bestimmen) als
handle = max(0.05, min(0.4·Sehne, 0.5·Δx)) — mit einer Untergrenze von
0,05 xh. Diese Untergrenze („floor“) ist im Rendering harmlos. Sitzen
zwei Buchstaben aber fast aufeinander, überschreibt sie den eigenen
Entwurfswert 0,4·Sehne: die Kubik greift weiter aus, als die Sehne lang
ist, und kehrt um.
Technisch: tools/pairlab/analyze.py::_generate_connector
→ uebergaenge-befund.md §5c „Nachtrag: degenerierte Solves“
Cusp-Connector — das Ergebnis dieses Handle-Floors: ein Verbinder, der in einer Spitzkehre (engl. cusp — eine Stelle, an der eine Kurve umkehrt statt weiterzulaufen) zusammenfällt. Alle 24 Stützpunkte liegen dann in ~0,05 xh Bogenlänge, benachbarte Punkte 8·10⁻⁵ xh auseinander. Als Bild egal, als Startwert für einen Optimierer fatal (siehe degenerierte Solves).
degenerierte Solves — Optimierungsläufe, die formal durchlaufen, aber
das Falsche optimieren. Konkret: Der Glättungsterm skaliert mit 1/ds²
(ds = Ankerabstand); bei einem Cusp-Connector geht der Verbinder-Block
damit rund 10⁷-fach steifer in die Hesse-Matrix ein als bei einem
normalen Übergang. Ergebnis: 24 von 248 Vorkommen verbrauchten ihr ganzes
Iterationsbudget auf das Geraderichten des Verbinders — die Buchstaben
bewegten sich überhaupt nicht. Sichtbar wurde es erst, als der Bench die
Abbruchmeldung des Optimierers wirklich exportierte (er hatte bis dahin
einen Schlüssel gelesen, den niemand schrieb).
Reparatur: chain.regularise_connector_anchors — eine
Diskretisierungs-Korrektur, keine Form-Korrektur.
Sehnen-Schwelle (chord threshold) — die Grenze, unterhalb derer ein
Verbinder neu diskretisiert wird: CHAIN_CONNECTOR_MIN_SPAN_UNITS = 0.20
xh. Sie liegt in einem messbar leeren Band — alle 24 betroffenen
Vorkommen hatten eine Sehne ≤ 0,187 xh, alle 224 gesunden ≥ 0,205 xh. Ein
sauberer Diskriminator, kein getunter Schwellwert.
Degeneriewächter (connector QC) — die nachgelagerte Prüfung, ob ein
gefitteter Ketten-Verbinder plausibel eine Schreibbewegung ist, statt quer
durch beide Buchstaben zu laufen (der zweite Degenerationstyp: formal
konvergiert, QC grün, aber eine lange gerade Diagonale). Vier reine
Geometrie-Signale — Naht-Anteil, Vorwärts-Verhältnis (net_dx / arc),
Bogen-zu-Lücke, Geradheit×Länge — hinter einer Mindest-Sehne, kalibriert
an den 11 bekannten Drill-Fällen (11/11 erkannt, ein nachweisbarer
Fehlalarm auf 179 belabelbaren Wortzeilen). Solange dieser Wächter nicht
auf beiden Sets fehlalarmfrei sitzt, bleibt pair_aggregates für
Ketten-Verbinder gesperrt.
Technisch: tools/pairlab/connector_qc.py::connector_degenerate,
Spalte chain_conn_degenerate im chainbench-Report.
Kill-Kriterium — ein vorab festgelegtes Ergebnis, bei dem ein
Vorhaben abgebrochen wird. Für Stufe A des Kettenfits waren es drei:
wachsende tail_stub_delta, Divergenz auf den Versalien und eine
Naht, die aus dem gemessenen Band läuft. Keines schlug an. Der Zweck ist
Disziplin: Man legt die Abbruchbedingung fest, bevor man die Zahlen
sieht.
M1 · M2 · M3 · M4 (die vier Kettenfit-Kennzahlen) — die Stufe-A-Prüfung von Issue #278. Sie tragen dieselben Buchstaben wie die MVP-Meilensteine (§5) und wie der „M4-Fit“, meinen aber etwas anderes — im Zweifel den Kontext prüfen.
- M1 — Konvergenz. Frage: Konvergiert der Kettenfit pro Buchstabe
mindestens so oft wie zwei unabhängige Fits? Berechnung: Anteil der
Buchstabensegmente, die beide Konvergenz-Tore von
core/fit.pybestehen, gemessen im buchstabenlokalen Fenster (like-for-like). Stand: Basislinie 0,746 · Kette 0,754 über 248 Vorkommen — erfüllt, nachdem die degenerierten Solves repariert waren (vorher 0,690). Untergrenze für Stufe B: 0,754. - M2 — heute unmessbare Übergänge. Frage: Wie viele Verbindungen,
bei denen die heutige Zerlegung nichts liefert (weil die Buchstaben
sich berühren), macht die Kette messbar? Berechnung: Anteil der
Vorkommen mit leerem
_real_join, für die die Kette einen konvergierten, mit Tinte belegten Verbinder liefert. Stand: 33 von 38 = 87 % — erfüllt. Das ist das stärkste Einzelargument des Verfahrens. - M3 — Verbinderform. Frage: Liegt der Ketten-Verbinder so nah an
dem aus der Tinte gelesenen Zug wie der erzeugte? Berechnung:
dconn(§4) zwischen den beiden Mittellinien, bogengleich beschnitten. Stand: erzeugt 0,028 xh · Kette 0,040 xh (n = 193) — wörtlich verfehlt, aber nur noch um 0,011 statt 0,046 xh, und der Rest sitzt in einer Klasse: dem Schleifen-Exit (d, ſ) mit +0,17 xh. Deshalb bleibt der Bann, dass Ketten-Verbinder nicht inpair_aggregatesfließen dürfen —gen_chamferlebt davon, unkontaminiert zu sein. - M4 — Buchstabenform gegen das Rauschen. Frage: Verbiegt die Kette die Buchstaben stärker, als die Hand ohnehin streut? Berechnung: mittlere Ankerabweichung Kette ↔ unabhängiger Trace, verglichen mit dem MAD-Boden aus den H1-Aggregaten derselben Hand. Stand: 0,0269 xh gegen einen Boden von 0,0112 xh — knapp verfehlt, aber ohne Verzerrungssignal: gegenüber der Chart-Zeile verformt die Kette weniger (0,0140 vs. 0,0170 xh). Sie verbiegt die Buchstaben nicht stärker, sie stellt sie anders hin.
Score · loss · bench_loss — Ein Score geht von 0 bis 100 (100 =
perfekt), loss = 1 − score/100 ist dieselbe Information in der
Loop-Konvention „kleiner ist besser“. bench_loss ist der
Mittelwert der Einzel-Losses über alle Fixtures — bewusst Mittelwert
statt Median, damit eine einzelne verschlechterte Glyphe die Kopfzahl
sichtbar bewegt. Ein Absturz zählt als 1,0. → qualitaetsmetrik.md §1
pair_loss — dieselbe Kopfzahl für das getrennte Set der isolierten
Buchstabenpaare (Abb. 20). Wörter und Paare bekommen eigene Headlines und
werden nie gemittelt. Der aktuelle Stand steht bewusst nicht hier:
eine Zahl in zwei Docs veraltet in einem davon (dieser Satz nannte bis
2026-09-02 noch den Lauf aug02). Er wohnt im Status-Blockquote von
qualitaetsmetrik.md, seine Historie samt Fixture-Wurzeln im
Headline-Ledger am Kopf von §14. → qualitaetsmetrik.md §6 ·
messjournal.md §14
Chamfer-Distanz — ein Standardmaß für „wie weit sind zwei Formen auseinander“: für jeden Punkt der einen Form der Abstand zum nächsten Punkt der anderen, gemittelt. Symmetrisch (beide Richtungen) oder gerichtet („Vorwärts-Chamfer“). Kommt in fast jeder Kennzahl dieses Projekts vor.
Dice — das Flächenmaß daneben: doppelte Überlappung geteilt durch die Summe beider Flächen (1 = deckungsgleich). Beantwortet „sieht es aus wie der Ausschnitt“, während Chamfer „liegt die Kante auf der Kante“ misst.
Öffnungsweite · Mittellinien-Öffnungsweite (D0) — wie weit ein
„Kringel“ innen offen ist, gemessen als Durchmesser des größten Kreises,
der in das Loch passt. Zwei Lesarten, die sauber auseinandergehalten
gehören: die Öffnungsweite der fertigen TINTE (das, was man sieht) und
D0, die Öffnungsweite der MITTELLINIEN-Schleife, also des Gebiets, das
die Stiftbahn selbst umschließt. Weil eine Gleichzug-Feder der Halbbreite
h die Kapsel-Union malt, ist das Tintenloch exakt die Erosion des
Mittellinien-Lochs um h, und beide hängen über Öffnungsweite = D0 − 2h zusammen. Der Nutzen von D0: es ist federunabhängig und macht
Platte, Skelett, Kettenfit und gespeicherte Zeile in EINER Zahl
vergleichbar. Fällt D0 unter 2h, verschwindet die Binnenfläche —
genau der Effekt, den der Federwechsel auf 0,097 auslöst. →
messjournal.md §14 „Ink-Clearance an die Feder sep05“ ·
notes/kringel-binnenflaechen-2026-09-06.md
Kringel-Landmarke — die Erwartung „diese Schleife muss offen bleiben"
als Eigenschaft JE BUCHSTABE und JE SCHLEIFE statt als eine Schwelle für
die ganze Hand (Autor-Entwurf 2026-09-06). Jede Schleife der Tafel trägt
zwei Etiketten, beide von der Platte abgelesen und im eingefrorenen
Kringel-Katalog (tools/tracebench/kringel_catalogue.json)
festgeschrieben:
- die Größenklasse, gezählt in Breiten der PLATTENFEDER
(
W = 2·0,0968 = 0,1936 xh), weil die Feder das Mittellinien-Loch um genauWerodiert und die Klasse damit eine Eigenschaft des Schreibgeräts ist, nicht der Stichprobe: kleinD0 < 2W(weniger als eine Federbreite Loch bleibt — ob sie offen ist, entscheidet das Gerät), mittel2W ≤ D0 < 4W, großD0 ≥ 4W; - der Zustand, aus dem Anteil der Vorkommen, in denen die Platte
überhaupt ein Loch zeigt: offen (≥ 80 %), wechselnd (dazwischen
— „je nach Tinte mal zu und mal offen"), Punktkringel (≤ 20 %; der
Kringel ist bauartbedingt ein Punkt und kann nie ein Verlust sein).
unbelegtist die vierte Marke: die Platte antwortet an dieser Schleife in keinem Vorkommen, also bekommt sie keine Erwartung.
Nur eine geschlossene offen-Schleife ist ein Defekt. Der Sensor
(tools/tracebench/kringel.py, Spalte kringel_lost im
Tintenfolger-Report) ist reine Report-Spalte wie der
Verschmelzungs-Anzeiger.
Technisch: size_class / loop_state / loop_apertures in
core/landmarks.py (von tools/tracebench/kringel.py re-exportiert;
der Katalog selbst bleibt eine Datei des Messwerkzeugs und wird
per Pfad gelesen), Katalogbau
tools/tracebench/kringelcat.py; der raster-freie Zwilling des
Schleifenfinders ist core/aggregate.py::loop_ranges
(→ Schleifenbereich). → messjournal.md §14 („Kringel-Landmarke
sep06“) · notes/kringel-binnenflaechen-2026-09-06.md
Topologie-Verlust (Kringel) — der schwerere Nachbar der zu engen
Schleife: die Komposition zeichnet an einer Stelle GAR KEINE Schleife,
wo die Platte eine Binnenfläche hält. Gemessen als Platten-Binnenfläche,
die keine Schleife ihres eigenen Slots für sich beanspruchen kann; sie
geht nie in eine Öffnungsweite ein, sondern wird je Buchstabe gezählt
(topology_losses_per_glyph im Katalogkopf). Davon zu trennen ist der
Splitter: eine komponierte Schleife unter 0,05 xh — entweder
Rasterrauschen oder eine auf nichts zusammengefallene Schleife
(collapsed_loops_per_glyph). → messjournal.md §14 („Kringel-Landmarke
sep06“)
Zwei-Züge-Modell — die Antwort auf den Verschmelzungs-Anzeiger:
statt den Klumpen zu skelettieren, wird die FEDER herausgerechnet. Wo
zwei Federzüge um eine kleine Binnenfläche verschmelzen, ist die Tinte
die Vereinigung zweier Kapseln von bekannter Halbbreite w_pen, und ein
Punkt der Binnenfläche ist genau dann eingefärbt, wenn irgendeine
Stützstelle näher als w_pen an ihm steht. Daraus wird eine harte
Aussage über die Bahn — keine Stützstelle darf näher als w_pen an
einer Binnenfläche stehen, die die Platte offen hält —, und die
Korrektur schiebt jede Stützstelle, die das verletzt, entlang des
Abstandsfeldes der Binnenfläche genau so weit hinaus. Wo die Bahn heute
der Klumpenachse folgt, trennt das die beiden Durchgänge auf
2·w_pen — die Trennung, die eine Zwei-Kapsel-Union mit überlebendem
Loch braucht.
Drei Regeln machen daraus einen Mechanismus statt eines Knopfes:
Geltungsbereich — nur Katalogschleifen im Zustand offen und in den
Größenklassen klein/mittel, und nur wo die Platte im SELBEN Vorkommen
ein Loch zeigt; Blende — die Verschiebung wird an beiden Enden ihres
Laufs über eine halbe Feder Bogenlänge glatt (C¹) ausgeblendet, damit die
Naht dem Unstetigkeits-Sensor keinen Knick liefert; Abnahme
(„Schleifen-Schluss") — das Auseinanderschieben der beiden Äste kann
die Selbst-Kreuzung aufziehen, die die Schleife überhaupt schließt, und
eine Weitung, die ihren Gegenstand zerstört, wird ZURÜCKGENOMMEN statt
gemeldet (dieselbe Bauart wie der Topologie-Wächter: eine Abnahmeregel,
kein weiterer Term). Ohne Loch bleibt nur die Strichtrennung
(stroke_separation = Klumpenbreite − 2·w_pen) als Messgröße: ihr
Vorzeichen sagt, ob die Tinte überhaupt von zwei Durchgängen stammen
kann — der Arm korrigiert dort nicht, weil nichts sagt, auf welcher
Seite welcher Durchgang lief.
Technisch: tools/pairlab/zweizuege.py, Schalter --zwei-zuege
(FollowWeights.zwei_zuege, Vorgabe AUS) im Tintenfolger.
→ messjournal.md §14 („Kette R3 Zwei-Züge-Modell sep07“) ·
notes/kringel-binnenflaechen-2026-09-06.md (Rettungsweg R3)
Verschmelzungs-Anzeiger — die Warnung davor, das Skelett für den
Federweg zu halten. Wo zwei Federzüge um eine enge Binnenfläche herum
zusammenfließen, gibt skeletonize die Mittelachse des VERSCHMOLZENEN
Klumpens statt der zwei Bahnen, und die liegt näher am Loch. Als Zahl:
die Halbbreite, die der Klumpen um die Binnenfläche trägt
((D0 des Skeletts − Öffnungsweite der Tinte) / 2), geteilt durch die
gemessene Federhalbbreite. 1,0 ist die Erwartung des Kapsel-MODELLS, in
dem beide einbeschriebenen Kreise denselben Mittelpunkt haben und die
Strichbreite lokal konstant ist — real streut das Verhältnis auch ohne
Verschmelzung, weshalb der Anzeiger vor jeder Verwendung an Stellen ohne
Verschmelzung geeicht werden muss. Deutlich darunter heißt „hier ist die
Mittelachse kein Federweg". Über die 202 gemessenen Binnenflächen der
Wortplatten steht das Verhältnis bei 0,0667 zu 0,0968, also bei rund 0,69.
Gebaut und geeicht am sep06 (§14 LF13, Rettungsweg (7) der Zeile
„Ink-Clearance an die Feder" in tintenfolger.md §7.9): die Eichung ist
kein Schwellwert, sondern eine KURVE — je weiter die Binnenfläche, desto
weniger Platz hatten die zwei Züge zu verschmelzen, und über sechs
Bänder steigt der Anzeiger monoton 0,609 → 0,646 → 0,646 → 0,733 →
0,795 → 0,878 (das S einzeln bei 0,970). Er bleibt reine
Report-Spalte: kein Öffnungs-Term wandert in einen Fit-Loss, bevor er
eingefroren ist. → messjournal.md §14 („Laufform LF13"),
notes/kringel-binnenflaechen-2026-09-06.md
Tintenabstand (ink_max / ink_mean) — Abstand der gefitteten
Mittellinie zur gemessenen Tinte (Skelett der Platte), in x-Höhen.
Das Bodenwahrheitsmaß eines Fits, und zwar in beide Richtungen: das
Maximum bepreist den Fehler (ein Stück Linie im leeren Papier), der
Mittelwert bepreist, ob eine Verbesserung des Maximums damit erkauft
wurde, dass die ganze Kette von der Tinte wegwandert. Beide zusammen sind
die Pflichtprüfung für jeden Regularisierer am M4-Fit — Formmaße allein
genügen nie (siehe Anker im leeren Papier).
→ qualitaetsmetrik.md §7
Anker im leeren Papier — die benannte Fehlerform des M4-Fits: ein
einzelner Anker verlässt den Strich und kehrt im nächsten Schritt
zurück. Physikalisch unmöglich — eine Feder schreibt Bögen und Geraden —,
für die Zielfunktion aber unsichtbar, weil dort alles Mittelwerte sind.
Ein solcher Anker vergiftet über den Vorkommens-Median die Laufform.
Gegenmittel in drei Stufen: die Vorkommensschranke verhindert, dass
ein einzelner ihn in den Schreibpfad trägt; das Spike-Gate
(anchor_spike) verwirft die unbrauchbare Messung an der Quelle; und seit
aug11 wird der Ausflug in ANGENOMMENEN Vorkommen repariert —
Interpolation der Nachbarn im eigenen Federzug, protokolliert in
measurements.repaired_anchors, das Gate urteilt weiter über die
unreparierte Geometrie. Vier Fit-Terme dagegen (Biegeenergie, Scharnier,
Eckanker-Stützung, Nachbarbindung) wurden gemessen und verworfen.
→ qualitaetsmetrik.md §7, §8, §11d, §11e
Schleifen-Sehne (LOOP_AWARE_REPAIR, tools/pairlab/anchors.py) —
die benannte Kehrseite der Reparatur des Ankers im leeren Papier: wo
der Duktus eine Binnenfläche schreibt, passt die Beschreibung des
Detektors („ein Anker, dessen beide Schritte dreimal so lang sind wie der
Median-Schritt seines Strichs") auch auf die Spitze der Schleife — die
Anker biegen dort über kurze Bogenlänge stark ab. Die Reparatur ersetzt
die Spitze dann durch die Sehne zwischen ihren Nachbarn, und weil
diese Nachbarn auf den beiden Strängen der Schleife liegen, zieht die
Sehne quer durchs Loch: die Binnenfläche schließt. Gemessen am
sep05-Bestand: von 235 angenommenen Vorkommen werden 20 repariert, 12
davon tragen eine messbare Binnenfläche — und die VIER, deren Reparatur
innerhalb eines Schleifenbereichs landet, verlieren alle vier
Öffnungsweite (Median 0,0410 xh, schlimmstenfalls 0,1068 beim g in
„Sprünge"), während die acht außerhalb um höchstens 0,0021 bewegen.
Gegenmittel ist der Schalter LOOP_AWARE_REPAIR (Default AUS):
ein markierter Anker innerhalb eines Schleifenbereichs der CHART-Zeile
(core.aggregate.loop_ranges) bleibt stehen. Der Preis ist benannt und
gewollt eng — ein echter Ausflug, der zufällig in einer Binnenfläche
landet, überlebt jetzt ins Vorkommen.
→ messjournal.md §14 „Laufform LF14 sep06"
Ernte-Fixpunkt — die Frage, ob die Ernte auf ihrer eigenen Ausgabe
stehen bleibt. Die Ernte ist eine Abbildung „Laufform-Zeilen →
Laufform-Zeilen": derive_word komponiert das Wort AUS den Zeilen, der
Kettenlöser startet auf dieser Komposition, und die gefitteten Anker
werden zu den neuen Zeilen — die Ernte liest also die Zeilen, die sie
ersetzen wird. Eine Karte heißt Fixpunkt, wenn zwischen zwei
aufeinander folgenden Ernten KEINE Zeile um mehr als 0,002 xh wandert
(die Zeilen sind auf 4 Nachkommastellen gerundet, ein echter Fixpunkt ist
also byte-gleich). Mit der heutigen Saat ist sie es nicht und wird es
auch nicht: gemessen sep06 wandert die Iteration in jedem Schritt um
0,005–0,063 xh weiter, und die Zahl der angenommenen Vorkommen wandert
235 → 232 → 239 mit. Das ist keine Nichtreproduzierbarkeit (derselbe
Befehl gibt zweimal dieselbe Karte), sondern eine Rückkopplung, und die
praktische Folge steht in werkzeuge.md: eine Re-Harvest-Karte gehört
gegen eine KONTROLLKARTE aus demselben Lauf gehalten, nie nur gegen den
Bestand — sonst wird die Iteration als Arm-Effekt gebucht.
→ messjournal.md §14 „Laufform LF14/LF15 sep06", werkzeuge.md
Chart-Saat (chain_seed="chart", tools/laufform/harvest.py) — die
Saat, die die Rückkopplung durchschneidet, und damit der Arm gegen den
fehlenden Ernte-Fixpunkt. Die Kette baut ihre Segmente ohnehin aus
den CHART-Ankern; von den Laufform-Zeilen hängen nur Platzierung,
Deckungsfenster und Registrierung ab, und alle drei kommen aus
derive_word. Die Chart-Saat lässt den Kettenlauf deshalb auf einer
Komposition OHNE Laufform-Zeilen aufsetzen — auf dem Duktus-Prior, den
keine Ernte schreibt —, während Fit, Gates, Reparatur und Median
unverändert gegen die Tinte laufen. Die Karte ist damit eine Funktion von
Tinte und Prior allein und in EINEM Schritt Fixpunkt (gemessen
byte-gleich, Vorkommen eingeschlossen). Default AUS; der Preis steht
neben dem Gewinn im §14-Eintrag.
→ messjournal.md §14 „Laufform LF15 sep06"
Spike-Verhältnis (anchor_spike_ratio, Gate anchor_spike) — die
Kennzahl hinter dem Anker im leeren Papier: größter Schritt zwischen
benachbarten Ankern, gemessen am Median-Schritt seines eigenen
Strichs, maximiert über die Striche. Absetzer zählen nie (eine
Strichgrenze ist die Hand, die neu ansetzt). Je Strich statt gepoolt,
weil ein langer Körperstrich sonst den Nenner aufbläht und einen Zacken
im kurzen Umlautstrich verdeckt. Ab MAX_ANCHOR_SPIKE_RATIO = 8,0
verwirft die Ernte das Vorkommen — nicht als Reparatur, sondern als
Aussage: eine Kette mit einer Unstetigkeit hat die Hand nie gemessen.
→ qualitaetsmetrik.md §8
gen_chamfer — die Auditzahl „gemessen vs. komponiert“. Abstand
zwischen dem erzeugten Übergang und dem an derselben Stelle aus der
Vorlage gemessenen. Sie sagt, wo und wie weit der Generator danebenliegt
— und ist damit die Grundlage jeder Entscheidung über eine Klassenregel.
Genau deshalb darf sie nie von Geometrie gespeist werden, die selbst vom
Generator abstammt (Prior-Kontamination).
doff — Platzierung: der horizontale Versatz zwischen
komponierter und gemessener Verbindung, abgelesen im Körper-Rahmen
(vom Ende der letzten Nicht-Diakritikum-Spur des linken Glyphs zum Anfang
der ersten des rechten). Nur x, weil die y-Komponente der Messung
konstruktionsbedingt keine Vorlagen-Information trägt. Nulllinie: Wörter
0,135 · Paare 0,192 xh.
dconn — Form: mittlerer punktweiser Abstand der beiden
Verbindungs-Mittellinien, beide bogenlängen-gleichmäßig auf
core.aggregate.PAIR_CONNECTOR_POINTS (24) resampelt und auf ihren
eigenen ersten Punkt gelegt. Start-aligniert, also translationsfrei —
die Platzierung ist allein Sache von doff. Kein kalibrierter
Absolutabstand, sondern ein monotones Signal: gleiche Verbindung, kleinere
Zahl = näher an der Vorlage.
dspan (ausdehnungs-normierte Formdistanz,
tools/pairlab/spanmeas.py, seit sep04) — dconns Antwort auf seinen
eigenen blinden Fleck. dconn legt beide Verbinder auf ihren START; wenn
eine Regel die Grenze zwischen Buchstabe und Verbinder verschiebt (der
Austritts-Trim von Arm J4), wird der komponierte Verbinder am KOPF länger,
ohne dass sich seine Form ändert — und dconn bucht die Verlängerung als
Formunterschied. dspan misst stattdessen den gemeinsamen Abschnitt:
beide Kurven enden am selben Ereignis, der Ankunft des Stifts auf B, also
werden sie von dort um dieselbe Bogenlänge min(arc) zurückgeschnitten
(Schnittpunkt interpoliert), auf dieselben 24 Punkte abgetastet und je auf
ihren eigenen ersten Punkt gelegt. Der Anker muss dafür der ECHTE sein:
die komponierte Seite ist spanmeas.drawn_join — der gezeichnete Zug
ohne seine zwei Tinten-Zugaben (die CONNECT_OVERLAP-Verlängerung über
beide Enden hinaus und der Rücklauf-Präfix einer Majuskel), aber MIT
jeder Änderung, die die Komposition an der Naht selbst vorgenommen hat.
Damit ist dspan blind gegen eine reine Kopf-Verlängerung — genau
der Artefakt, der bei J4 zwei Drittel des gemessenen Anstiegs ausmachte —
und weiter translationsfrei. Abnahme an J4 (§14 „Übergänge S1"): Δ
+0,0036 gegen +0,0615 bei Start-Ausrichtung derselben Kurven; die
Fallquote steigt von 19,8 % (Bench-dconn) über 31,4 % (bereinigt, aber
start-ausgerichtet) auf 48,8 % und landet damit bei der Handbereinigung
des Eintrags (51 %), die dafür einen Basislauf brauchte. Report-only wie
doff/dconn; ersetzt dconn nicht, sondern beantwortet die engere
Frage, ob das gemeinsame Stück dieselbe Form hat.
Verbinder-Mitschnitt (tools/pairlab/prodconn.py, JoinCall, seit
sep04) — wie eine Messschicht den Produktions-Verbinder an einer
Platzierung aufruft, die der Komponist nie gewählt hat, ohne seine
Grammatik zu kopieren: recording() tauscht
core.compose._connector_centerline für die Dauer EINER Komposition gegen
einen weiterreichenden Mitschneider (die Komposition bleibt dabei Item für
Item dieselbe), replay() ruft dieselbe Funktion mit den
mitgeschnittenen Argumenten erneut auf und verschiebt nur die Geometrie —
A's Austritt und die zwei Wort-Koordinaten-Flaggen fork_line/
stem_launch um A's Fit, B's Anlauf um B's (y auf der Linie, x auf dx).
Der Grund für den Mitschnitt statt einer Rekonstruktion: zwei Eingaben
sind in der Komposition nicht ablesbar — first_line ist B's
UNGETRIMMTER erster Zug (das emittierte Item ist schon um entry_trim
gekürzt, auf 35 % der Nähte), und der Austritt einer Majuskel ist der
Ornament-Rücklaufpunkt. Gegenbegriff: der eingefrorene Spiegel
(analyze._generate_connector), die taute Einzel-Kubik vom 2026-07-11,
die heute nur noch der Kettenfit-Init und der Paritätstest benutzen.
Produktions-Init (connector_init, chain._connector_spec, Arm
K-F sep04) — WELCHER Generator den START PUNKT des Kettenfit-
Verbinders zeichnet. "mirror" ist der historische Init: der
eingefrorene Spiegel, aus den beiden Körper-Endpunkten neu gezogen;
"production" nimmt die Kurve, die core.compose._connector_centerline
beim Komponieren DIESES Wortes zurückgegeben hat (Verbinder-Mitschnitt,
prodconn.joins_for) — mit Girlande, Gabel und Absatz-Ritt, die der
Spiegel nie bekommen hat. Warum das nur ein Startpunkt ist und keine
Zielfunktion: der Verbinder trägt reg_w = 0 (kein Tikhonov-Term,
bindende Bedingung 3 von chain.py), seine beiden Endanker gehören per
_seam_ownership den Nachbarbuchstaben, und der Glättungsterm misst
Krümmungs-ÄNDERUNG, nicht Abstand zur erzeugten Bézier. Was der Init
mitbewegt und was darum in jedem Vergleich mitgenannt wird: die
Anker-ANZAHL des Verbinder-Blocks und damit seine Diskretisierung
(_second_difference_operator friert seine ds am Start ein) — dieselbe
Eigenschaft hat der Spiegel, sie ist keine Zielfunktions-Änderung. Der
Ernte-Pfad (laufform.harvest --path chain) behält seinen eigenen
Default, damit keine gespeicherte Bahn sich still mitbewegt. Gemessen
und verworfen (§14 „Kette K-F sep04"): "mirror" bleibt Default.
Der bleibende Befund ist dabei nicht der Verbinder, sondern der
Prüfstand — für 23 der 63 Wörter weicht das Anker-Array der beiden
Inits um höchstens 1,8·10⁻¹⁵ ab, und auf dieser Null-Änderung kippen
neun Wächter-Verdikte mit aiou-Ausschlägen bis +0,0800; das
0,003-Gate der Kettenarme entscheidet auf dieser Ebene also nichts
mehr.
Anker · Sample · Schritt — die drei Sorten Punkt, die im Fit alle wie
Punkte aussehen und ständig verwechselt werden. Anker sind die
Stützpunkte der Spline, also die Freiheitsgrade des Fits (120 je Buchstabe,
templates.anchors). Samples liegen auf der Spline zwischen ihnen — und
NUR dort liest die Zielfunktion die Tinte ab (~180 je Buchstabe); kein Anker
wird je selbst befragt. Schritt ist der Abstand zweier benachbarter Anker,
worauf anchor_spike_ratio misst. Ein Anker wirkt also nur mittelbar, über
die ein bis zwei Samples in seiner Umgebung; wer die Rückstellkraft am
Ankerort misst, beziffert eine Kraft, die in der Rechnung nicht vorkommt —
was einmal eine Fehldiagnose gekostet hat. Achtung auch beim Zeichnen:
fitted_polyline_px ist die SAMPLE-Reihe, nicht die Ankerreihe.
Nachbarbindung (core.fit.DEFAULT_SMOOTH_WEIGHT,
chain.CHAIN_LETTER_BIND_WEIGHT) — der Fit-Term gegen den Anker im leeren
Papier: die zweite Differenz der Verschiebungen je Federzug. Eine
Verschiebung des ganzen Strichs kostet exakt nichts, ein einzelner Anker, der
seine Nachbarn verlässt, quadratisch. Das unterscheidet ihn von den beiden
verworfenen Vorläufern: der Biegeterm (§7) nahm die zweite Differenz der
ANKER und bepreiste damit die Krümmung, aus der eine Schrift besteht; das
Scharnier (§8) bepreiste den Abstand („ein Sprung auf nahe Tinte ist immer
noch ein Sprung"). Existiert zweimal, weil es zwei Fit-Pfade gibt — im
Einzelbuchstaben-Fit und in den BUCHSTABENBLÖCKEN der Kette, wo alle
gespeicherten Vorkommen herkommen; nicht zu verwechseln mit
CHAIN_CONNECTOR_SMOOTH_WEIGHT, der die ANKER eines frei erfundenen Verbinders
glättet. Gemessen und verworfen (§11d): der Term wirkt — gestrandete Anker
−58 %, Spike-Verhältnis −45 % — und verschiebt trotzdem 18 % mehr Anker aus
der Tinte heraus, weil ein gebremster Anker seine Nachbarn mitnimmt. Aus einem
Anker im leeren Papier werden drei. Beide Gewichte bleiben auf 0.
→ qualitaetsmetrik.md §7, §8, §11a, §11d
Zirkuläres Kriterium — der Fehlschluss, einen Eingriff an einer Kennzahl zu
messen, die er selbst bestraft. Zweimal gemessen dokumentiert: die
Nachbarbindung senkt anchor_spike_ratio per Konstruktion, und weil das
Ernte-Gate denselben Grund führt, sah ihr Mehr-Ertrag (209 → 218 angenommene
Vorkommen, McNemar p = 0,021) wie ein Produktgewinn aus — jeder Gewinn war
ein zuvor mit anchor_spike abgelehntes Vorkommen, während die echte
Konvergenz schlechter wurde. Gegenmittel und Pflicht jeder Vorregistrierung:
ein Kriterium, das weder in der Zielfunktion noch im Gate steht (hier der
Abstand des gespeicherten Ankers zur Tinte). → qualitaetsmetrik.md §11b, §11d
Gradientenzerlegung (chain.gradient_decomposition, tools/pairlab/gradlab.py)
— die Diagnose, die vor jedem neuen Fit-Term steht: die Kraft je Term und
je Anker am gefundenen Optimum. Ein Optimum ist ein Punkt, an dem sich die
Kräfte aufheben; welcher Term einen Defekt festhält, ist damit eine
Messfrage, keine Vermutung. Bauregel — und der Grund für den Namen:
die Terme werden einzeln gerechnet und ihre Summe gegen den echten
Gradienten geprüft (GRADIENT_SUM_RTOL), sonst beschreibt die Diagnostik
eine andere Zielfunktion als die, der der Löser gefolgt ist. Gelesen wird
immer gegen eine Kontrollpopulation (dieselben Terme an den unauffälligen
Ankern derselben Lösung): ein Term, der am Defekt genauso stark zieht wie
überall, erklärt ihn nicht. → qualitaetsmetrik.md §11
Technisch: core/fit.py::_sampling_operator,
core/template.py::build_sample_plan → vom-scan-zum-schreiben.md Schritt 4
d_end (verworfen) — Abstand des Kettenendes eines gefitteten
Buchstabens zur nächsten Tinte, in x-Höhen; gedacht als „Nahtstellen-Kennzahl"
für die Fehlerart E („Knick nur am Rand"). Sie hat ihr vorregistriertes
Bestätigungskriterium auf der Rückhaltemenge bestanden (AUC 0,764,
p = 0,012) und wird trotzdem nicht geführt: gegen die anderen Fehlerarten
trennt sie auf Zufallsniveau (E gegen W/B 0,539), ist also nicht
nahtspezifisch, und sie bleibt hinter dem längst berechneten peak zurück
(0,888 für „irgendein Mangel" gegen „gut"). Der Eintrag steht hier, weil der
Name in §9/§10 vorkommt und weil „bestätigt, aber unbrauchbar" die Lehre der
Runde ist. Technisch: qualitaetsmetrik.md §10
meas (Report-Spalte) — die Zeile, die doff und dconn je
komponierter Verbindung im Wordbench-Report ausweist, plus Blockmediane
und meas_excluded. Ausgeschlossen (gezählt, nie stillschweigend): Zeilen,
deren Dissektion die Ernte selbst verworfen hat (fit_ok), und
Verbindungen, die aus einem freigegebenen Override gerendert wurden — ein
Override misst gegen sein eigenes Quell-Specimen konstruktionsbedingt ~0.
Technisch: tools/wordbench/pairmeas.py
Report-Spalte — eine Zahl, die nie in den Loss eingeht. Bauweise
im Repo streng festgelegt: eigener try/except, angehängt nach dem
stabilen Block, und der Headline-Nachweis ist Pflicht — ein Lauf vor
und nach der Einführung muss bis zur letzten Stelle identisch sein. Die
Linie dieser Spalten: Slant (R5) → Gleichzug (jul30) → meas (aug02)
→ Naht-Winkel (sep02) → Unstetigkeit (sep06).
Slant-Spalte — Report-Spalte, die die gemessene Schräglage der Vorlage
gegen die der komponierten Zeile stellt (90° = senkrecht), aus dem
Spaltenprofil. tools/wordbench/slant.py.
Gleichzug-Audit — Report-Spalten für zwei physikalische Invarianten
einer Gleichzug-Schrift: (a) EIN FLUSS — aufeinanderfolgende
Pen-down-Elemente müssen Ende-an-Anfang schließen (eine Lücke heißt: der
Stift ist gesprungen); (b) EINE STRICHBREITE — zwei fast parallele
Pfadstücke in einem bestimmten Abstandsband lesen sich als doppelt breiter
Strich („Doppelung“). Exaktes Nachfahren (Retrace) und transversales
Kreuzen sind erlaubt. tools/wordbench/gleichzug.py.
Naht-Winkel (seam_deg) — wie stark die Feder an der Naht
abknickt, also dort, wo ein generierter Verbinder den Buchstaben verlässt
(dep, Abgang) und den nächsten erreicht (arr, Ankunft). Gemessen wird
die Richtungsdifferenz Abgehend minus Ankommend in Schreibrichtung, in
Grad, positiv = die Feder dreht gegen den Uhrzeigersinn; das Fenster ist
mit 0,05 xh Bogenlänge bewusst kleiner als die 0,12 xh, auf die der
Composer seine Verbinder-Tangenten ausrichtet — auf dem Fenster der
Konstruktion selbst gemessen wäre der Restknick per Definition null. Auf
der eingefrorenen 1922er Worttafel geht der Verbinder im Median +11,87°
steiler ab, als der Buchstabe zuletzt lief, und kommt −3,26° flacher
an (Prüfung 2026-09-02, 206 von 214 Joins). Ausgeschlossen und gezählt:
Verbinder mit vorangestelltem Versal-Rückzug (deren „Abgang“ ist eine
gewollte 180°-Kehre). Echte Kehren (ſ/w/r/v) bleiben drin — Duktus, kein
Defekt. Report-Spalte, nie Teil des Loss.
Technisch: tools/wordbench/seam.py::seam_angles, SEAM_WINDOW;
Blockzeilen seam_dep_median / seam_arr_median (vorzeichenbehaftet) und
seam_*_abs_median. → tools/wordbench/README.md
Unstetigkeits-Sensor (Report-Spalten cont_*, seit sep06) — der
Sensor, der als erster die Größe misst, die der Autor tatsächlich sieht:
nicht wie WEIT die komponierte Mittellinie von einer Referenz liegt,
sondern ob sie mit sich selbst stetig ist. Anlass ist sein Leitsatz
vom 2026-09-06 — auffällig sind „die plötzlichen Änderungen an Stellen, wo
sie nichts zu suchen haben, weil da kein Richtungswechsel ist", während
der genaue Radius eines Bogens egal ist. Genau umgekehrt messen alle
Lineale, die ein komponiertes WORT beurteilen: bench_loss, dtw_xh,
dconn/dspan sind Abstände, und ein Knick und ein glatter Bogen durch
dieselben Endpunkte bekommen dieselbe Zahl. Referenzfreie Formterme hat
die Natürlichkeitsmetrik (Glätte · Eckenschärfe · Kollinearität) —
aber am einzelnen Buchstaben; dieser Sensor ist ihr Wort-Verwandter, nimmt
die Duktus-Ereignisse aus und liest Unstetigkeit statt Oszillation.
Gemessen wird auf den komponierten Federzügen an
jedem Punkt, der KEINE Landmarke ist (Federabsetzen, durchstoßende
Kreuzung, Retrace-Zone, Umkehrecke — je eine Feder Radius, alle vier
gezählt): Knick, Wackler, Pfeilhöhe (bow_median über das
ganze Wort, bow_join in der Umgebung der generierten Verbinder) und
curv_loss, die tiefste flache Stelle, die auf beiden Seiten eine
Wölbung hat. Die Fenster sind aus der FEDER abgeleitet, nicht aus einer
Runde: halbe Feder (0,0725 xh) für die Richtung, eine Feder (0,145) als
Rand und Landmarken-Radius, zwei Federn (0,29) als Sehne. Report-Spalten,
nie Teil des Loss. Technisch:
tools/wordbench/continuity.py::continuity, KINK_WINDOW_UNITS ·
BOW_CHORD_UNITS · LANDMARK_RADIUS_UNITS · KINK_THRESHOLD_DEG →
messjournal.md §14 („Übergänge S2")
Knick (kink_max_deg, kink_count) — eine Richtungsänderung, die
an EINEM Punkt sitzt, obwohl dort kein Duktus-Ereignis ist: der Weg läuft
gerade, springt von 30° auf 40° Steigung und läuft gerade weiter. Gemessen
als die am Punkt KONZENTRIERTE Drehung, |2·turn(W₁) − turn(2·W₁)| über
die rückwärtige und vorwärtige Sehne — für einen Kreisbogen jedes Radius
exakt 0, für eine Ecke zwischen zwei Geraden exakt der Knickwinkel. Damit
misst die Zahl Unstetigkeit, nicht Krümmung, und ein enger Bogen des
Alphabets löst sie nicht aus. Gezählt wird ab θ = arcsin(0,2) =
11,537° — der Winkel, bei dem der Weg seine glatte Fortsetzung um ein
Zehntel der Strichbreite verlässt; das Verhältnis ist federunabhängig,
weil das Lesefenster die halbe Federbreite ist. Nicht zu verwechseln mit
Knick am Rand (E), der humanbench-Fehlerklasse, die derselben
Erscheinung mit dem Auge begegnet. Technisch:
tools/wordbench/continuity.py
Wackler (wobble) — das Zittern MITTEN im Zug: die Laufrichtung
schwankt hin und her, statt einem Trend zu folgen. Gemessen als Hochpass
auf das Richtungsprofil — die Richtung über die halbe Feder, entfaltet,
minus ihrem bogenlängen-gewichteten gleitenden Mittel über die Sehne —,
gemeldet als RMS in Grad. Gerade und sauberer Kreisbogen lesen beide ~0,
also zählt nur die Oszillation. Der geometrische Zwilling der
humanbench-Fehlerklasse Gewackel (W) und der Wort-Nachbar des
Glätte-Sensors, der dieselbe Größe auf einer einzelnen
Laufform-Zeile zählt. Technisch: tools/wordbench/continuity.py
Natürlichkeitsmetrik (Sütterlin) — die zweite, referenzfreie Metrik:
Weil Sütterlin einen pixeligen Scan mit konstanter Strichbreite hat, wäre
Pixeltreue das falsche Ziel. Stattdessen score = 100 · Tor^0,5 · Natürlichkeit — die Deckung ist nur das Tor (eine glatte Glyphe am
falschen Ort kann nicht hoch scoren), entschieden wird über fünf Terme am
gerenderten Verlauf: Glätte · Vertikalität · Eckenschärfe · Kollinearität
· Rückzug-Treue. Zwei Metriken, eine pro Schrift — ein kombinierter
bench_loss über Schwellzug und Gleichzug wäre bedeutungslos.
core/quality_suetterlin.py → qualitaetsmetrik.md §5
Messboden — die Erkenntnis, dass 100 nicht erreichbar ist: runde Federkappen gegen eckige Balkenenden, ±0,5 px Binarisierungs-Unsicherheit an jeder Kante eines Drucks von 1866. Praktisch heißt das: hohe 80er / niedrige 90er ≈ im Rahmen der Messbarkeit perfekt.
Frozen-Reference-Regel — die Torpfosten stehen fest. Eingefroren sind
Maske, Skelett, EDT, die geshapten Slots, die Template-Zeilen, der
gepoolte Nib und (seit aug02) pair_instances.json. Ein Experiment kann
die Metrik nicht dadurch „verbessern“, dass es die Binarisierung
verschiebt oder das Ziel neu exportiert. Während eines
Optimierungs-Loops sind zusätzlich Metrik-Module und Tests eingefroren:
geändert wird der Composer, nie das Lineal.
Re-Baseline — der bewusste, menschlich entschiedene Neu-Export dieser Referenzen. Zahlen über eine Re-Baseline hinweg sind nicht vergleichbar und werden im Journal ausdrücklich als solche markiert.
Wurzel-Digest (root_digest) — der Fingerabdruck einer
Fixture-Wurzel, damit man einer Kennzahl ansieht, worauf sie gemessen
wurde: SHA-256 über die sortierte Liste aus (relativem Pfad, Größe,
SHA-256 der Bytes) aller Dateien der Wurzel. Deterministisch (die
Sortierung ist die einzige Reihenfolge), blind für DATEISYSTEM-Zeitstempel
und Rechte (eine kopierte Wurzel behält ihre Identität), empfindlich schon
gegen ein einzelnes gekipptes Byte oder eine bloß hinzugefügte Datei.
Der Digest identifiziert damit einen EXPORT, nicht einen DB-Stand
(Befund sep02, §14 „Laufform LF11 — humanbench-Wortrunde"): das
exported_at im manifest.json ist Inhalt und geht mit ein, also
bekommen zwei Exporte derselben unveränderten Daten verschiedene Digests
und messen trotzdem identisch. Zu zitieren ist der Digest der Wurzel, auf
der wirklich gemessen wurde; ein Neu-Export verlangt einen neuen Digest,
ohne dass sich eine Zahl bewegt. Weil die
Wurzeln gitignored sind, hinterlässt ein Neu-Export sonst keine Spur — die
Prüfung vom 2026-09-02 fand ein Zahlenpaar, dessen Grundlage niemand mehr
rekonstruieren konnte (die undeklarierte Re-Baseline). Hausregel:
jede genannte Headline nennt exported_at + die ersten 12 Hex daneben;
--expect-root <Präfix> macht die erwartete Grundlage zur Vorbedingung und
bricht vor dem Messen ab.
Technisch: tools/wordbench/roots.py — EINE Umsetzung für alle Bänke
(root_digest, check_expected_roots, announce_roots, der Flag-Helfer
add_expect_root_argument), Kopfzeilen root: / digest=, volle Digests
im --json-Report unter roots; im Wordbench prüft derselbe Vorspann
zusätzlich das page_sha256 des Manifests gegen die Tafel-Bytes.
Seit sep05 tragen den Sensor alle Messeinstiege, die eine
Fixture-Wurzel lesen: tools.wordbench.run, tools.tracebench.run ·
.k0eval · .view · .excursions, tools.pairlab selbst sowie
.follow · .spanmeas · .chainbench · .bindab · .gradlab ·
.peaklab · .landmarklab · .harvest — vorher maßen die
Duell-Werkzeuge stumm gegen die Wurzel, die gerade auf der Platte lag.
Dazu die zweite Hälfte, check_compared_roots: der Kopf nagelt den Lauf
fest, nicht das, wogegen verglichen wird — --compare, --rows und
--base lesen darum den roots-Block der gespeicherten Datei und
verweigern eine fremde Basis, bevor gemessen wird (eine Datei ohne
roots bekommt eine Warnung statt einer Verweigerung).
→ tools/wordbench/README.md
MAD (median absolute deviation) — die robuste Streuung: Median der absoluten Abweichungen vom Median. Anders als die Standardabweichung verzieht ein einzelner Ausreißer sie nicht. Im Projekt die Streuungsangabe schlechthin (MAD-Hülle je Anker, MAD-Whisker am Versatz). Hausregel: bei fehlender MAD wird kein „± 0,00“ gedruckt — und bei n = 1 gibt es keine.
laufform_dev_xh (der Prüfstein) — die Antwort auf „ist das, was die
Engine schreibt, noch das, was die Statistik sagt?“: der Abstand zwischen
dem aus den Vorkommen rekonstruierten Median und der aktuell gespeicherten
Laufform-Zeile. 0 = aktuell; ein Wert > 0 = veraltet. Wird auch schon beim
reinen Lesen der Aggregate mitgeliefert, damit die Frage ohne einen
Neuaufbau beantwortbar ist. core/aggregate.py::laufform_deviation
Prüfstein — allgemein: eine Bedingung, an der eine ganze Stufe geprüft wird und die bindend über alle Stufen gilt (z. B. „nie über Hände mitteln“, „Duktus bleibt Prior“, „Same-Hand-Headline unangetastet“). → handmodell-stufenplan.md §5
Same-Hand-Disziplin — Kopfzahlen werden nur gegen Vorlagen derselben Hand gebildet. Die Abb.-22-Schülerschrift ist ein anderer Schreiber und läuft als eigenes Set mit eigener Zahl, nie in der Headline. Fremde Hände sind Kontext, nie Maßstab.
Segment-Attribution — die Zerlegung eines Wort-Losses auf seine Teile:
welcher Buchstabe und welcher Übergang trägt wie viel. Erst damit ist ein
Score handlungsfähig („der zweite n-Bogen kostet 0,11“ statt „das Wort ist
0,19“). core/word_metric.py::score_word_segments
glyphbench · wordbench · pairlab · chainbench · glyphlab · wordlab — die Werkzeugfamilie. Benches messen (glyphbench: einzelne Buchstaben gegen eingefrorene Referenzen; wordbench: komponierte Wörter und Paare gegen echte Wortproben; chainbench: die beiden Fit-Pfade gegeneinander). Labs zeigen: matplotlib-Overlays, aus denen man sieht, warum eine Zahl schlecht ist (glyphlab: die Ableitung eines Buchstabens; wordlab: ein komponiertes Wort über seiner Vorlage mit Penalty-Callouts; pairlab: die Sektion eines Übergangs). Daneben steht als dritte Gattung humanbench, das nicht rechnet, sondern fragt: es baut den blinden Bewertungsdurchgang und wertet dessen Urteile aus. Merksatz aus den Läufen: die Skizzen des Autors waren das Messinstrument, der Bench der Regressionswächter. → werkzeuge.md
Fixture-Wurzel — das eingefrorene Eingabepaket eines Bench-Sets
(Crops, Masken, Skelette, Slots, Template-Zeilen, Laufform-Zeilen,
pair_instances.json, word_instances.json). Gitignored
(Open-Core-Moat), neu erzeugbar über
tools/wordbench/export_fixtures.py (DB-Pfad) oder fetch_fixtures.py
(API-Pfad, für Sitzungen ohne DB-Zugang).
Referenzsatz (nachgefahren) — die manuell per S-Pen nachgefahrenen
Wortbahnen (word_instances, Provenienz authored), an denen jeder
automatische Wortbahn-Kandidat gemessen wird. Der Entwicklungssatz
(Tuning) sind heute die 10 am 2026-08-13 nachgefahrenen Abb.-19-Wörter
(die · laden · linken · mit · muß · und · unter · Wer · will · zwei),
committete Konstante; jedes SPÄTER nachgefahrene Wort ist per Definition
Rückhaltemenge (Bestätigungssatz). Die tragende Invariante: Bewegung
gibt es nur BLIND und vorregistriert in Richtung Entwicklungssatz, nie
zurück — ein Wort, auf dem je getunt oder dessen Zahl je gelesen wurde,
kann nie wieder Prüfmaterial werden. Seit der Split-Neuziehung
(tintenfolger.md §2.5, vorregistriert 2026-08-16) ist die Rückhaltemenge
zweigeteilt: Bestätigung A (offen für vorregistrierte
Bestätigungsmessungen) und Bestätigung B (VERSIEGELT, öffnet erst
für die großen Adoptionsentscheidungen); der Entwicklungssatz wächst bei
Vollausbau der 63 Wörter deklariert um Galoppieren + das (12 Wörter /
19 Vorkommen). Ein Kandidat kann nie sein eigener Maßstab sein: die
traced-Ernte-Fits sind Ausgaben des Kandidaten, nicht seine Wahrheit.
Technisch: word_instances.json je Fixture-Wurzel;
tools/tracebench/sets.py::TRACEBENCH_DEV_IDS
→ proposals/tintenfolger.md §1 + §2.5
Frame-Gate (frame_stale) — der Maschinencheck, dass die
Registrierung einer gespeicherten Wortbahn noch die eingefrorene
Rect/Lineatur beschreibt, über deren Crop sie gezeichnet wird:
|baseline_row+ty − (baseline_y−y0)| ≤ 4 px (der vertikale Suchbereich
des Score-Gitters) und |xh_px − (baseline_y−midband_y)| ≤ 0,51 px
(halbes Pixel über ganzzahliger Lineatur). Fehlschlag STEMPELT die Zeile
(frame_stale mit Grund), droppt sie nie — Konsumenten zählen-und-
schließen-aus. Generalisiert die #334/#336-Fehlerklasse (Rect unter
gespeicherter Bahn editiert); beim --only-Refill prüft es gegen die
eingefrorenen word.json der Wurzel, beim Voll-Export gegen das Sidecar.
Technisch: tools/wordbench/export_fixtures.py::_frame_stale_reason
tracebench — der dritte Bench neben glyphbench (Buchstabe) und
wordbench (komponiertes Wort): er misst WORTBAHN-Kandidaten (Kettenfit,
Tintenfolger, InkSight, später Fusion) gegen den nachgefahrenen
Referenzsatz — Punktdistanz (dtw_xh), papertreues AIoU gegen die
Tintenmaske, Richtungs-Chamfer, Fehlerzähler an Kreuzungen/Marken/
Retraces. Ein Kandidat ist wörtlich eine word_instances-Zeile; die
Kriterien sind vorregistriert (messjournal.md §14), ein
Strukturdefekt vetot jeden Distanzgewinn. Technisch: die Mess-Module
tools/tracebench/{metric,frames,counters,sets}.py (Stufe B); Harness +
Provider folgen als Stufe C → proposals/tintenfolger.md §2
k0-Protokoll — die referenzfreie 63er-Auswertung der Ketten-Arme
(seit K0-Z aug20), das Gegenstück zum dev-19-Scoring: je Wort der
Soll-Abstand |Kreuzungen − Kompositions-Soll| + |Retrace-Zonen −
Zonen-Soll| (Soll aus ductus_soll, seit K0-S die EINE Soll-Pipeline
mit dem Wächter) plus aiou gegen die eingefrorene Maske; gepaart
über eine Basis mit Strich-Identitäts-Klassen (welche Zeilen sich
zwischen zwei Kandidaten überhaupt bewegten — verglichen werden die
geparsten Strichzüge, nicht die Datei-Bytes; in den §14-Einträgen
bis aug21 „byte-identisch“ genannt — die Grundlage der
Identitäts- und Konstruktions-Vorhersage-Gates). Die stehende
aiou-Verlierer-Schwelle je Wort ist −0,003 (Messrauschen). Bis
aug21 je Runde als Scratch-Skript neu gebaut, seither
tools/tracebench/k0eval.py. Technisch: Zähler aus
tools/tracebench/counters.py, Soll aus soll.py →
messjournal.md §14 „Kette K0-Z" (Erstform), /verify-trace
(Mess-Liturgie), werkzeuge.md (Werkzeug-Inventar)
dtw_xh — die Headline-Distanz des tracebench: unconstrained DTW
(euklidisch, in xh, symmetric-1-Schritte, beide Enden verankert, kein
Band), normalisiert durch die Länge T des optimalen Warping-Pfads (die
LDTW-Normalisierung, §6), beide Bahnen vorher arc-length-uniform
resampelt. Nur vorwärts — die Richtung ist Duktus-Wahrheit, ein
rückwärts besser passender Kandidat ist ein Duktus-Fehler
(Report-Spalte dtw_reversed_better, nie verrechnet). Eigener Name,
bewusst nicht „LDTW": Resampling + xh-Einheit machen die Zahl mit
publizierten Werten unvergleichbar. QC-Begleiter dtw_max_absorption
(max. Punkte einer Seite auf EIN Sample der anderen — der
Singularitäts-Wächter). Technisch: tools/tracebench/metric.py::dtw
Marke (mark) — die Strichklasse, die der tracebench VOR dem
Body-Vergleich herauslöst und separat zählt: ein nicht-erster Strich,
der komplett über DIACRITIC_MIN_Y (= 1 xh) schwebt und die
Bogen-Kappe nicht überschreitet — i-Punkt/-Strich, Umlautzeichen
und der u-Deckstrich. Letzterer erst seit aug26: bis dahin machte
ihn die Kappe zum Body, entgegen dieser Aufzählung und entgegen der
Erwartungstabelle MARKS_PER_KEY (→ Bogen-Kappe).
Der t-Querstrich kreuzt das Mittelband und bleibt Body (ihn zählt der
Kreuzungszähler). Gematcht per Zentroid mit Refusal; fehlende Marken
sind Co-Primär-Gate, mit gutem Body-dtw_xh nicht rückkaufbar — der
verschluckte i-Punkt ist der dokumentierte Fehlermodus des ganzen
Felds, den keine publizierte Metrik erfasst. Technisch:
tools/tracebench/frames.py::classify_strokes/match_marks
Bogen-Kappe (arc cap) — die dritte Bedingung der Marken-Klasse
(MARK_MAX_ARC_UNITS): ein schwebender Strich zählt nur bis zu dieser
Bogenlänge als Marke, darüber als Body. Sie hält aus der
Marken-Klasse heraus, was nur zufällig in der Oberlänge bleibt — ein
abgesetztes Versalien-Ornament, eine Oberlängenschleife, ein
Fit-Defekt, dessen Bahn die Tinte verlässt: solche Striche würden sonst
zur Marke erklärt und verschwänden damit aus dem Primärmaß.
Steht seit aug26 bei 1,5 xh, davor bei 0,8 — und 0,8 lag
INNERHALB der Marken-Population statt zwischen Marke und Body: auf der
eingefrorenen Referenz enden Punkte und Umlaute bei 0,652 xh, die
u-Bögen beginnen bei 1,039 xh. Die Höhe ist aus dem Breitenmodell
begründet (ein Kleinbuchstabe ist eine x-Höhe breit, ein Diakritikum
steht über EINEM Buchstaben), nicht aus der Verteilung; angehoben und
nicht gestrichen, weil die Kappe sonst ihren eigentlichen Zweck
verlöre. --mark-arc-cap reproduziert jeden alten Wert. Technisch:
tools/tracebench/frames.py. Der Marken-Nachfit hat seit aug26 eine
EIGENE Kappe (tools/pairlab/marks.py::MARK_MAX_INK_ARC_UNITS, 1,6) —
früher davon abgeleitet, entkoppelt, damit eine Lineal-Änderung nicht
still die Kandidatenseite mitbewegt.
→ messjournal.md §14 „Lineal L-U"
Retrace-Segment — zweimal beschriebene Tinte als GEZÄHLTE Zone:
zusammenhängende antiparallele Sample-Paare (Detektor
core.geometry.detect_retrace_pairs, prox 0,15 xh, ≥ 3 Samples auf
gemeinsamem 0,02-xh-Raster), wobei Hin- und Rückschenkel EINER
Aus-und-zurück-Bewegung zu einer Zone fusionieren (über die
Partner-Indizes des Detektors — sonst verweigert das Zentroid-Matching
eine Bahn gegen sich selbst, und das authored-Identitäts-Gate schlüge
auf jedem Deckstrich-Wort an). Seit den Struktur-Zählern v2
(messjournal §14 aug16) zählt ein Pass nur als Retrace, wenn
sein Partner BOGEN-NAH liegt (Lücke ≤ 1,0 xh) und der Pass keine
Spitzen-Graze ist (Arc ≥ 0,30 xh); ferne Antiparallel-Nähe ist eine
→ Berührung, ein Partner im anderen Strich eine Überlagerung.
Robusteste Vergleichszahl ist das Bogen-Verhältnis
retrace_arc_ratio, die Zonen-Counts sind die Ortsdiagnose.
Technisch: tools/tracebench/counters.py::count_retraces
Junction-Pinch — der aug17 benannte Verlustmechanismus der
Lotse-Route an Schleifenschlüssen: Der Viterbi-Ritt routet beide
Pässe eines Selbstschnitts über dieselben 1–3 Korridor-Pixel des
Skelett-Knotens; statt eines transversalen X entstehen zwei
tangentiale Y-Zusammenläufe, die das Durchstoß-Kriterium zu Recht
nicht zählt. Zwei Unterklassen mit verschiedenen Heilmitteln: der
PUNKT-Pinch (der spätere Pass belegt Korridor-Pixel erneut —
erreichbar über die Zonen-Ausweitung der Kartenfahrt, v0.7) und die
SCHLEIFEN-Klasse (der Aufwärts-Pass boardet die verschmolzene
Schiene genau auf Kreuzungshöhe, es gibt keine Wiederbelegung —
erreichbar nur über Karten-Vorfahrt an Karten-Selbstschnitten,
v0.8/v0.9). Technisch: tools/inkpilot/pilot.py
(RIDE_DOUBLE_ZONE_MARGIN_UNITS, MAP_CROSSING_WINDOW_UNITS,
MAP_CROSSING_PIN) → messjournal.md §14 „Lotse v0.7–v0.9",
proposals/tintenfolger.md §7.10
Absprung (Lotse) — ein maximaler Lauf von mindestens zwei
Punkten der Lotse-Bahn, die AUSSERHALB des Tintenkörpers liegen.
Der Körper ist die Vereinigung der Scheiben mit Radius
width_map[p] um jedes Skelettpixel p; in der
Medialachsen-Näherung ist der Abstand davon slack = edt − width_map[nächstes], negativ in der Tinte, positiv daneben, gemessen
in x-Höhen. Weil der Ritt das Skelett per Konstruktion fährt, ist
jeder Absprung von einem benannten Mechanismus gesetzt. Die
sep04-Forensik misst auf dev-19: keines der 3 350
Karten-Samples hat eine leere Bord-Umgebung (je Sample erhoben,
unabhängig vom Ursachen-Label — Fenster-Samples werden per
Konstruktion in den Brücken-Zustand gezwungen), der Schienen-Auslauf
liegt in 201 Punkten nie daneben, der gewöhnliche Ritt in 2 von
6 872 — was danebenliegt, ist Karten-Vorfahrt, und die
Ritt-Doppelzone in 49,5 % ihrer Punkte. Zwei Klassen tragen ihn:
Karten-Abdrift und Fenster-Versatz (beide unten). Technisch:
tools/inkpilot/forensics.py (ink_slack_field, jump_events,
traced_pilot_word, blame) → messjournal.md §14 „Lotse
Absprung-Forensik sep04"
Karten-Abdrift — die sep04 benannte GEERBTE Absprung-Klasse der
Lotse-Route: In einer Ritt-Doppelzone gilt Karten-Vorfahrt
(RIDE_DOUBLE_MAP_PRIORITY seit v0.5, ausgeweitet um
RIDE_DOUBLE_ZONE_MARGIN_UNITS seit v0.7), und weil
MAP_RUN_PIN_KNOTS seit v0.16 auf „bridges" steht, wird der Lauf
NICHT an die Tinte zurückgepinnt — der Folger reicht die komponierte
Karte wörtlich durch. Messbar daran, dass der Überschuss des Stifts
über die Karte im Median exakt +0,0000 ist: der Lotse fügt nichts
hinzu. Die Klasse trägt die tiefsten (bis 0,269 xh) und längsten
(Bogen bis 0,84 xh) Absprünge, ist aber KEIN Knotenphänomen: nur 5 der
11 sitzen an einem Skelettknoten vom Grad ≥ 3 (Lokalitäts-Schranke
0,35 xh), 5 haben gar keinen Knoten so nah — sie ist ein Lauf entlang
der Zone. Ihre Ursache liegt in der
PLATZIERUNG der Komposition, nicht im Folger — der Lotse macht sie
nur sichtbar; die Rettungswege stehen darum bei den Platzierungs-Armen
(§7.9). Technisch: tools/inkpilot/pilot.py
(RIDE_DOUBLE_MAP_PRIORITY, RIDE_DOUBLE_ZONE_MARGIN_UNITS,
_assemble_rides map_mask) → messjournal.md §14 „Lotse
Absprung-Forensik sep04", proposals/tintenfolger.md §7.9
Fenster-Versatz — die sep04 benannte SELBST GEMACHTE
Absprung-Klasse der Lotse-Route und der einzige Mechanismus, mit dem
die Route die Tinte aus eigenem Antrieb verlässt: In einem gepinnten
Kreuzungs-Fenster wird die Kandidatenmenge des Viterbi auf den
Karten-Zustand allein reduziert (states[k] = [(None, 0.0)]), und
_pin_map_runs/_pin_forced_runs verschieben den Lauf danach STARR,
bis seine Enden die Bord-Punkte treffen — der Bauch des Laufs wird
dabei mit hinausgetragen. In 11 von 15 Ereignissen lag die Karte
selbst auf der Tinte; Median-Überschuss über die Karte +0,0928 xh,
maximal +0,2146. Zweischneidig und darum lange unsichtbar: in 12
weiteren Fenstern zieht dieselbe Pinnung um −0,0165 xh ZURÜCK zur
Tinte, sodass die Summe unauffällig bleibt und die v0.9/v0.11-Gates
bestanden wurden. Benannte Konversionen: formtreue statt starrer
Pinnung, und map_slack_xh als Nie-schlechter-als-die-Karte-Budget.
Technisch: tools/inkpilot/pilot.py (MAP_CROSSING_WINDOW_UNITS,
MAP_CROSSING_PIN, _pin_map_runs, _pin_forced_runs) →
messjournal.md §14 „Lotse Absprung-Forensik sep04",
proposals/tintenfolger.md §7.9
Plateau-Anker — der aug19 adoptierte Pinnungs-Mechanismus der
Lotse-Route (v0.11, L1e): Jeder Karten-Selbstschnitt in einem
Fenster-Lauf erhält einen ANKER (Offset = nächster
Skelett-Verzweigungsknoten − Schnittpunkt, Suchradius 1,0 xh), und
das Offset wirkt als starres PLATEAU von ±0,35 xh statt als
Punkt-Knoten — eine Kreuzung überlebt eine lokal konstante
Verschiebung exakt (beide Pässe verschieben sich gleich, das X
wandert starr auf den Tinten-Knoten), während Punkt-Knoten das
Offset-Feld an genau der Kreuzung scheren, die sie sichern sollen
(das gemessene v0.10-Negativ: Merge/Oskulation in dichten Clustern).
Plateaus, die sich entlang IRGENDEINES beteiligten Passes
überlappen, verschmelzen GLOBAL (Union-Find über die
Anker-Identitäten) zu einem Cluster mit einem gemeinsamen
Mittel-Offset — der dichte Cluster verschiebt sich als Ganzes.
Technisch: tools/inkpilot/pilot.py (MAP_RUN_PIN_KNOTS,
PIN_KNOT_PLATEAU_UNITS, map_crossing_knots, _pin_map_runs) →
messjournal.md §14 „Lotse v0.10/v0.11 aug19"
Marken-endständige Assembly — die aug19 als Kette v2
adoptierte Formulierungsänderung (K-A): der Ketten-Kandidat emittiert
die Diakritika-Striche eines Wortes (Assembler-Kriterium: alle
Samples über DIACRITIC_MIN_Y) NACH allen Körper-Strichen, in der
komponierten Engine-Ordnung, die auch die Hand schreibt — die
v1-Assembly setzte sie je RUN zwischen die Läufe, und das
ordnungstreue forward-DTW zahlte die Sequenz-Inversion als die
gesamte unter/muß-Kollaps-Klasse (unter 0,4503 → 0,0854 bei
byte-identischer Geometrie; Kette-p90 0,236 → 0,099). Eine reine
ORDNUNGS-Änderung der Strichliste; ihre Adoption war die erste
datierte Re-Baseline eines Duell-Kandidaten (alle gepaarten
Vergleiche rechnen seither gegen v2). Technisch:
tools/laufform/harvest.py (HarvestOptions.marks_last,
chain_word_strokes), tools/pairlab/trace.py:: diacritic_stroke_units → messjournal.md §14 „Kette K-A aug19"
Entdrillung (untwist) — der aug19 adoptierte
Lotse-Mechanismus (v0.13, UNTWIST_WINDOW_UNITS = 0,5) gegen die
GEWEBE-Form der Doppel-X-Duplikate: Die Duplikat-Orte tragen mehrere
Roh-Schnitt-Ereignisse desselben Pass-Paars in kleinem Fenster
(3/5/6 Ereignisse, wo die Hand 1/1/0-mal kreuzt), Entfernen muss
darum PAARWEISE geschehen, damit die Parität die topologisch nötige
Kreuzung stehen lässt (die v0.12-Sehne entfernte alle und das X
mit). Je Ereignis-Paar wird der Wiggle-Bogen (die Seite mit der
größeren Sehnen-Abweichung) an der Sehne der beiden Schnittpunkte
GESPIEGELT — richtungserhaltend, lokal, geloggt. Gemessene Grenzen:
Geometrie allein trennt ein Gewebe nicht von einem echten ENGEN
Doppel (mits t-Paar, 0,07 xh — das 0,8-Fenster tötete es), und die
Paar-Entfernung ist PARITÄT-BLIND — die aug20-Autopsie zeigt sie
am Galoppieren-G-Kopf das echte X mitsamt seinem Duplikat fressen
(2 → 0, wo die Hand 1 schreibt); der benannte Diskriminator ist das
Lineal-Soll-Budget (eigener Eintrag). Technisch:
tools/inkpilot/pilot.py::untwist_strokes → messjournal.md §14
„Lotse v0.13/v0.14 aug19", „G-Kopf-Ritt-Autopsie aug20"
Lineal-Soll-Budget (ruler-soll budget) — die aug20-Korrektur
der soll-budgetierten Entdrillung (v0.15/v0.16): Ein Entdrillungs-Paar
darf nur fallen, wo die Ereignis-Nachbarschaft danach nicht unter ihr
Karten-Soll rutscht — und das Soll zählt der GEFRORENE
Kreuzungs-Detektor des Lineals selbst (crossing_points auf der
xh-skalierten Karte: Durchstoß-Kriterium, Arc-Floor, Merge) statt
roher Segment-Schnitte. Die Autopsie fand die rohe Zählung jeden
Karten-Schnitt ~doppelt listen (will: 10 roh gegen 4 gezählt) — exakt
wills falsches v0.15-Veto; mit Lineal-Zählung löst sich das Veto, das
G-Kopf-Veto feuert korrekt, mits echtes t-Doppel bleibt geschützt.
Gehört zur v0.16-Leiter der selektiven Pinn-Stufen (bridges ·
zones; bridges ∪ zones = all). Seit v0.17 arbeitet das Veto als
Reservierungs-Veto: das Soll wird je Entdrillungs-Pass
eins-zu-eins auf die Ereignisse gematcht, reservierte Ereignisse
sind unpaarbar — jede ZÄHL-Variante (Radius wie Delta) fällt in
dichten Clustern als Commons-Problem (unters 12 Events über
1 Soll: jede Einzelentfernung findet einen Ersatz-Matcher, die
Kaskade räumt die Stelle trotzdem leer). Technisch:
tools/inkpilot/pilot.py::map_self_intersections (Soll-Quelle),
::pin_run_mask (Stufen), UNTWIST_SOLL_BUDGET ·
UNTWIST_SOLL_MATCHING →
messjournal.md §14 „Lotse v0.16/v0.17 aug20"
Karten-Soll-Vollständigkeit — die aug20 gestellte Frage
nach den Kreuzungen, die die Karte GAR NICHT führt (Wächter
können nur schützen, was das Soll kennt) — noch am selben Tag
GEMESSEN beantwortet: die Karte ist vollständig. Die
Platzierungskarte auf der ROHEN komponierten Karte matcht
41 von 41 Hand-X des Dev-Satzes (Ortsfehler median
0,159 xh); die vermeintliche Lücke (unters t-Stamm-Doppel:
Abstieg + 0,07-xh-versetzter Rückpass, der K1b-Befund) war die
0,12-xh-ABTASTUNG von Soll-Quelle und Ritt-Bahn — eine
Auflösungs-Grenze (v0.18), keine Kompositions-Lücke. Was
karten-seitig bleibt, sind Soll-X ohne Hand-Partner (mit-2,
linken: die Karte kreuzt, wo DIESE Hand nicht kreuzt) —
Beleg-Varianz, kein Fehler. Technisch: messjournal.md §14
„Karten-Soll-Autopsie"/„t-Stamm-Ritt-Autopsie aug20",
tintenfolger.md §7.9
Doppel-X-Duplikat — die seit Lotse v0.11 dominante
Rest-Spurious-Klasse des Kreuzungszählers (4 der 6 Zählungen):
Dieselbe Hand-Kreuzung wird vom Kandidaten ZWEIMAL gezeichnet, weil
die gepinnten Fenster-Pässe doppelt durch die Knoten-Nachbarschaft
wackeln — zwei nah beieinanderliegende Kreuzungs-ORTE, von denen
einer matcht und der andere als unecht zählt. Kein
Topologie-Erfindungs-Fehler (das X ist real, nur doppelt); benannter
nächster Mechanismus: EIN X je Knoten-Cluster (Begradigung der
Fenster-Teilbahn je Pass durch den Knoten). Technisch:
messjournal.md §14 „Lotse v0.11 aug19",
proposals/tintenfolger.md §7.9
Durchstoß-Kriterium (pierce test) — die v2-Definition der
gezählten Schleifenkreuzung (Owner-Spezifikation aus dem manuellen
Audit): Eine Kreuzung existiert nur, wo eine Linie die andere
DURCHBRICHT — eindeutig auf einer Seite herein, auf der anderen
heraus, beidseitig geprüft. Formal: TLS-Gerade durch das
±0,25-xh-Fenster jedes Passes; die Fensterenden des anderen Passes
müssen auf entgegengesetzten Seiten liegen, beide ≥ 0,05 xh
(≈ halbe Strichbreite) heraus. Ersetzt die 15°-Winkel-Schwelle: eine
Retrace-Ablösung ist keine Kreuzung, wie spitz ihr Winkel auch sei,
und ein flacher Schleifen-Schluss ist eine, wie flach er auch sei
(impliziter Konditionierungs-Boden arcsin(0,05/0,25) ≈ 11,5° — darunter
beantwortet die Tinte die Frage selbst nicht). Seit v2.1 zusätzlich
RETRACE-INTERN verweigert: Ein Ring, dessen beide Chords einander
Antiparallel-Partner des Retrace-Detektors sind, ist der beiläufige
Selbstschnitt eines Hin-und-zurück-mit-Ablösung, keine
Struktur-Kreuzung; für antiparallel-benachbarte Paare liegt der
effektive Boden damit bei der Detektor-Toleranz 25°. Gezählt werden
Kreuzungs-ORTE, nicht -Ereignisse. Technisch:
core/landmarks.py::_pierces (von tools/tracebench/counters.py
re-exportiert), Konstanten
PIERCE_WINDOW_UNITS/PIERCE_MARGIN_UNITS/CROSS_PARTNER_NEAR_UNITS
→ messjournal.md §14 (Struktur-Zähler v2 + Nachtrag v2.1)
Berührung (Struktur-Zähler) (touch) — Vorbeischreiben statt
Retrace: zwei Passagen derselben Bahn laufen nahe und entgegengesetzt
(der Retrace-Detektor flaggt sie), aber zwischen ihnen liegt entlang
des Wegs mehr als 1,0 xh — die Feder kam später wieder vorbei, sie
fuhr nicht zurück. Eigene gezählte und berichtete Klasse neben
Retrace und Überlagerung (Partner im anderen Strich), nie Teil eines
Loss; auf der Duell-Seite gepunktet gezeichnet. Die v1-„erfundenen
Retraces" der Kette waren überwiegend erfundene Berührungen — die
Komposition schreibt Buchstaben zu eng aneinander vorbei.
Technisch: core/landmarks.py::structure_zones (von
tools/tracebench/counters.py re-exportiert),
RETRACE_MAX_PARTNER_GAP_UNITS
→ messjournal.md §14 (Struktur-Zähler v2)
Duell-Ansicht — die Sichtbarmachung des Tintenfolger-Duells: ein
selbst-enthaltenes HTML, das je Wort ALLE Bahn-Kandidaten als
schaltbare Ebenen über dem echten Crop zeigt, die Hand-Nachfahrung
immer als grüne Referenz, plus die Schreib-Animation — ein Play-Knopf
animiert alle sichtbaren Bahnen synchron in Schreibreihenfolge
(stroke-dashoffset, konstante Stiftgeschwindigkeit in xh, Absetzen
als echte Lücke). Finale Form UND Entstehung, nebeneinander statt als
Zahlenzeile. Technisch: tools/tracebench/view.py
→ proposals/tintenfolger.md §4c
Residualprofil — die Kurve unter jedem Wort der Duell-Ansicht, die
je Verfahren zeigt, WO die Kopfzahl dtw_xh herkommt: x = Bogenlänge
entlang der Hand-Nachfahrung (nur Tinte, Absetzer als gestrichelte
Marker), y = Abstand der Kandidaten-Bahn in x-Höhen. Kein naives
Punkt-n-gegen-Punkt-n bei gleicher Punktzahl (das verschöbe nach der
ersten Extraschleife alles Folgende zum Phantomfehler), sondern der
per-Sample-Abstand ENTLANG der optimalen DTW-Zuordnung, die auch die
Kopfzahl mittelt — deshalb ist der Mittelwert über alle
Zuordnungspaare exakt dtw_xh, und das Profil kann der Zahl nie
widersprechen. Flach nahe 0 = sauber, Berge = daneben; Marken bleiben
wie in der Kopfzahl außen vor; die Anzeige-Dezimierung behält je
Fenster das SCHLECHTESTE Sample (ein Ausreißer kann nicht
weggeglättet werden), und Hover setzt eine Sonde an die entsprechende
Wortstelle. Technisch: tools/tracebench/view.py::residual_values
(über den Warping-Pfad metric.DtwResult.pairs — Anzeige-Zugang zur
Zuordnung, zahlenneutral) → reference/messjournal.md §14
Chronik (tracebench) — die create-only Rundenhistorie des Duells:
jeder Optimierungs-/Mess-Lauf wird als zeitgestempeltes Verzeichnis
NEBEN dem privaten Archiv-Klon abgelegt (Artefakte + Duell-HTML +
INDEX-Zeile), nach der dbsnapshot-Disziplin — nie löschen, nie
überschreiben, leere Snapshots verweigert, nichts davon im Repo
(Bahndaten sind gelernter Datensatz, Open-Core-Regel). So bleibt der
Fortschritt über die Folger-Runden browsebar; die spätere öffentliche
Methoden-Seite bedient sich HIER, als bewusste
Produkt-Flächen-Entscheidung. Technisch:
tools/tracebench/chronik.py (KS_CHRONIK_ROOT ·
$KURRENTSCHRIFT_ARCHIVE-Nachbar) → proposals/tintenfolger.md §4c
Route G (prior-free control) — der Kontrollkandidat des
Tintenfolger-Duells: gewinnt eine Schreibreihenfolge AUS DER TINTE
ALLEIN — Skelett → Segmentgraph → Greedy-Traversierung per
Gute-Fortsetzung — und macht damit erstmals messbar, was der
Duktus-Prior wirklich kauft (die Differenz zu Kettenfit/Folger auf
denselben 10 Dev-Wörtern). Ausdrücklich KEIN Konkurrent: Schlägt der
Kettenfit ihn nicht klar, ist das ein Befund erster Güte. Er trifft
genau drei Entscheidungen — linkester Endpunkt als Startpunkt, ein
Skalarprodukt am Knoten, Absetzen bei Sackgasse — und lehnt jeden
gelernten Anteil ab (auch den Startpunkt-Prior des Referenz-Codes, der
auf Unterschriften gefittet ist). Der publizierte MATLAB-Code (Diaz et
al. 2022, MIT) läuft hier nicht und ist deshalb die Spezifikation, nicht
die Abhängigkeit. Technisch: tools/routeg (graph.py baut,
recover.py läuft, to_candidate.py rahmt um; Kandidaten-Label
routeg-graph, nie routeg-wor). Anzeige-Name auf der Duell-Seite
seit 2026-08-16: Nullprobe (→ Duell-Namen).
→ proposals/tintenfolger.md §4b, messjournal.md §14
Duell-Namen (display names of the tracing duel) — die lesbaren
Verfahrensnamen der Duell-Seite und der späteren öffentlichen
Methoden-Seite (Owner-Entscheid 2026-08-16), je ↔ technischer Name:
Hand (die eigene S-Pen-Nachfahrung, die Referenz) · Kette (der
Kettenfit MIT Struktur-Wächter — seit dem Entscheid die EINZIGE Kette:
fit-erfundene Kreuzungen sind nie richtig, join-gebildete stecken im
Soll-Budget; seit Kette v5 aug26 ist der ganze Wächter-Stack —
Kompositions-Soll, Ratsche, Zone 0,55 — der Default von
pairlab.follow, ein Lauf ohne Flags IST die Kette; der Folger OHNE
Wächter heißt Kette-frei und ist ein Diagnose-Arm, nie Duell-
Kandidat, weil er Tinte deckt, indem er Struktur zerstört) · InkSight (Small-p, derender-Prompt; der text-Prompt
war Diagnose und ist von der Seite genommen) · Nullprobe (die
prior-freie Kontrolle, technisch Route G/tools/routeg — die Probe
ohne Wirkstoff). Geplant: Zögling (eigenes Trajektorien-Modell auf
Engine-Paaren, Route B2) · Vier Augen (Fusion beider Routen) ·
Feinschliff (Natürlichkeitsfilter als zweite Stufe) · Chor
(ordnungs-bewusste Auswahl unter Varianten) · Lotse (Arbeitstitel:
Skelett direkt fahren, Duktus als Karte an Abzweigungen). Technische
Namen bleiben in Code und datierten §14-Einträgen unverändert — dieser
Eintrag ist die Übersetzungstabelle. Technisch: Label-Marker in
tools/tracebench/view.py (CHAIN_MARKERS/CONTROL_MARKERS)
→ proposals/tintenfolger.md §7.8
Wächter-Ausgang (guard outcome) — was der Struktur-Wächter mit
EINEM Wort getan hat, aus den Runden-Protokollen des Folgers gelesen
und seit aug26 eine Spalte des k0-Protokolls: clean (jede Runde
im ersten Anlauf angenommen) · halved (angenommen nach halbiertem
max_delta) · zonal (angenommen erst nach der zonalen Neu-Lösung
mit gepinnten Ankern) · revert-r<n> (spätere Runde verworfen, das
Wort behält Runde n) · revert-init (Runde 1 verworfen — das Wort
behält den Ketten-Init und wurde GAR NICHT gefolgt). Die Stufen der
v5-Autopsie: gegen den rundenatomaren Soll-Wächter waren 26 von 31
bewegten Wörtern revert-init, v5 macht daraus zonal. Daneben der
Stack-Sensor: k0eval liest die Wächter-Flags beider Dateien und
warnt bei Abweichung — zweimal in zwei Tagen wurde sonst gegen den
falschen Folger gemessen. Technisch:
tools/tracebench/k0eval.py::guard_outcome/guard_stack
→ messjournal.md §14 „Kette v5"
Verfahrensseite — die Register-Seite eines Duell-Verfahrens unter
docs/reference/ (verfahren-kette.md · verfahren-lotse.md ·
verfahren-inksight.md · verfahren-nullprobe.md): Steckbrief
(Anzeige-Name, Code-Heimat, aktuell adoptierte Konstanten) plus
Versions-/Arm-Ledger mit Verdikt und §14-Anker. Die Konvention (eine
Versionsnummer je vorregistriertem Arm; Stand = Menge der adoptierten
Mechanismen; keine rückwirkende Umnummerierung; die Nullprobe bewusst
unversioniert) steht in der Übersicht. Register, keine zweite
Wahrheit: jede Zahl dort ist ein datiertes Zitat, der Beleg wohnt in
messjournal.md §14. Technisch:
docs/reference/verfahren.md (Übersicht + Konvention),
Nachzieh-Pflicht in docs/dokument-status.md
→ reference/verfahren.md
Gute-Fortsetzung (good continuation) — die Gestalt-Regel, mit der
ein prior-freies Verfahren an einer Kreuzung entscheidet, welcher Ast
weiterläuft: der, dessen Richtung die einlaufende am besten fortsetzt.
In Route G ein einziges Skalarprodukt über ein 5-Punkt-Fenster; im
Referenzverfahren eine gewichtete Summe π_ij aus Außenwinkeln,
Innenwinkeln und Krümmung plus Dijkstra durch den Cluster. Die
Kreuzung ist in JEDER zitierten Arbeit der benannte harte Fall — die
Regel ist das Beste, was ohne Duktus-Wissen zu haben ist, und ihre
Lücke gegenüber dem Prior ist genau das, was Route G beziffert.
Technisch: tools/routeg/recover.py::_walk (DIRECTION_WINDOW)
→ proposals/tintenfolger.md §4b
grid_step_crop_px — der Präzisionsboden einer InkSight-Bahn: das
Modell quantisiert seine Ausgabe auf ein 225-Stufen-Gitter über dem auf
Langseite 224 skalierten, weiß gepaddeten Eingabebild, also beträgt ein
Gitterschritt max(Langseite/224, 1) Crop-Pixel — bei unseren 154–310 px
breiten Wort-Crops bis ~1,4 px. Die Spalte wird je Wort mitreportet,
damit dieser Anteil des gemessenen Fehlers nie stillschweigend dem
Kandidaten zugerechnet wird. Technisch:
tools/inksight/prepare.py (frames.json) → proposals/tintenfolger.md §4
Bewertungsdurchgang (labelling round) — eine Runde, in der ein Mensch
gefittete Buchstaben blind beurteilt: je Bildschirm ein Ausschnitt der
Vorlage mit der gezeichneten Mittellinie darüber, dazu eine Kategorie der
Fehler-Taxonomie, ein Ortsmarker und, wenn er mag, ein freier Satz.
Anlass ist die Lücke zwischen Geometrie und Wahrnehmung: geo_rmse,
cov_rmse_local und anchor_spike_ratio messen Abstände, keine davon
misst, ob eine Abweichung stört. Der Durchgang beantwortet genau eine
Frage — welche Fehlerart sieht welche Kennzahl überhaupt? — und liefert
ausdrücklich keine Schwellwerte, keinen Detektor und keine Note „wie gut
sind die Fits“.
Technisch: tools/humanbench (build.py baut, page.py rendert,
analyse.py rechnet in der vorregistrierten Reihenfolge)
→ menschliche-bewertung.md
Gefüllte Ringe — der Anzeigefehler, den die Vorbereitung der ersten
humanbench-WORT-Runde (sep02) zutage förderte, und seither eine Konstruktionsregel
(menschliche-bewertung.md §3.6b): die Silhouette eines Federzugs ist
ein Außenring PLUS die Ringe seiner Binnenflächen, und die Urteilsseite
füllte jeden Ring einzeln statt die Gruppe als EINEN Pfad mit
fill-rule: evenodd. Folge: jede Schleife läuft zu (das Z von „Zorn"
als massiver Tropfen). Tückisch ist nicht die Hässlichkeit, sondern die
RICHTUNG des Schadens — zugefüllt sehen beide Arme genau an den
Merkmalen gleich aus, über die geurteilt werden soll (Schleifenweite,
Binnenraum, Bogenrundung), also antwortet der Beurteiler ehrlich „kein
Unterschied". Ein Anzeigefehler dieser Art rauscht nicht, er zieht zur
Mitte und redet jeden Kandidaten klein — vorhergesagt aus dem
Mechanismus; wie groß der Effekt ist, hat noch keine Runde sauber
gemessen (dazu bräuchte es dieselben Bilder unter beiden Fassungen).
Behoben in PR #492. Ob der Fehler außerdem Urteile erreicht hat, ist
offen: der Bestand sagt nein (die Payloads tragen das erst mit #492
eingeführte Format), das Sitzungsprotokoll der LF11-Runde sagt, die
ersten 27 Bildschirme seien noch auf der alten Anzeige gelaufen — eine
vorher geöffnete Browser-Seite erklärt beides und hinterlässt keine
Datei (§14 „Laufform LF11 — humanbench-Wortrunde").
Regel daraus: vor der ersten Runde eine Form mit Binnenfläche
gegenprüfen — und falls eine Anzeige doch mitten in einer Runde repariert
wird, teilt das die Runde: die Grenze liegt im Zeitstempel, die
bereinigte Menge wird nach demselben Auswerteplan gezählt (Wiederholungen
stimmen nie mit) und trägt unter sechs vollständigen Paaren keinen
Adoptionsanspruch; berichtet werden beide Lesarten.
→ menschliche-bewertung.md §3.6b, messjournal.md §14 („Laufform
LF11 — humanbench-Wortrunde")
Fehler-Taxonomie — die sechs Kategorien, in denen ein
Bewertungsdurchgang urteilt, plus ein Modifikator. Sie sind die
Schnittstelle zwischen Auge und Zahl — jede spätere Kennzahl wird gegen sie
gebaut —, deshalb steht ihre operative Definition ausführlich in der
Methodendoku und nicht nur als Knopfbeschriftung im Code. G und K
beantworten die Frage allein, die Fehlerarten addieren sich, U
kombiniert mit allem. Beurteilt wird die Mittellinie gegen die Tinte
ihres eigenen Buchstabens; die Strichbreite kommt nicht vor.
G— gut. Keine Stelle, die man markieren würde. Zugleich die billigste Probe darauf, dass die Regel verstanden wurde:Gdarf in der Auswertung nie zusammen mit einer Fehlerart auftauchen — wer zögert, setzt die Fehlerart plusU.A— Ausreißer. Eine Stelle springt aus der Kette, die unmittelbaren Nachbarn sitzen richtig; der Fehler ist ein Punkt (mit dem Daumen abgedeckt, ist der Buchstabe in Ordnung). Das menschliche Gegenstück zum Anker im leeren Papier.W— Gewackel. Die Linie folgt der Tinte im Groben, zittert aber um ihren Sollverlauf, oder eine Rundung läuft als Vieleck statt als Bogen. Kein einzelner Übeltäter, sondern Unruhe. Trägt bis auf Weiteres auch die eckig gelaufene kleine Schleife („der Kringel ist eher ein Quadrat als ein Kreis“), für die eine eigene KategorieRvorgesehen ist.B— Bereich daneben. Ein zusammenhängendes Stück der Kette liegt neben seiner Tinte, für sich glatt und plausibel, nur am falschen Ort. GegenAdie Ausdehnung, gegenWdie Glätte, gegenKder Rest des Buchstabens.E— Knick am Rand. Die Beanstandung sitzt ausschließlich im ersten oder letzten Stück der Ankerkette; definierend ist der Ort, nicht die Form. Dahinter steckt überwiegend ein abgeschnittener Anstrich: der Fit beginnt zu spät, das erste Stück Tinte bleibt unbedeckt, der Knick ist nur dessen sichtbarer Rest. Eine andere Krankheit als ein Ausreißer mittendrin — dort ist Tinte da und der Fit verlässt sie trotzdem.K— komplett daneben. Kein Schweregrad, sondern ein Ausschluss: der Fit gehört nicht zu diesem Buchstaben, es gibt nichts zu markieren. Solche Vorkommen fliegen aus der Bewertung aller anderen Kategorien — ein Totalausfall wäre sonst überall ein Positiv und höbe jede AUC, ohne dass eine Kennzahl irgendetwas Spezifisches gesehen hätte.U— unsicher (Modifikator): Das Urteil steht, der Beurteiler steht nicht dafür ein. Gerechnet wird zweimal, mit und ohne — weichen die Zahlen auseinander, ist das ein Befund über die Kategorie, nicht über die Kennzahl.
Technisch: tools/humanbench/page.py::CATEGORIES
→ menschliche-bewertung.md §2 · qualitaetsmetrik.md §9
Vorregistrierung (pre-registration) — der Auswerteplan wird geschrieben, bevor die Zahlen da sind: Reihenfolge der Auswertung, Ausschlüsse, Mindestbesetzung, die Auflösung, die die Daten überhaupt tragen, falsifizierbare Erwartungen und was ein Ergebnis auslösen darf. Ohne ihn passt man die Auswertung hinterher an die Daten an — bei sechs Kategorien und acht Kennzahlen findet sich immer eine Zelle, die etwas zeigt, und niemand weiß hinterher, ob sie gesucht oder gefunden war. Bindend wird der Plan erst durch seinen Zusatz: Was nicht im Plan steht, ist eine nachträgliche Idee und wird als solche gekennzeichnet — mit Datum und Anlass, als eigener Nachtrag, ohne eine vorregistrierte Auswertung zu ersetzen. Ein Nachtrag nach den Labels ist keine Vorregistrierung mehr, sondern eine Hypothese für die nächste Runde. Dieselbe Disziplin wie das Kill-Kriterium (§3) und das vorregistrierte A/B vor jeder rendernden Änderung. → menschliche-bewertung.md §4
Verlässlichkeitsschranke · blinde Wiederholung (test–retest) — ein
Teil der Bildschirme zeigt ein bereits beurteiltes Vorkommen ein zweites
Mal, ohne es als Wiederholung kenntlich zu machen. Aus der
Selbst-Übereinstimmung folgt die Obergrenze dessen, was eine Kennzahl je
erreichen kann: Wer sich in einer Kategorie nur in 6 von 12 Fällen selbst
bestätigt, für den kommt auch ein perfekter Detektor nicht wesentlich
darüber hinaus — und der Satz „unsere Kennzahl ist blind für X“ wäre
unfalsifizierbar. Deshalb wird jede AUC mit dieser Schranke berichtet,
und unter einer vorher genannten Übereinstimmung wird für die Kategorie
keine Blindheit behauptet. Gemessene Lehre: zufällig gezogene
Wiederholungen messen seltene Kategorien nicht — bei 10 % Prävalenz
enthalten 12 Paare je etwa ein Ja, die Übereinstimmung kommt fast ganz aus
Einigkeit über die Neins. Wiederholungen sind nach Kategorie zu schichten.
Technisch: tools/humanbench/build.py::pick_repeats mit
REPEAT_MIN_GLYPH_COUNT/REPEAT_JITTER, Auswertung
analyse.py::reliability → menschliche-bewertung.md §3.2
Abdeckungsmatrix (coverage matrix) — die Kopf-Ausgabe eines
Bewertungsdurchgangs: je Kategorie × Kennzahl eine AUC gegen „Kategorie
gesetzt / nicht gesetzt“ (AUC = die Wahrscheinlichkeit, dass die Kennzahl
ein zufälliges Vorkommen mit der Fehlerart höher bewertet als eines
ohne; 0,5 = blind, 1,0 = perfekte Trennung), K ausgeschlossen und je
Zeile mit ihrer Verlässlichkeitsschranke daneben. Sie wird grob
gelesen — „sichtbar überhaupt?“, also deutlich über ~0,7 —, nie fein: bei
10–15 Positiven je Kategorie liegt der Standardfehler bei ≈ 0,09, ein
Unterschied von 0,04 ist auf solchen Daten nicht auflösbar und wird nicht
neu verhandelt.
Technisch: tools/humanbench/analyse.py::coverage_matrix,
Standardfehler nach Hanley-McNeil → menschliche-bewertung.md §1
Rückhaltemenge (hold-out) — der Teil der Stichprobe, der bewusst
ungelabelt bleibt (reserve.json, durch dieselbe Austeilung
bandbalanciert wie der gelabelte Teil). Regel: entwickeln auf dem
gelabelten Satz, bestätigen auf der Rückhaltemenge. Eine Kennzahl, die
gebaut wird, um zu sehen, was dieser Durchgang gefunden hat, wäre sonst auf
denselben Labels abgestimmt und bestätigt — also gar nicht bestätigt;
ohne den zweiten Durchgang gilt sie als unbestätigt und darf keine
Entscheidung tragen. Technisch: tools/humanbench/build.py, --n-label
→ menschliche-bewertung.md §3.3
Provenienz-Stempel (provenance.json) — was der Builder ungefragt
neben jede Runde schreibt: Runde, Modus, Bauzeit, Quelle, Saat, Bänder,
Zoom, Rand, Wiederholungsregeln, Code-Commit und -Branch, die
verwendeten Eingaben und alle Zählungen. Grund: Ein Urteil gilt gegen
einen Stand des Fits. Ändert sich der Algorithmus — und genau das ist
der Zweck der Übung —, werden die Urteile nicht wertlos, sondern zum
Vorher-Zustand; aber nur, wenn festgehalten ist, worauf sie sich
bezogen haben. Fehlt der Stempel, ist die zweite Runde keine Fortsetzung,
sondern eine neue, unvergleichbare Messung — und die erste damit verloren.
Aus demselben Grund ist das Instrument ein Werkzeug im Repo und kein
Skript je Runde. Nicht zu verwechseln mit der Provenance einer
gespeicherten Geometrie (§2): Jene sagt, wer eine Zeile gezeichnet hat,
dieser, gegen welchen Stand geurteilt wurde.
Technisch: tools/humanbench/build.py::provenance
→ menschliche-bewertung.md §7
paariger Blindvergleich (paired comparison) — der
Vorher/Nachher-Durchgang: dasselbe Vorkommen zweimal gerechnet,
nebeneinander auf einem Ausschnitt, eine einzige Frage — „welche Linie
folgt der Tinte besser?“ — und drei gleichwertige Antworten: links ·
rechts · kein Unterschied erkennbar (das ist ein Ergebnis, keine
Ausrede — der Streit liegt dann unter der Sichtbarkeit). Er tritt an die
Stelle eines zweiten Kategorien-Durchgangs, weil „gut“ kein absoluter
Maßstab ist: Zwischen zwei Sitzungen verschiebt sich die Latte um einen
unbekannten Betrag, und nach Runde eins weiß der Beurteiler, wonach er
sucht. Die Seitenzuordnung steht ausschließlich im Schlüssel, die Seiten
werden je Bildschirm aus der Saat gezogen, Wiederholungen werden
gespiegelt gezeigt. Er misst die Richtung („ist es besser
geworden?“) auf denselben Vorkommen — nicht die Prävalenz je Fehlerart und
keine Fehlerrate. Technisch: tools/humanbench/build.py::build_paired
→ menschliche-bewertung.md §8
Echtheitsfrage (authenticity question) — die zweite der beiden Fragen,
die ein paariger Blindvergleich stellen kann: „welche sieht echter
geschrieben aus?“ statt „welche Linie folgt der Tinte besser?“. Sie löst die
Genauigkeitsfrage ab, sobald beide Linien gleich gut auf der Tinte liegen —
dann misst jene nichts mehr (zwei genaue Linien sind beide genau). Gefragt
wird nach dem Schriftbild, nicht nach der Nähe zur Vorlage; die beiden können
einander sogar zuwiderlaufen, weil eine Linie, die jeden Skelett-Zacken
mitnimmt, genauer ist und weniger geschrieben aussieht. Weil sie etwas anderes
misst, sind ihre Runden mit denen der Genauigkeitsfrage nicht vergleichbar
— das Instrument trägt die gestellte Frage deshalb in die Kopfzeile des
Ergebnistextes (ECHTHEIT/n gegen VERGLEICH/n), damit ein Text auch ohne
seinen Plan zuzuordnen bleibt. Technisch:
tools/humanbench/page.py::QUESTIONS (--question ink | authentic),
Auswertung analyse.py::analyse_paired
→ menschliche-bewertung.md §8, §8a
Wortrunde (word round) — der dritte Modus des Bewertungsdurchgangs und
der einzige, der die drei sichtbarsten Defekte des Geschriebenen überhaupt
zeigt: den Anker-Median-Zickzack einer Laufform-Zeile, den zu dünnen
Strich und den Knick an der Naht. Jedes eingefrorene Lineal ist für sie
blind (das Resampling schluckt den Zickzack, keine Kennzahl trägt die Breite,
der Knick sitzt unter dem Messfenster) und der Kategorien-Durchgang ebenfalls,
weil er einen Buchstaben zeigt und eine Mittellinie zeichnet. Die
Wortrunde zeigt stattdessen ein ganzes Specimen-Wort mit zwei Kompositionen
als Tinte darüber — gefüllte Silhouetten und Verbinder-Kapseln ihrer eigenen
Breite — und stellt die Echtheitsfrage. Vorregistriert entschieden wird
sie bei ≥ 60 % Kandidat unter den entschiedenen Bildschirmen und ≤ 25 % „kein
Unterschied“ über alle, und nur, wenn die gespiegelten Wiederholungen zeigen,
dass nicht nach Position geantwortet wurde. Technisch:
tools/humanbench/build.py --word-arms (build_word), Erzeuger
tools/humanbench/wordarm.py, Auswertung analyse.py::analyse_paired mit
ADOPT_CANDIDATE_SHARE/ADOPT_MAX_TIE_SHARE
→ menschliche-bewertung.md §8a
Arm-Datei (arm file) — die Eingabe einer Wortrunde: je Seite eine
JSON-Datei mit einer Komposition je Fixture-Wort — Registrierung plus
strokes (Punkte in x-Höhen, y nach oben von der Grundlinie, mit
Strichbreite) und fills (Silhouetten) —, also wörtlich das, was
compose_word liefert. Der Builder komponiert nichts selbst: ein
Instrument, das seinen eigenen Kandidaten rechnete, könnte von dem Lineal
wegdriften, das ihn bestätigen soll. Zwei Größen daraus wandern in den
Schlüssel: der arm_gap (wie weit die beiden Arme auf diesem Wort
auseinanderlaufen, symmetrisch, in x-Höhen — die Schwere-Achse, an der die
Bänder geschnitten werden) und die Verdachtsklasse (--strata, die
deklarierte Fehlerklasse eines Wortes, über die die Wiederholungen ausgeteilt
werden). Technisch: Vertrag im Kopf von tools/humanbench/build.py,
Referenz-Erzeuger tools/humanbench/wordarm.py, Prüfsumme je Arm im
Provenienz-Stempel → menschliche-bewertung.md §8a
Ortsmarker · Ortsprüfung — der eine Punkt, den der Beurteiler je Bild in
den Ausschnitt klickt (die auffälligste Stelle, nicht alle), und die
Auswertung darüber. Sein Wert liegt darin, dass er unabhängig von der
eigenen Rechnung ist: Eine Ortsaussage, die aus dem selbst berechneten
Maximum stammt, ist zirkulär und belegt nichts — daran ist die frühere Zahl
„die Gate-Ablehnungen sitzen an Strichgrenzen“ zerbrochen. Zwei vorab
festgelegte Auswerteregeln: ein fehlender Marker ist kein Datum (nicht
markiert heißt „nicht markiert“, nie „dort ist kein Fehler“; die
Markerquote wird mitberichtet, denn sinkt sie über die Sequenz, ist das
Ermüdung und keine Aussage über die Bilder), und Bilder mit mehreren
Kategorien zählen nur in die Gesamtfrage, weil bei einem Punkt nicht
entscheidbar ist, welcher Fehlerart er gilt.
Technisch: tools/humanbench/analyse.py::place_check; die Koordinaten
stehen im Panel-Pixelrahmen und werden über den Schlüssel auf Ankerindex
bzw. Strichgrenze zurückgerechnet → menschliche-bewertung.md §3.7
Werkbank — die Admin-Oberfläche als eine Arbeitsfläche statt fragmentierter Tabs. Seit dem Redesign „aus einem Guss“ (2026-08) ist der ganze Admin die Werkbank: eine Vorlagen-Auswahl und darunter drei Ansichten — Buchstaben · Übergänge · Wörter —, jede nach dem Muster Übersicht ⇄ Detail, mit dem Subjekt in der URL, sodass jeder Quersprung ein normaler Link ist. Jede Ebene nimmt frei eingetippte Ziele an: eine Kombination oder ein Wort, das keine Vorlage je geschrieben hat, muss trotzdem richtig aussehen und bemängelbar sein. → optimierungs-werkbank.md
Stufen-Doktrin — die bindende Rollenverteilung, wer welche Stufe liefert. Grundregel: Manuell hinzufügen nur, wo Ground Truth entsteht, die das System nicht selbst herleiten kann. Alles Generierte wird bemängelt. Also: Tafel-Duktus und das Nachfahren eines misslungenen Worts sind Menschenarbeit; Laufform, Übergangs-Grammatik und Komposition sind Algorithmus-Territorium und werden reklamiert, nicht von Hand gepatcht. Begründung: „Ein Mangel schärft die Regel für alle Wörter, ein manueller Eingriff repariert genau eine Stelle.“ → optimierungs-werkbank.md §3
Abstandsprofil (Werkbank) — die Kurve unter einer Wort-Karte der
Werkbank (/admin/woerter, Detail): je Punkt der gespeicherten
Nachfahrung der NÄCHSTE Abstand zur Engine-Komposition, in x-Höhen,
über der Bogenlänge der Nachfahrung — flach nahe 0 = deckungsgleich,
Berge = daneben; Hover setzt eine Sonde an die Stelle im
Platten-Ausschnitt. Ein Anzeige-Maß der Werkbank, bewusst NICHT
das Residualprofil der Duell-Seite (→ §4): Nachfahrung und Komposition
segmentieren ihre Striche verschieden (generierte Verbinder,
aufgeschobene Marken), eine Schreibreihenfolge-Zuordnung (DTW) würde
dort Segmentierung als Fehler melden — deshalb nächster Abstand statt
Zuordnung, und deshalb nie mit dtw_xh zu verwechseln. Eine Richtung
(Nachfahrung → Engine): überschüssige Engine-Tinte zeigt die
Overlay-Ansicht, nicht diese Kurve. Technisch:
app/src/sections/admin/words/distanceProfile.ts +
DistanceProfileChart.tsx → proposals/optimierungs-werkbank.md
Auftragskorb (work_items) — statt Screenshots eine Tabelle: Der
Autor markiert in der Werkbank einen Buchstaben, ein Paar oder ein Wort
(⚑) und legt daraus einen Auftrag ab — Ebene, Ziel-Schlüssel, wo gesehen,
freie Notiz. Mehr ist von der Mensch-Seite nicht gefordert; die Ebene heißt
„wo gesehen“, nicht „wo verursacht“. Migration 0020/0022.
Korb-Notiz (work_items.kind = "note") — die vierte, zielfreie Ebene
des Auftragskorbs: eine allgemeine Kleinigkeit ohne Buchstabe, Paar oder
Wort — eine Admin-UI-Falte, ein schiefes Wort in der Oberfläche —, für die
sich ein GitHub-Issue nicht lohnt. Ihr ganzer Inhalt ist der Notiztext (das
einzige Pflichtfeld), angelegt direkt im Korb statt über ⚑, das immer etwas
Bestimmtes markiert. Läuft dasselbe Protokoll, nur ohne Pflicht-stage:
das Stufen-Vokabular benennt Stufen des Schreibwegs. →
optimierungs-werkbank.md §5
Landmarken-Linse — die Ebene der Buchstaben-Ansicht, die zeigt, WAS die
Struktur-Erkennung in einem Buchstaben sieht, und zwar auf der
geschriebenen Form statt in einer Tabelle: Kreuzung als Ring, Retrace-Zone
als Band entlang der Bahn, Absetzen als Strich, Umkehrecke als Quadrat,
Kringel als Kreis im Maß seiner Öffnungsweite D0, Verschmelzung als
schraffiertes Band. Grund für die Fläche (Autor-Wunsch 2026-09-07): Die
Landmarken tragen den Duktus-Soll, den Tintenfolger-Zähler und den
Kringel-Katalog — und waren bis dahin nur im Messlauf sichtbar. Wer den
Duktus autort, konnte nicht sehen, ob die Erkennung ihn richtig liest.
Gezeichnet werden dieselben Erkenner, mit denen die Bench misst; der
einzige Griff der Linse ist ⚑ (→ Landmarken-Auftrag), denn die
Landmarken-Ebene ist GENERIERT und fällt damit unter „nur bemängeln“ der
Stufen-Doktrin.
Technisch: core/landmarks.py (die gemeinsame Heimat der Erkenner, aus
tools/pairlab/landmarks.py, tools/tracebench/counters.py und
tools/tracebench/kringel.py hierher gezogen, weil api/ nicht tools/
importieren darf), Route GET /sources/{id}/templates/{glyph_key}/landmarks, SPA
sections/admin/letters/LandmarkPanel.tsx + LandmarkOverlay.tsx.
→ optimierungs-werkbank.md §8
Landmarken-Auftrag (work_items.kind = "landmark") — die fünfte
Korb-Ebene: eine Beschwerde über EINE erkannte Struktur eines Buchstabens
(„hier fehlt eine Kreuzung“, „der Kringel ist falsch klassiert“, „hier ist
keine Ecke“). Sie trägt den glyph_key wie ein Buchstaben-Auftrag — die
Landmarken-Ebene ist aus genau dieser Zeile abgeleitet, eine zweite
Schlüsselspalte wäre ein zweiter Name für dasselbe —, und WELCHE Landmarke
mit welchen Zahlen gemeint ist, schreibt die Linse selbst in die ersten
zwei Zeilen der Notiz: Zeile 1 die Identität (Landmarke: Kringel #1 (loop#1) · d · Tafel-Duktus (Variante 0)), Zeile 2 die gemessenen Werte.
Darunter steht, was der Autor sieht. Die Stelle ohne Marke ist der
Sonderfall ohne Index: ein Klick ins Leere meldet, dass an dieser Stelle
eine Marke FEHLT — die Beschwerde, die eine reine Marker-Fläche nicht
annehmen könnte. → optimierungs-werkbank.md §8
Landmarken-Erkennung (stage = "landmark_detector") — die einzige
Stufe des Korb-Vokabulars, die KEINEN Schritt des Schreibwegs benennt: der
Buchstabe war richtig, der Erkenner falsch. Sie steht in der Triage-Reihe
zuletzt vor not_reproducible, weil die Reihenfolge auch hier gilt — erst
fragen, ob der autorierte Duktus stimmt, dann den Sensor verdächtigen, der
ihn liest. → optimierungs-werkbank.md §8
Auftragskorb-Protokoll — der Rest ist Protokoll, und die API
erzwingt es (check_transition, 422 bei unvollständigem Abschluss):
understanding— die Beschwerde in eigenen Worten zurückgespiegelt, bevor irgendetwas geändert wird. Drei Sätze: was ich als Beschwerde verstehe · was ich beim Nachprüfen gesehen habe · welche Stufe ich zuerst verdächtige.reproduced—yes/partly/no: ist die Beschwerde überhaupt aufgetreten? („Nachprüfen, nicht nacherzählen.“)stage— die diagnostizierte Stufe aus einem geschlossenen Vokabular:chart_ductus·laufform·join_rule·composition·pair_override·word_trace·landmark_detector·not_reproducible. Ein geschlossenes Vokabular macht aus dem Archiv eine Abfrage statt einer Lesearbeit.resolution— Stufe, Änderung, PR, Messstand. Querverweis-Regel: dieresolutionnennt die PR, die PR-Beschreibung nenntKorb #<id>.
Triage-Pflicht · Regel-Fix vor Override — die Reihenfolge, in der ein Auftrag geprüft wird: Tafel-Duktus falsch? → Laufform/Fit? → Klassenregel? → Platzierung? → erst zuletzt ein Paar-Override. Ein Override ohne vorherige Regel-Prüfung ist ein Doktrin-Verstoß.
Rückgabe an Autor (returned) — der ehrliche Ausgang, wenn die
Triage eine Ground-Truth-Lücke ergibt (der Tafel-Duktus ist falsch,
der Fit ist ohne manuelles Nachfahren unmöglich). Statt done wird
returned gesetzt, und die resolution nennt den konkret benötigten
manuellen Schritt. Die Zeile bleibt im Korb sichtbar — sie wartet auf den
Autor, nicht auf den Algorithmus.
Einrichtungs-Wizard — die einzige Bearbeitungsfläche für den Tafel-Duktus, in Schritten: Ausschluss (Radierer · Tinte-Pinsel · „Lücken füllen“ · „Zelle einsetzen“) → Lineatur (inkl. Schräglagen- Linien) → Weg (den Duktus als Stiftzüge aufnehmen; jedes Absetzen beginnt einen neuen Zug, „Anpassen“ erlaubt Warp-Ziehen zum Ausbügeln) → Übersicht/Freigabe.
Radierer · Tinte · Lücken füllen · Zelle einsetzen — die vier
Ausschluss-Werkzeuge über einer Chart-Zelle: freihändig Tinte entfernen ·
freihändig Tinte hinzufügen · kleine Sprenkel automatisch schließen
(farbcodiert in der Maskenvorschau, damit sichtbar ist, was verschluckt
wurde) · Tinte aus einer anderen Zelle derselben Tafel einkopieren
(bboxes.patches — so entsteht ein ü aus u-Basis + ä-Umlaut, obwohl es
keine eigene ü-Zelle gibt).
Technisch: Alle drei Tinten-Eingriffe komponiert
core/chart.py::crop_with_mask vor der Binarisierung in den
Ausschnitt — sie ändern also, was die Maske überhaupt sieht;
crop_mask_to_png_bytes rendert daraus die binarisierte Vorschau
(„Maske zeigen“) mit farbcodierter Auto-Füllung.
Wort-Editor · Paar-Editor — die beiden manuellen Ground-Truth-Flächen:
der Wort-Editor lässt ein misslungenes automatisches Nachfahren von Hand
über dem Ausschnitt neu ziehen (→ authored, wird von keiner Neu-Ernte
überschrieben); der Paar-Editor zeichnet einen Verbinder für genau ein Paar
und gibt ihn frei (→ glyph_pairs, die sparsame Ausnahme).
Nachfahr-Stand (traceStatusOf, shell/model.ts) — der dreiwertige
Stand einer Wortprobe im manuellen Nachfahr-Durchgang, hinter dem
Status-Filter der Wörter-Übersicht (Alle · Offen · Nachgefahren ·
Unvollständig): nachgefahren = eine gespeicherte authored-Bahn
liegt vor (ein automatischer Fit zählt nicht — er ist genau das, was
der Durchgang ersetzt) · unvollständig = die Probe ist als
angeschnitten markiert, das Nachfahren geht also nie · offen = alles
übrige, und damit die Arbeitsliste. „Offen" ist der Filter, den es
gibt, damit „was fehlt noch?" eine Auswahl ist und keine Scrollarbeit.
Unvollständige Wortprobe (incomplete, words.json) — eine
Wortprobe, deren EIGENE Tinte angeschnitten ist: der i-Punkt fehlt, der
letzte Buchstabe läuft aus dem Rechteck. Sie lässt sich nicht von Hand
nachfahren und ist darum weder Arbeit noch Versäumnis — markiert mit
"incomplete": true (Grund im note daneben) an ihrer Zeile im
committeten Sidecar data/sources/<id>/words.json, fällt sie aus der
Arbeitsliste und aus dem Nenner des Nachfahr-Zählers heraus und wird
als eigene Zahl ausgewiesen. Beleg bleibt sie: der heile Teil ist
weiter messbar. Nicht zu verwechseln mit Fremdtinte (§3) — die
stammt aus einer Nachbarzeile und wird per exclude weiß gemalt; hier
fehlt Tinte des Wortes selbst. Die Marke ist das zweite Mittel, nicht
das erste (Autor, 2026-08-31): schneidet nur das RECHTECK die Tinte
ab, wird das Rechteck repariert (→ Rechteck-Reparatur) — angeschnittene
Wörter bringen nichts, und das eingefrorene Fixture ist ein Grund für
ein angekündigtes Re-Baseline, keiner, den Mangel stehen zu lassen.
incomplete bleibt für das, was kein Rechteck einfangen kann: Tinte,
die auf der Platte selbst endet.
Rechteck-Reparatur (tools/wordbench/repair_boxes.py) — das
Nachziehen einer Wortproben-Kante, die die eigene Tinte anschneidet.
Gemessen wird auf der ROHEN binarisierten Platte, weil der
Standardschnitt auf der despeckelten misst und ein dünner i-Strich
unter dieser Schwelle liegt. Was eigene Tinte ist, entscheidet die
Lineatur der Zeile: außerhalb ±1,35 xh liegt die Nachbarzeile,
Interpunktion hängt ganz unter der Mittellinie und kommt nie herein,
blasser Durchschlag fällt am Schwärze-Vergleich aus. Über 2 x-Höhen
Wachstum wird gemeldet statt angewandt (Rückfallebene, bewusst locker:
bei einer x-Höhe verweigerte sie regieren, dessen letztes n wirklich
angeschnitten war). Die exclude-Boxen wandern mit — neu eingeschlossene
Fremdtinte bekommt eine, eine die nur noch eigene Tinte verdeckt fällt
weg. Zwei weitere Dinge wandern mit: die CROP-lokalen
Registrierungen gespeicherter Bahnen (shift_registrations.py, reiner
Ursprungs-Versatz, kein Nachfahren — die verschobene Zeile bekommt den
Ursprung, auf den sie sich bezieht, als rect_origin mitgestempelt, sonst
ist ein Lauf auf der x-Achse nicht wiederholbar) und die Fixture-Roots
(Re-Export + datierter §15-Eintrag).
H0–H5 · R1–R5 · W1–W6 · M0–M7 — die vier Nummerierungen der Arbeitspläne, bewusst getrennt gehalten: H = Handmodell-Stufenplan (H0 Bench-Anschluss der Laufformen · H1 Vorkommen + Aggregate · H2 Paar-Statistik · H3 Konstanten → Hand-Parameter · H4 zweite historische Hand · H5 die eigene Hand; H0–H2 ausgeliefert). R = Schreibsystem-Redesign (R1 Paar-Matrix · R2 Positions-Rückbau · R3 geerntete Paar-Overrides · R4 Platzierungsrest · R5 Schräglage; alle umgesetzt). W = Werkbank (W1 Backend · W2 Seite · W3 Wort-Editor · W4 Protokoll · W5 Stufen-Einsicht · W6 Nachfahr-Stand; alle umgesetzt). M = MVP-Roadmap (M0 Toolchain … M4 Fit-Routine … M7 abgespeckte Animation) — daher „M4-Fit“. Nicht zu verwechseln mit den vier Kettenfit-Kennzahlen M1–M4 (§3).
Vereinfachungs-Gate — die Regel aus H3: Ein Parameter darf nur dann aus dem Code in die Statistik wandern, wenn (a) die Bench sich nicht verschlechtert und (b) netto Code entfällt oder ein Sonderfall verschwindet. Antwort auf die Sorge „das ganze wird immer besser, aber der Code auch immer komplexer“: Vereinfachung ist ein Gate, kein Nebeneffekt.
Verworfen — Abschnitte mit dieser Überschrift sind geschlossene
Entscheidungen mitsamt Begründung. Sie werden beim Überarbeiten eines Docs
nicht geschwächt oder gelöscht; neue Argumente gehen nach
docs/proposals/. Der Zweck: dieselbe Sackgasse nicht zweimal laufen.
Rettungsweg (conversion path) — die beim VERWERFEN einer Maßnahme benannte Idee, die sie doch noch ins Ziel bringen könnte (Owner-Direktive 2026-08-16). Jeder §14-Ergebnis-Eintrag eines ehrlichen Negativs schließt mit seinen Rettungswegen (oder explizit „keiner benannt"); die zentrale stehende Liste ist proposals/tintenfolger.md §7.9. Ein Rettungsweg ist immer ein NEUER Mechanismus, neue Evidenz (Bestätigungssatz) oder ein neuer Sensor (z. B. der blinde Menschvergleich als Tie-Breaker) mit frischer Vorregistrierung — nie derselbe Knopf mit weicheren Gates. Verhältnis zu „Verworfen": das Verdikt bleibt geschlossen; der Rettungsweg ist die separat vorregistrierte NÄCHSTE Hypothese, nicht seine Wiedereröffnung. → proposals/tintenfolger.md §7.9 · messjournal.md §14
Status-Vokabular der Docs — jedes Doc trägt unter der Überschrift einen Status mit absolutem Datum: bindend (entschieden) · lebend (beschreibt den Ist-Stand und trägt eine benannte Nachzieh-Pflicht) · teil-umgesetzt · umgesetzt-historisch · offen · Befund-Journal (datierte Momentaufnahme, wird nie fortgeschrieben, nur abgelöst) · statisch (quellenbelegtes Nachschlagematerial). Ab rund 10 000 Token wird der Kopf zum Stand-Block: bis zu 40 datierte Zeilen, die sagen, was gilt, was offen ist und wo der Rest steht — jeder Satz mit dem Anker seiner Quelle. → docs/dokument-status.md
Messjournal (measurement journal) — die Datei
messjournal.md, seit 2026-09-04 die Heimat von §14, dem
Kampagnen-Journal: 88 datierte Abschnitte, je einer pro Mess-Runde, mit
Vorregistrierung, gemessenen Zahlen und Verdikt. Vorher stand die Sektion in
qualitaetsmetrik.md und machte dort zwei Drittel der Datei aus, sodass jede
Frage nach einer Metrik-REGEL das ganze Journal mitlud; der Umzug ist Wort für
Wort und lässt Überschriften wie Anker unangetastet, weshalb die Nummer §14
als Zitierschlüssel bleibt (rund 350 Zitate im Repo). Einstieg ist das
Register im Kopf: eine Zeile je Abschnitt mit Datum, Route, Typ · Verdikt
und Befund — erst der Sprung aus dem Register lädt einen Abschnitt. Ein
abgeschlossener Arm zieht in
messjournal-archiv.md (Verdikt gebucht ·
Rettungswege eingetragen · ≥ 4 Wochen unberührt), behält dabei seinen Anker,
und seine Registerzeile bekommt nur den Dateinamen vor das #-Fragment.
Technisch: tools/docs_register (JOURNAL, ARCHIVE_PAGE, METRIC),
CI-Job „Docs-Register“. → messjournal.md · qualitaetsmetrik.md
Kurzglossar (short glossary) — die Datei
kurzglossar.md (seit 2026-09-04): 77 Begriffe zu je ein
bis zwei Sätzen, je mit dem Sprung in den Themenblock dieses Glossars.
Ausgewählt in zwei nachvollziehbaren Schritten: gezählt — ein
Eintragstitel wird Kandidat, wenn er mit Wortgrenzen in mindestens zwei von
drei Quellen vorkommt (Code in core/, api/, tools/, alembic/,
app/src/; die Agenten-Dateien; die letzten 40 gemergten PR-Beschreibungen)
— das ergab 92 Kandidaten —, und daraus ausgeschlossen entlang dreier
benannter Klassen: Wortfalle (der Treffer stammt aus gewöhnlicher Prosa),
schon abgedeckt (der Inhalt steht dort unter einem anderen Eintrag) und
Ein-Arm-Etikett (ein Messname, den genau ein §14-Abschnitt benutzt). Die
Klassen mit ihren Titeln stehen im Kopf des Kurzglossars; 77 bleiben. Grund:
dieses Glossar kostet über 56 000 Token und stand damit als Pflichtlektüre
in CLAUDE.md; die Kurzfassung ist die Pflichtlektüre, das volle Glossar
bleibt die Nachschlage-Instanz und behält seinen Schnellindex.
→ kurzglossar.md · glossar.md
Lese-Budget (reading budget) — die Obergrenze dessen, was eine Sitzung
laden muss, bevor sie mit der eigentlichen Aufgabe anfängt: die
Pflichtlektüre aus CLAUDE.md und jeder dort benannte Lesepfad haben je eine
Zahl, gemessen am 2026-09-04 plus 10 % Luft. Das Gate dazu ist
uv run python -m tools.docs_budget check (CI-Job „Docs-Budget“); es liest
die Pflichtliste aus CLAUDE.md, statt sie abzuschreiben, also hebt ein
neuer Listenpunkt die gemessene Summe und fällt auf. Gezählt wird ohne
Tokenizer, mit einem eigenen deterministischen Proxy (Wortstücke, lange
Komposita geteilt, mal einem Kalibrierungsfaktor) — die Budgets stehen in
Proxy-Einheiten, damit Gleiches mit Gleichem verglichen wird; der Abgleich
gegen tiktoken o200k_base steht im Modul-Docstring. Ein Budget wird
bewusst gehoben, mit Begründung im PR, nie stillschweigend. Dasselbe Gate
prüft Stand-Blöcke, die eine Zeile je Datei in der Karte und jeden Anker.
Technisch: tools/docs_budget (BUDGETS, PATHS, proxy_tokens).
→ werkzeuge.md § docs_budget · docs/index.md
Stand-Block (standing block) — der erweiterte Status-Blockquote eines
großen Docs (ab rund 10 000 Token): bis zu 40 datierte Zeilen, die sagen,
was gilt, was offen ist und wo der Rest steht — jeder
zusammenfassende Satz mit dem Anker seines Abschnitts. Er ist das, was eine
KI-Sitzung liest, statt die Datei zu laden; Muster sind
proposals/tintenfolger.md und reference/qualitaetsmetrik.md. Nicht zu
verwechseln mit dem gewöhnlichen Status-Kopf, den jedes Doc trägt.
→ docs/dokument-status.md · /write-docs
Changelog-Fragment (changelog.d/<slug>.md) — der Changelog-Beitrag
einer PR als EIGENE Datei statt als Bullet unter [Unreleased] der
geteilten CHANGELOG.md (seit 2026-08-30). Format = das der CHANGELOG
selbst (### Category über fett betitelten englischen Bullets), damit der
Release-Schnitt (tools.changelog release) die Fragmente unverändert unter
die neue Versionsüberschrift faltet — neueste zuerst je Kategorie, nach dem
Commit, der sie anlegte — und sie danach löscht. Grund: die eine geteilte
Stelle war der Ort, an dem jeder Geschwister-Merge die anderen PRs in den
Konflikt schickte (Audit-Serie 2026-08-29/30); der Union-Merge-Treiber
heilte nur den lokalen Rebase, GitHubs eigene Mergebarkeitsprüfung
ignoriert ihn. Der CI-Job „Changelog (fragment)" verlangt je PR ein
Fragment (Ausnahmen: reine data/-PRs, Label skip-changelog, PRs von
Dependabot) und weist direkt in [Unreleased] HINZUGEFÜGTE Bullets ab —
hinzugefügt, nicht bloß verändert: ein Bullet wird über seinen fetten Titel
identifiziert (seit 2026-09-04), also darf der Wortlaut eines dort schon
stehenden Eintrags korrigiert werden, und nur ein NEUER Titel (oder eine
weitere Kopie eines vorhandenen) ist ein hinzugefügtes Bullet. Ebenfalls
abgewiesen: der unausgefüllte Platzhalter (#NNN) — die PR-Nummer bleibt
optional, der Platzhalter nicht. Technisch:
tools/changelog/__init__.py — parse_entries (ein Parser für Fragmente
und [Unreleased]), bullet_title/_added_bullets (die Titel-Identität),
check_placeholder, check_pr (die PR-Regel), plan_release/apply_release
(der Schnitt); CI-Job changelog in .github/workflows/ci.yml.
→ werkzeuge.md § Der Changelog-Schnitt · changelog.d/README.md
Fehlerschicht (apiErrorText) — die deutsche Antwort der Werkbank
auf einen fehlgeschlagenen API-Aufruf: aus dem HTTP-Status wird ein
Satz, der den nächsten Schritt nennt („Diese Glyphe ist gesperrt — erst
in der Tafel entsperren"), und die englische Rohzeile des Servers bleibt
darunter in einem zugeklappten <details> („Technische Meldung") stehen.
Beides zusammen ist der Punkt: Vorher renderten alle achtzehn Admin-Stellen
String(err) wörtlich, also stand „Error: 423 Locked: glyph 'longs' is
locked; pass force=true to overwrite" mitten in deutscher Oberfläche und
sagte nichts darüber, was zu tun ist; bloßes Übersetzen hätte die einzige
Diagnose weggeworfen, die es gibt. Der Satz antwortet, das Detail
beweist. Der Rückgabewert trägt zusätzlich den status, damit
Aufrufer einen Sonderfall (404 = „noch nicht angelegt", kein Fehler) am
Typ erkennen statt die Meldung nach „404" zu durchsuchen.
Der Name ist englisch, die Ausgabe deutsch — sprachregelung.md §1
verlangt englische Bezeichner, und §3 verwirft deutsche Identifier
ausdrücklich auch für deutsche Fachbegriffe („Begriff gehört in den
Kommentar, nicht in den Bezeichner"). Der Begriff steht also hier im
Glossar, nicht im Code.
Technisch: app/src/sections/admin/shell/apiErrorText.ts +
ErrorText.tsx; die Sätze in app/src/locales/de/admin.ts (admin.errors).
Liegt bewusst unter sections/admin/ und nicht bei lib/api/: der
Katalog darf das öffentliche Bundle nicht erreichen (no-restricted-imports).
Entwurfsnetz des Wizards — die Rettungskopie des gezeichneten Wegs.
Der Weg ist der einzige Zustand des Einrichten-Wizards, der nicht
live committet wird (Ausschluss, Tinte, Lineatur und Schräglage schreiben
sofort), und zugleich der Schritt, an dem Handarbeit Ground Truth erzeugt
(→ Stufen-Doktrin). Deshalb zwei Schichten: Escape, Backdrop-Klick und
„Schließen" laufen alle über eine Rückfrage, die benennt, was
verloren ginge und was nicht; und selbst das bewusste „Verwerfen" legt
die Striche unter kurrentschrift.wizard.<sourceId>.<glyphKey> in den
sessionStorage, sodass das nächste Öffnen sie zum Wiederherstellen
anbietet statt sie stillschweigend zurückzumalen.
Technisch: useWizard.ts (dirty, discardAndClose, draft),
SetupWizard.tsx (requestClose).
Zwei Stillen (Leerzustands-Regel) — ein Leerzustand muss die Ursache
nennen, die tatsächlich vorliegt, nicht die nächstbeste. Konkret in der
Werkbank: no-occurrences („Noch keine Vorkommen geerntet") gegen
no-hand („Keine Hand an den Vorkommen hinterlegt"). Die Hand wird aus
den Vorkommen abgeleitet — gibt es keine, kann keine eine Hand nennen,
und der Hand-Satz benennt eine Ursache, die es noch gar nicht geben kann;
genau das stand vor 2026-09 auf jeder Karte einer frisch geseedeten
Vorlage. Dieselbe Regel gilt eine Ebene höher schon für die Aggregate
(„kein Neuaufbau" vs. „unter der Mindest-Vorkommenszahl").
Technisch: StatsStatus in LensStats.tsx, abgeleitet in
WorkbenchData.tsx::statsContextOf und pairMeasurement.ts::aggregateLayerState.
Typo-Boden — die bindende Untergrenze der Schriftgrößen des öffentlichen
Auftritts: Fließtext ≥ 19 px, Caption ≥ 14 px, ohne Ad-hoc-Größen (design-system.md
§9). „Boden" statt „Richtwert", weil er MESSBAR ist: app/scripts/type-floor.mjs
fährt alle öffentlichen Routen in einem echten Browser an, liest die berechnete
Schriftgröße jedes Elements mit eigenem Text und schlägt unter 14 px fehl. Genau
eine Ausnahme ist sanktioniert, der 13-px-overline der Typo-Leiter (§3). Der
Boden wurde am 02.09.2026 an 17 Stellen unterschritten — durchweg
MUI-size="small"-Vorgaben und Ad-hoc-fontSize-Werte, keine Absicht; deshalb
sitzt die Korrektur im Theme und die Kontrolle im Skript.
→ concepts/design-system.md §9 · app/scripts/type-floor.mjs
Trefferfläche (hitArea) — die unsichtbare Vergrößerung eines
Bedienelements auf das 44-px-Touch-Ziel, ohne seine Optik anzufassen: ein
zentriertes ::after mit max(100%, 44px) in beiden Kanten
(app/src/styles/hitArea.ts). Sie ist die Antwort auf den Konflikt zwischen
Plattformempfehlung (Apple HIG 44 pt, Material 48 dp) und einem Entwurf, dessen
kleine Marken — das Wiederholen-↻ über der Tinte, das Kurrent-i des InfoHint,
das leise „beenden" — absichtlich leise sind: eine unsichtbare Trefferfläche
statt einer kleineren Wahrheit. WCAG 2.2 SC 2.5.8 (24 × 24 px) hielt die Seite
schon vorher über die Abstandsausnahme; die 44-px-Regel geht bewusst darüber
hinaus und ist seit dem Entscheid des Autors vom 03.09.2026 bindend
(design-system.md §9.3, bis dahin als Vorschlag notiert). Nachgeprüft wird sie
nicht an der berechneten Größe, sondern an der echten Trefferfläche:
npm run touch-targets fragt per elementFromPoint in 22 px Abstand vom
Mittelpunkt nach — das fängt den stillen Bruch, bei dem ein overflow: hidden
das Pseudo-Element beschneidet und das Ziel bei unveränderter Zeichnung
zurückschrumpft.
→ concepts/design-system.md §9.3 · app/src/styles/hitArea.ts ·
app/scripts/touch-targets.mjs
Eigenhand-Erfassung — die Werkzeugkette, mit der der Autor seine
eigene Hand als Trainingsdaten erfasst: Wortvorrat → Streifenplan →
Bogen drucken → mit echter Feder schreiben → einlesen → Siebung →
Fassungen in der Streifenkartei → Bestandsbericht → nächster Bogen.
Technisch: tools/eigenhand/, Datenwurzel data/samples/own-hand/
(gitignored, Archiv via tools/eigenhand/snapshot.py).
→ proposals/eigenhand-erfassung.md
Wortvorrat — der committete, kuratierte, in Wellen wachsende Bestand
ECHTER Wörter der Eigenhand-Erfassung (alt und modern, hauptsächlich
Deutsch, Englisch getaggt); Kurationsschichten per Tag (mvp9 ·
bench-abb19 · quizbank · rare-join · haeufig · english).
Trainingsdaten, kein Mess-Satz — keine Bench-Kopfzahl liest daraus.
Technisch: tools/eigenhand/corpus.py::pool_entries.
→ proposals/eigenhand-erfassung.md §4
Streifen (Eigenhand) — die stabile Inhaltseinheit der
Eigenhand-Erfassung: eine feste Wortgruppe, die genau eine Bogenzeile
füllt. Einmal vergeben, nie umnummeriert (append-never); Aufnahmen sind
Fassungen. Technisch: IDs S0037; Wächter
tools/eigenhand/pool.py::verify_immutable.
→ proposals/eigenhand-erfassung.md §4
Streifenplan — das committete, append-only Verzeichnis
Streifen → Wörter, deterministisch gebaut (Phase A gewichtetes
Set-Cover für die Startdeckung, Phase B defizitgetriebener Ausbau mit
Wiederholungs-Dämpfung REPEAT_DAMPING). Seit Format 2 trägt er neben
den Streifen die Tabelle forms (Wort → Fugen-Form), damit auch ein
Leser ohne die Kurationsquelle richtig formen kann — der Server tut
genau das. Technisch: core/eigenhand/streifen.json, Builder
tools/eigenhand/pool.py, Leser core/eigenhand/plan.py.
→ proposals/eigenhand-erfassung.md §4
Anheftung — der einzige Weg an einem eingefrorenen Streifenplan
vorbei: ein Wort, das der Autor JETZT geschrieben haben will, bekommt
einen eigenen angehängten Streifen, und dieser Streifen führt fortan die
Planreihenfolge an. Kein Streifen wird dafür umgeschrieben (append-never
bleibt), keine Geometrie bewegt sich; angeheftete Wörter zählen in
Bestand und Deckung wie jedes andere Wort und verlassen die Spitze der
Warteschlange auf dem normalen Weg — indem sie belegt sind. Begründet
wird eine Anheftung nicht mit Deckung, sondern damit, was das Wort ist.
Technisch: Wortliste tools/eigenhand/corpus.py::PINNED_FIRST (Tag
pin), Befehl python -m tools.eigenhand.pool pin, Block pins im
Plan, gelesen von core/eigenhand/plan.py::ordered_strips.
→ proposals/eigenhand-erfassung.md §4
Fassung — EINE konkrete Aufnahme eines Streifens (eine gesiebte
Bogenzeile). Status angenommen · verworfen (nur Kartei-Protokoll,
keine Datei) · zurueckgezogen (explizit per redo --retire; ASCII, wie
alle drei Werte — core/eigenhand/ids.py::STATUSES, und die API nimmt
kein zweites Schreibweise-Paar an);
Neuaufnahme ERGÄNZT, sie ersetzt nicht. Nur angenommene Fassungen
zählen als Trainingsmaterial. Technisch:
fassungen/S0037/F02/{streifen.png, meta.json}; der PNG ist
selbst-zuordenbar (gedruckte Streifen-ID + Wortlabels im Ausschnitt).
→ proposals/eigenhand-erfassung.md §6–§7
Bogen — ein gedrucktes A4-Blatt der Eigenhand-Erfassung: dynamische
Zusammenstellung offener Streifen mit Wortkästen samt Lineatur,
Klartext-Labels, Streifen-IDs am Rand und Passmarken; derselbe Streifen
darf mehrfach daraufstehen (Versuche, --repeat). Jeder Bogen schreibt
neben sein PDF die layout.json — den einzigen Geometrie-Vertrag des
Importers (Registrierung statt Erkennung). Technisch: IDs B0012;
komponiert in core/eigenhand/bogen.py::compose_sheet (Auswahl, Layout,
PDF), abgelegt entweder lokal durch tools/eigenhand/sheet.py oder als
Zeile eigenhand_sheets durch POST /eigenhand/sheets.
→ proposals/eigenhand-erfassung.md §5, §7.1
Passmarken — die vier gedruckten schwarzen 8-mm-Eckquadrate eines
Bogens, links oben mit 3-mm-Lochung (Donut) zur Orientierung: darüber
entzerrt der Import Scan wie Handyfoto (Homographie) und erkennt
gedrehte Aufnahmen. Technisch: tools/eigenhand/fiducial.py
(scikit-image, bewusst ohne OpenCV).
→ proposals/eigenhand-erfassung.md §6
Schnittband — das Rechteck, zu dem eine Bogenzeile geschnitten wird:
feste Spalten (x = 12 … 197 mm) plus feste Polster über der Oberlinie und
unter der Klartext-Zeile. Für jede Zeile eines Stils identisch (Sütterlin
185 × 29 mm; Kurrent und Offenbacher 185 × 28 mm, weil CUT_MIN_HEIGHT_MM
ihren flacheren Zeilen mehr Polster über und unter der Lineatur gibt),
unabhängig von der Wortzahl — deshalb haben am Ende ALLE Streifen EINER
Schrift dieselbe Höhe und Breite. Die Streifen-ID sitzt im oberen
Polster, also auf dem Streifen (Zuordenbarkeit); die Stiftmarke bleibt
draußen. Der Import schneidet digital am selben Rechteck, damit
Papierstreifen und streifen.png dasselbe Objekt sind. Technisch:
core/eigenhand/geometry.py::cut_box/cut_size_mm, je Zeile in
layout.json unter cut_mm.
→ proposals/eigenhand-erfassung.md §5
Schnittmarken — die kurzen Striche in den Blatträndern, die zeigen, wo
geschnitten wird: je Zeile vier auf Höhe der Querschnitte (links und
rechts), dazu die beiden Längsschnitte in den Lücken ZWISCHEN den
Streifen. Nie innerhalb des Schnittbands — gedruckte Tinte auf dem
Streifen wäre Tinte in den Trainingsdaten — und nie am Blattkopf, wo eine
Haarlinie auf dem Scan in eine Passmarke verlaufen und deren Schwerpunkt
verziehen könnte. Technisch:
core/eigenhand/geometry.py::cut_ticks/page_cut_ticks.
→ proposals/eigenhand-erfassung.md §5
Stiftmarke — das eine gedruckte Kästchen am rechten Rand JEDER
Bogenzeile (5 mm, ab x = 199 mm, im Kopf einmal mit „ok“ beschriftet —
außerhalb des Schreibfelds, in Reichweite der Hand am Zeilenende). Der
Schreiber hakt direkt nach dem Schreiben ab, ob die Zeile taugt; der
Import liest die Marke aus dem entzerrten Bild und belegt die Siebung
damit vor. Anders als die QC-Flags DARF sie vorbelegen: sie ist ein
Menschenurteil im besten Moment, nicht eine Maschinenvermutung —
überschreibbar bleibt sie trotzdem. Die Regel (Autor, 2026-08-26, löst
das „leer = verworfen" vom 23.08. ab): Haken oder Kreuz = angenommen;
ohne Haken zählt die Zeile nicht — sie bleibt unbeurteilt, der
Streifen steht wieder in der Warteschlange; verworfen mit Grund ist
eine ausdrückliche Wahl auf der Siebungsseite, keine Vorgabe.
apply --haken verbucht die Haken direkt. Technisch:
core/eigenhand/geometry.py::mark_box,
tools/eigenhand/ingest.py::read_pen_mark, je Zeile in layout.json
unter mark_mm. → proposals/eigenhand-erfassung.md §5–§6
Siebung — der Annehmen/Verwerfen-Schritt je Bogenzeile auf einer
selbstständigen Offline-HTML-Seite (humanbench-Muster: data-URIs,
Resume, uid-verschlüsseltes Ergebnis). Regel ist die Sieb-Disziplin
(aus mvp-roadmap M2): verworfen wird nur nach Schreibqualität
(verschrieben, verrutscht) — nie wegen Verbindungsenge; Ausfälle müssen
zufällig sein, nicht selektiv; best-of über Mehrfach-Versuche desselben
Streifens ist erlaubt. Technisch: tools/eigenhand/page.py →
apply.py.
→ proposals/eigenhand-erfassung.md §6
Streifenkartei (kurz: Kartei) — das lokale Manifest einer Hand und
ihre EINZIGE Zustandsquelle: Bögen, Fassungen, Schreibsitzungen
(Datum · Feder · Tinte · Papier · Gerät), Redo-Liste. Streifen-Zustände
(geplant · unterwegs · belegt) werden ABGELEITET, nie gespeichert;
unterwegs ist reine Anzeige — die Druck-Warteschlange beginnt immer
vorn im Plan minus belegt (Autor-Entscheid 2026-08-26, proposals
§7), ein Stapel setzt sie seitenweise fort und wird EIN PDF.
Nie committet, nie von Hand editiert. Technisch:
data/samples/own-hand/<hand>/kartei.json,
tools/eigenhand/kartei.py::strip_state.
→ proposals/eigenhand-erfassung.md §7
Übergangsraum — die Soll-Grundgesamtheit der Eigenhand-Erfassung:
alle GEFORMTEN glyph_key-Übergänge und Glyph-Positionen, die in echtem
Wortschatz vorkommen, korpusfrequenz-gewichtet; berechnet aus
Konsultationskorpora (Klasse 2). Die Gewichtstabelle wird nie
committet (Frequenzlisten-Doktrin, quiz-wortbank.md §4); seit dem
Autor-Entscheid 2026-08-25 liegt sie neben der lokalen Kopie als EINE
Zeile in der privaten, geteilten DB (eigenhand_uebergangsraum,
Migration 0026, Push tools.eigenhand.universe --push) — als
vollständiges Soll-Universum (Korpus-Items ∪ Pool-Items zu 0) samt
Provenienz, damit Werkbank und Terminal dieselben Quoten und dieselbe
gewichtete Druck-Warteschlange rechnen. Item-Notation l>e
(Übergang) und e@medial (Glyph-Position). Bewusst nicht „Abdeckung“
genannt — der Begriff gehört der Humanbench-Abdeckungsmatrix (§4).
Technisch: tools/eigenhand/universe.py,
core/eigenhand/coverage.py (soll_from_weights = die eine
Ziel-Ableitung beider Seiten), GET|PUT /eigenhand/uebergangsraum.
→ proposals/eigenhand-erfassung.md §4, §7.1
Mindestbelegung (Eigenhand) — die harte Untergrenze des
Streifenplans: JEDE Glyphe — Buchstabe, Ligatur, Ziffer, Zeichen — wird
mindestens dreimal eingeplant, unabhängig von ihrer Textfrequenz
(Owner-Regel 2026-08-23: „sowas wie q nur 1× darf nicht sein“). Eine
Garantie, keine Präferenz: Phase A2 des Builders hebt jede unterbelegte
Glyphe auf, bevor der frequenzgetriebene Ausbau beginnt, und meldet
namentlich, wenn die Wellenkapazität nicht reicht. Nicht zu verwechseln
mit dem gewichteten Aufbauziel (→ Bestandsbericht), das je nach Frequenz
zwischen 3 und 20 liegt. Technisch:
tools/eigenhand/pool.py::GLYPH_MIN_PLANNED, Prüfzeile am Ende jedes
tools.eigenhand.progression-Laufs.
→ proposals/eigenhand-erfassung.md §4
Beleg (Eigenhand) — ein Vorkommen eines Übergangsraum-Items in den angenommenen Fassungen einer Hand; die Zähleinheit des Bestandsberichts. → proposals/eigenhand-erfassung.md §7
Bestandsbericht — der Soll/Ist-Bericht der Eigenhand-Erfassung je
Glyph-Position und Übergang, mit zwei Kopfzahlen: Erstbeleg-Quote
(Anteil Items mit ≥1 Beleg) und Ausbau-Quote (Σ min(Ist, Soll)/
Σ Soll), beide ungewichtet UND übergangsraum-gewichtet (die gewichtete
Zahl ist die ehrliche Kopfzeile). Dazu der Druckvorschlag — dieselbe
Warteschlange, die sheet.py --next druckt: Redo > nie belegt >
Wiederholung nach gewichtetem Soll-Gewinn. Zweistufiges Soll: die
Erstbeleg-Stufe (≥1 Beleg je Item — sie misst die Erstbeleg-Quote und
treibt Phase A des Streifenplans) und das Aufbauziel
clamp(3 + 17·√(w/wmax), 3, 20) (coverage.target_for_weight,
Untergrenze 3 — es misst die Ausbau-Quote).
Technisch: core/eigenhand/bestand.py (die Rechnung),
tools/eigenhand/report.py (Terminal), GET /eigenhand/bestand/{hand}
/admin/eigenhand(Werkbank — mit Quoten, sobald die Gewichte peruniverse --pushin der DB liegen),tools/eigenhand/pool.py::soll_modelübercoverage.soll_from_weights. → proposals/eigenhand-erfassung.md §7
Eigenhand-Buchführung — die Hälfte der Streifenkartei, die in der
GETEILTEN Datenbank liegt: welche Bögen gedruckt sind (mit ihrem Layout)
und welche Streifen wie oft angenommen wurden (eigenhand_sheets ·
eigenhand_fassungen, Migration 0024, Owner-Entscheidung 2026-08-23).
Die Zahlen brauchen keine Pixel — die Wörter folgen aus Streifen-ID plus
committetem Plan. Seit 0025 liegen die Streifenbilder trotzdem
daneben (eigenhand_strips, Owner 2026-08-24), damit die Werkbank einen
geschriebenen Streifen zeigen kann wie einen Tafel-Crop: eigene Tabelle,
PNG-Spalte überall deferred, admin-gesichert, private, no-store, nie im
Repository — der Master bleibt das private Archiv. Nahtstelle ist die
Kartei-FORM: lokal kartei.json, serverseitig
EigenhandRepository.kartei — dahinter rechnet dieselbe Schicht. Seit
0026 liegt auch das Soll daneben: die Übergangsraum-Gewichte als EINE
hand-unabhängige Zeile (eigenhand_uebergangsraum, Autor 2026-08-25,
Push universe --push), damit Quoten und gewichtete Warteschlange auf
beiden Seiten dieselben sind.
Technisch: core/database/models.py, api/routers/eigenhand.py,
hoch/runter mit tools/eigenhand/sync.py ↔ pull.py
(Bilder nur auf --mit-streifen).
→ proposals/eigenhand-erfassung.md §7.1, §7.2
Stehendes Setup — Feder, Tinte, Papier und Aufnahmegerät einer Hand,
EINMAL erklärt statt bei jedem Import getippt (eigenhand_hands,
Migration 0025). Begründung ist photometrisch, nicht ergonomisch:
diese vier sind Parameter der ganzen Kampagne — wechseln sie mittendrin,
zerfällt das Korpus in Kohorten, die man auf Strichbreite und Schwärzung
nicht mehr vergleichen kann. ingest liest sie als Vorgabe aus einem
lokalen Zwischenspeicher; die EFFEKTIVEN Werte stehen zusätzlich an jeder
Fassung (bewusst denormalisiert — ein echter Wechsel soll als Bruch in
den Daten sichtbar sein, nicht rekonstruiert werden müssen). Reihenfolge:
vor der ersten Sitzung erklären, sonst bleiben die Felder der davor
eingelesenen Fassungen leer. Technisch: tools/eigenhand/setup.py
(CLI, lokaler Cache setup.json), GET|PUT /eigenhand/setups/{hand},
Panel „Stehendes Setup“ in /admin/eigenhand.
→ proposals/eigenhand-erfassung.md §7.2
Wort-Ausschnitt (Eigenhand) — ein einzelnes Wort, aus einem
gespeicherten Streifen HERAUSGERECHNET statt zusätzlich abgelegt: der
Streifen merkt sich seinen Crop-Anfang in Millimetern
(crop_origin_mm), das layout.json des Bogens sagt, wo die Wortkiste
sitzt, und die Pixelbreite über der Schnittband-Breite gibt den Maßstab.
Senkrecht bleibt der Ausschnitt auf VOLLER Streifenhöhe — Ober- und
Unterlängen sind das Interessante an einem Wort. Dieselbe Überlegung wie
beim Tafel-Crop-Endpunkt, nur in mm statt in Tafelpixeln.
Technisch: core/eigenhand/crop.py,
GET /eigenhand/strips/{hand}/{strip}/{fassung}?wort=….
→ proposals/eigenhand-erfassung.md §7.2
Diese Begriffe stammen aus der Literatur, nicht aus dem Repo. Sie stehen
hier, weil sie in Recherche-Notizen und Issue-Diskussionen als
Vergleichsmaßstab auftauchen — und weil unsere Hausmaße (gen_chamfer,
dconn) eben Hausmaße sind.
DTW (Dynamic Time Warping) — Standardverfahren, um zwei unterschiedlich lange Sequenzen (z. B. zwei Stiftbahnen) elastisch aufeinander abzubilden und ihren Abstand zu messen. Klassiker der Handschrift-Literatur, für Trajektorienvergleich aber schlecht kalibriert.
LDTW (Length-independent DTW) — längenunabhängige Variante davon,
eingeführt von PEN-Net (ACCV 2022). Präzise (Primärquelle verbatim
geprüft, aug14): unconstrained DTW geteilt durch die Länge T des
gefundenen optimalen Warping-Pfads (Eq. 1) — kein Band, kein fester
Schrittvorrat, und der Divisor ist datenabhängig (T ≤ M+N), keine
Konstante. Kleiner ist besser. Es existiert KEINE
Referenz-Implementierung (das PEN-Net-Repo enthält nur Trainingscode);
publizierte Werte hängen an [0,64)-Koordinatenboxen und
CASIA-Einzelzeichen und sind mit unseren Wort-Zahlen nicht
vergleichbar. Unsere Headline dtw_xh (§4) übernimmt genau diese
T-Normalisierung, resampelt aber beide Seiten arc-length-uniform und
misst in xh — deshalb der eigene Name.
AIoU (Adaptive Intersection over Union) — das zweite Maß aus
derselben Arbeit. Präzise (Primärquelle verbatim geprüft, aug14): die
Referenz ist NICHT eine Ground-Truth-Bahn, sondern die
OTSU-binarisierte Tintenmaske des Bildes; nur die VORHERSAGE wird
1 px gerastert und per 3×3-Dilatation iterativ verbreitert, bis die IoU
maximal ist — AIoU = max_k IoU(G, dilate^k(P)). „Adaptiv" heißt: an
die argmax-Dilatationsstufe, nicht an eine gemessene Breite; genau das
eliminiert den Einfluss der Strichbreite. Größer ist besser;
auflösungsabhängig (Raster immer mitnennen). Publizierte
Größenordnungen: 0,45–0,55 (PEN-Net, isolierte CASIA-Zeichen), ~0,75
(Diffusions-Rekonstruktion 2026, ebenfalls Zeichen-Ebene) — beide NIE
als Zielwerte für verbundene Wörter importieren. Der tracebench (§4)
implementiert die Spalte papertreu gegen die eingefrorene ref_mask.png
— was sie nebenbei auf alle Wörter ohne Nachfahrung ausdehnt; eine
Wordbench-Variante (komponierte Maske statt Bahn) bleibt ein eigenes,
anderes Maß.
HTG (Handwritten Text Generation) — der Literatur-Sammelbegriff für
Modelle, die Handschrift als Bild synthetisieren (Offline-Synthese):
GANs wie ScrabbleGAN, Transformer wie HWT/VATr, Diffusionsmodelle wie
DiffusionPen und One-DM. Gegenstück zur Online-Synthese nach Graves, die
Stiftbahnen statt Pixel erzeugt. Für uns relevant als möglicher
Parallelweg (Kurrent-Bilder generieren, dann die Bahn zurückgewinnen) —
Stand der Technik, Datenlage und Prüfsteine in
bildsynthese-und-stiftbahn.md.
HWD (Handwriting Distance) — perzeptuelle Distanz im Merkmalsraum eines eigens auf Handschrift-Stil trainierten Netzes (BMVC 2023). Eingeführt, weil FID (Fréchet Inception Distance, das übliche Maß für generierte Bilder) für Handschrift schlecht taugt: falsches Backbone, quadratischer Bildausschnitt, Stichprobengrößen-Bias.
Sigma-Lognormal / Kinematic Theory — Réjean Plamondons Modell, das einen Handschriftzug als Überlagerung lognormaler Geschwindigkeitsprofile beschreibt — also eine physiologisch plausible Kurvenfamilie. Interessant für uns, weil es keine Online-Trainingsdaten braucht und direkt auf die erzeugten Verbinder zielt: Es sagt nicht nur, wie schnell, sondern auch welche Kurvenform ein Mensch zwischen zwei Punkten zieht. Daniel Berios Kalligrafie-Synthese ist die ausgebaute Variante davon.
Zwei-Drittel-Gesetz — die schwache, bereits benutzte Version davon:
die Schreibgeschwindigkeit sinkt mit der Krümmung (v ∝ κ^(−1/3)), dazu
Isochronie — die Dauer eines Zuges wächst deutlich langsamer als seine
Länge (im Repo Dauer ∝ Länge^0,6), ein langer Zug wird also einfach
schneller geschrieben. Steckt in
app/src/lib/strokeTiming.ts und macht die Schreib-Animation glaubwürdig.
→ animation-rendering.md §1
G1- / G2-Stetigkeit — geometrische Stetigkeitsgrade an einer Nahtstelle zweier Kurven: G0 = gleicher Punkt, G1 = zusätzlich gleiche Tangentenrichtung, G2 = zusätzlich gleiche Krümmung. Unser Übergangs-Generator trifft Punkt und Tangente, also G1; nichts erzwingt Krümmungsstetigkeit über die Fuge. Saubere Schreibschrift lebt aber genau davon — ohne ein Krümmungskriterium bleibt jede Fuge lokal richtig und global sichtbar. Als benannte offene Naht notiert.
Trajektorien-Recovery (handwriting trajectory recovery) — das Forschungsfeld „aus einem Bild die Stiftbahn zurückgewinnen“, in dem der Kettenfit fachlich zu Hause ist. Verwandt und ausdrücklich nicht gewählt: blindes Skelett-Tracing (löst das Kreuzungsproblem nicht) und neuronale Bildsynthese (liefert Raster, keine Bahn — also keinen Duktus, keine Strichfolge, keine Animation, keine Belegbarkeit).
MDN (Mixture Density Network) — Ausgabeschicht, die statt eines
Punktes eine Mischverteilung vorhersagt (mehrere Gauß-Komponenten samt
Gewichten). Graves 2013 setzt sie auf ein LSTM, um je Zeitschritt die
Verteilung des nächsten Stift-Offsets zu modellieren — die Grundlage der
generativen Handschrift-Synthese. Technisch: Parameter μ/σ/ρ/π plus
Stift-ab-Wahrscheinlichkeit; Kontext in
graves-handschrift-synthese.md
und kurrent-writer-and-recognizer.md §1.
Priming / Biasing — die zwei Steuerhebel des Graves-Writers:
Priming konditioniert den LSTM-Zustand mit echten Trajektorien eines
Zielautors, bevor der neue Text generiert wird (Stil-Imitation);
Biasing skaliert zur Laufzeit die Varianz der MDN-Verteilung
(Lesbarkeit ↔ Natürlichkeit). Technisch: Mechanik, Grenzen (Style
Collapse, OOV-Alignment) und moderne Nachfolger in
graves-handschrift-synthese.md.
HTR · CER — Handwritten Text Recognition und Character Error Rate
(Anteil falscher Zeichen). Der geplante Lesepfad: Transkribus als
Default (CER 5–7 %), das self-hosted Modell dh-unibe/trocr-kurrent als
Fallback (CER 2,65 %). → htr-integration.md
L-BFGS-B — der benutzte Optimierer: ein quasi-Newton-Verfahren mit
begrenztem Speicher und Box-Schranken (daher das B — genau die
Schranken, die die Platzierungsblöcke des Fits brauchen). Steht hier, weil
Abbruchmeldungen dieses Optimierers (STOP: TOTAL NO. OF ITERATIONS REACHED LIMIT) in Befundtexten wörtlich zitiert werden.
Die Namen, unter denen Besucher die Werkzeuge kennen. Sie stehen hier, weil
sie im Repo bislang nur benutzt wurden: „Schreibtafel“, „Lesetafel“ und
„Grundtafel“ meinen drei verschiedene Dinge, und „Tafel · Chart“ (§2) ist
noch einmal ein viertes — die Lehrbuch-Tafel als Datenquelle, nicht die
Seite. Ein Blick hierher spart das Auseinandersortieren (Website-Audit
2026-09-02). Die Texte selbst liegen in app/src/locales/de/, eine Datei je
Namensraum; die Seiten sind die Routen aus app/src/routes/paths.ts.
Schriftkunde (/schriftkunde) — die belegte Übersichtsseite über
Kurrent, Sütterlin und Offenbacher: Grundbegriffe, die drei
Ausgangsschriften mit ihren Kennwerten, Federn, Tinte und Papier,
Buchstaben-Besonderheiten, Chronologie, Quellen. Jede Angabe stützt sich
auf docs/schriftkunde/*.md — das Faktenblatt ist die einzige Quelle für
historische Aussagen auf der Website, nicht das Gedächtnis des Schreibenden.
locales/de/schriftkunde.ts, Abschnitts-Anker in
sections/schriftkunde/sections.ts.
Lese-Quiz (/quiz) — das Abfragespiel: eine geschriebene Form
(einzelner Buchstabe oder ganzes Wort), vier Antworten, nach einem Fehlgriff
beide Formen nebeneinander. Erklärt wird ein Fehlgriff nur bei den
dokumentierten Verwechslerpaaren (→ Lesefalle §1, sections/quiz/ lesefallen.ts) — „no explanation is better than an invented one“. Welche
Auswahlzeilen die Seite überhaupt zeigt, entscheidet offersChoice
(sections/quiz/quizOptions.ts): eine Zeile mit nur einer verfügbaren
Option ist eine Tatsache, keine Wahl, und erscheint darum weder in der SPA
noch auf der vorgerenderten Crawler-Seite.
Schreibtafel (/tafel) — die Alphabet-Seite: die drei Grundtafeln
nebeneinander zum Vergleichen und Nachschlagen; die Sütterlin schreibt sich
dort Zug um Zug selbst, jeder Buchstabe mit seiner Strichfolge.
sections/tafel/TafelView.tsx.
Grundtafel — die gemeinfreie Original-Lehrtafel einer Quelle
(Loth 1866, Sütterlin 1922, Koch 1928), so wie sie gedruckt wurde — das
Bild, nicht die Nachschrift. Drei davon zeigt die Schreibtafel.
sections/tafel/useGrundtafeln.ts; die Quelle dahinter ist die Vorlage
(§2).
Lesetafel — das A4-PDF der Schreibtafel: dieselben Formen zum
Ausdrucken und Danebenlegen beim Entziffern. lib/lesetafel.ts.
Lesart prüfen (/lesen/vergleichen) — die Hilfe für das eine Wort,
das sich nicht entziffern lässt: Man tippt seine Vermutung ein, die Feder
schreibt sie, daneben stehen die Wörter, die sich von ihr nur in
Verwechslerpaaren unterscheiden (→ Lesart §1, GET /lesarten).
Federprobe (/federprobe) — die Schreibfläche für beliebigen Text:
eingetippt, live in Sütterlin geschrieben, mit den generierten Übergängen.
Die öffentliche Kostprobe der Komposition (§2). sections/scribe/.
Tintenboden — die Untergrenze, unter der eine geschriebene Zeile nicht
mehr klein gesetzt, sondern umgebrochen wird: 14 px x-Höhe, also 14 px
je Template-Einheit (Grundlinie = 0, Mittelband = 1). Der Wert ist der
Typo-Boden des Design-Systems (§9: „Caption ≥ 14 px“) — geschriebene Formen
bekommen mindestens, was gesetzte Schrift bekommt, und brauchen eher mehr:
Was ein Sütterlin-u vom n trennt, sitzt innerhalb des Mittelbands und ist
ein Bruchteil davon, während eine gedruckte Letter sich als Ganzes
unterscheidet. Gemessen: Der Website-Audit 2026-09-02 fand einen
29-Zeichen-Satz auf 360 px bei 7,1 px je Einheit (22,5 px Tinte für den
ganzen Satz) und nannte ihn unlesbar. Fällt eine Zeile unter den Boden,
bricht WrittenWord den Text an Leerzeichen um (→ Umbruch der Federprobe).
Der Boden ist eine Zusage über das ERGEBNIS, nicht über die Schätzung: Der
Umbruch wird aus dem Durchschnittsvorschub des ganzen Textes geplant, und
eine Zeile, die aus dem Komponisten dichter zurückkommt als dieser Schnitt
(sie hat die breiten Buchstaben eingesammelt), wird mit ihrer GEMESSENEN
Breite neu geplant — so bleibt keine umbrechbare Zeile unter dem Boden.
app/src/lib/lineWrap.ts MIN_XHEIGHT_PX.
Umbruch der Federprobe — der Autor-Entscheid vom 2026-09-04 für lange
Texte auf schmalen Geräten: Der Text wird an Wortgrenzen in mehrere
Zeilen gebrochen, und jede Zeile ist eine eigene Komposition — ein
eigener GET /write/word, ein eigener durchgehender Federzug von ihrem
Anstrich bis zu ihrem Auslauf. „Zug um Zug“ gilt damit je ZEILE, nicht je
Text; der Zeilenanfang bekommt seinen richtigen Anstrich, weil
core/shaping.py die Wortposition ohnehin je Slot vergibt. Alle Zeilen
teilen sich eine x-Höhe (die der breitesten), wie eine Hand über einen
Absatz hinweg; die Schrift läuft links bündig, und die Feder hält am
Zeilenbruch einen längeren Takt als beim Absetzen (LINE_BREAK_PAUSE_MS).
Verworfen wurden dabei: Maßstab-Boden mit horizontal scrollender Fläche und
eine viewportgekoppelte Zeichenobergrenze mit Hinweis. Ehrlich benannte
Grenze: Ein einzelnes Wort, das breiter ist als der Rahmen, wird nicht
getrennt — es bleibt eine Zeile unter dem Tintenboden und zieht (als
breiteste Zeile) den ganzen Block mit hinunter. Nicht zu verwechseln mit
der Unantastbaren Lineatur des Übungsblatts: Dort ist ein Umbruch
verworfen, weil die Vorschrift exakt zwischen ihre Linien gehört; die
Federprobe schreibt auf eine freie Fläche ohne vorgedruckte Zeilen.
app/src/lib/lineWrap.ts planLines → components/WrittenWord.
Schriftgrößen-Leiter — die drei Stufen, in denen die Federprobe schreibt
(Autor-Entscheid 2026-09-04, klein · mittel · groß, Vorgabe mittel): ein
Umschalter, kein Zoom. Eine Stufe ist eine Ziel-x-Höhe in px je
Template-Einheit — der Text wird bei dieser Größe GESCHRIEBEN, nicht ein
fertiges Bild vergrößert, also plant planLines den Umbruch für sie und eine
größere Stufe bringt mehr Zeilen. Verankert ist die Leiter am → Tintenboden:
14 · √2 ≈ 20 · 28 (= 2 × 14) · 40, √2-Schritte über der Größe, bei der eine
geschriebene Zeile gerade noch lesbar ist; klein trifft dabei genau das, was
eine volle Desktop-Zeile vorher schrieb (gemessen 20,8 px je Einheit auf
1440 px). Der Boden gewinnt, wo der Rahmen die Stufe nicht trägt: Weil ein Wort
nie getrennt wird, kappt der Planer das Ziel auf die x-Höhe, bei der das
breiteste Wort noch passt — auf 360 px fallen darum alle drei Stufen auf ~14 px
zusammen. Die Wahl bleibt je Leser erhalten (localStorage) und reist als
?size= im Teilen-Link, wobei die URL den Speicher schlägt, damit ein
geteilter Link das Bild des Absenders zeigt. Gilt nur der Federprobe; ohne das
Prop targetXHeightPx bemisst wie bisher height die Größe.
app/src/sections/scribe/size.ts, design-system.md §7.1.
Postkarte (Federprobe) — die Größe der Federprobe-Eingabe seit dem
2026-09-04: 480 Zeichen, gedacht als acht geschriebene Zeilen zu sechzig —
dieselbe Zeilenlänge, die das Übungsblatt druckt (MAX_LINE_LEN). Der Zähler
n/480 zählt getippte Zeilenumbrüche mit, denn sie sind im Feld auch Zeichen.
Ein getippter Umbruch ist immer ein Umbruch: planParagraphs teilt ZUERST an
den Umbrüchen und bricht dann jeden Absatz um; eine Leerzeile ist EIN
Absatzabstand (mehrere fallen darauf zusammen, führende und abschließende
entfallen). Nie geht ein \n an die API — jede Zeile ist eine eigene
/write/word-Anfrage, und core.shaping.shape_text liest ein \n als
gewöhnliches Leerzeichen, schriebe den Umbruch also als Lücke mitten in die
Zeile. Die 60 ist zugleich die harte Obergrenze des Planers
(MAX_CHARS_PER_LINE), damit keine Anfrage der 160-Zeichen-Grenze der Route
nahekommt. app/src/sections/scribe/ScribeView.tsx, lib/lineWrap.ts.
Übungsblatt (/schreiben/uebungsblatt) — das erzeugte PDF mit der
Lineatur der gewählten Ausgangsschrift, wahlweise mit Schräglinien,
Federwinkelmarke und dem eigenen Text als Vorschrift (§1) in den Zeilen.
sections/worksheet/.
Unantastbare Lineatur — die Doktrin des Übungsblatts für eine
Vorschrift-Zeile, die breiter gerät als die Zeile fasst (Autor-Entscheid
2026-09-02): Sie wird weder verkleinert noch an einer Wortgrenze
umgebrochen — beides nähme der Vorschrift genau das, wofür sie da ist,
nämlich exakt zwischen ihren Linien zu stehen. Stattdessen bleibt die Zeile
ungeschrieben, ihr Platz auf dem Blatt bleibt reserviert, sie bekommt ihre
Zeilenmarke, und die Seite sagt es unter dem Textfeld mit Zeilennummer und
Zeichenzahl. Der Gegenentwurf („lieber schief als gar nicht“) ist damit
verworfen. lib/uebungstext.ts placeText.
Zeilenmarke — die rot gestrichelte Bande über dem Mittelband einer Zeile,
die für eine nicht geschriebene Vorschrift-Zeile freigehalten wird, mit deren
Zeilennummer am Seitenrand. Sie erscheint nur in der Vorschau: Ein
gedrucktes Übungsblatt trägt keine Warnbänder, es lässt die Zeile einfach
leer. Damit verschwindet nichts still, ohne den Druck zu verunstalten.
lib/uebungstext.ts RowMark → sections/worksheet/PreviewSvg.tsx.
Zeichenbreiten-Mittel (AVG_ADVANCE_UNITS) — wie breit ein Zeichen im
Mittel läuft, in Template-Einheiten (x-Höhe = 1). Gemessen 2026-09-02 am
Komponisten über abcdefghijklmnopqrstuvwxyz: 1,55. Darauf ruht die einzige
Zahl, die das Übungsblatt über die Zeilenlänge verspricht — „bei 6 mm
Mittellänge etwa 18 Zeichen“ statt der früheren pauschalen 60 (das war bloß
die Obergrenze des Eingabefeldes). Es beantwortet „wie viel passt ungefähr“,
nie „diese Zeile passt“: Das Urteil über eine konkrete Zeile fällt an ihrer
eigenen Komposition. lib/uebungstext.ts maxCharsPerLine.
„Zug um Zug“ — das Leitmotiv der öffentlichen Texte und zugleich eine
inhaltliche Zusage: Was die Seite zeigt, ist die Bewegung der Feder in
ihrer Strichfolge, nicht eine Schriftart mit fertigen Buchstabenbildern.
Wo der Satz steht, muss dahinter eine echte Komposition aus dem Duktus (§1)
stehen — WrittenGlyph/WrittenWord, nicht der Fallback-Font. In der Prosa
heißt die schreibende Instanz „die Feder“; „Synthese“ bzw.
„Synthese-Engine“ bleibt den Stellen vorbehalten, die das Gezeigte
kennzeichnen (Bildunterschriften, Herkunftshinweise).
architektur.md— §2 Analysis-by-Synthesis, §3 Schema, §4 Übergänge, §5 Schwellzug vs. Tinteallgemein.md— die belegten paläografischen Grundbegriffe (§1 hier ist deren Kurzfassung)qualitaetsmetrik.md— alle Metriken im Detail samt Baseline-Historiemenschliche-bewertung.md— der blinde Bewertungsdurchgang: Fehler-Taxonomie, Instrumentregeln, Vorregistrierunguebergaenge-befund.md§5/§5c — das Übergangs- und Kettenfit-Vokabular in seinem Messkontexthandmodell-stufenplan.md— Laufform, Aggregat, Prüfstein, H0–H5optimierungs-werkbank.md— Werkbank, Auftragskorb, Stufen-Doktrinsprachregelung.md— warum die Docs deutsch und die Bezeichner englisch sind