CAF — wiederverwendbare Basis
Basisdokumentation (modules)
6Kapitel
12761Wörter
~63 Min.Lesezeit
4 Bausteinemodules

Stand 27.10.2026 21:53

01. Zweck und Abgrenzung

Zweck

CAF steht für Core Application Framework und ist die wiederverwendbare Basis unter modules/: anwendungsneutrale ABP-Bausteine, die ein Produkt einbindet, statt sie je Produkt neu zu schreiben. Sie sind Quellcode-Bausteine, keine NuGet-Pakete (IsPackable=false) und werden per ProjectReference konsumiert; verbindlich ist je Baustein die Vertragsdatei VERTRAG.md (ADR-03).

Das RAL Gütezeichen Anhörungsportal ist der am weitesten ausgebaute Referenzhost. Der LogoLicense ContractManager ist ein zweiter ausführbarer Konsument von Authentication und UI.Blazor; sein fachlicher Umfang ist noch im Aufbau. Belegter Produktbedarf bestimmt die gemeinsame CAF-Fläche.

Das Repository umfasst zusätzlich dokumentierte Dienstverantwortungen unter services/. Diese gemeinsame Ablage erweitert den Frameworkbegriff nicht: ein Dienst ist eine eigene Betriebs-/Schnittstellenverantwortung, ein CAF-Modul wiederverwendbares In-Process-Verhalten. Den aktuellen Schnitt beschreibt Dienste und Kundenbetrieb.

Die am 13.09.2026 bestätigte Entwicklungsrichtung beginnt mit diesem Portal und führt danach zum LogoLicense ContractManager. Gemeinsame Fähigkeiten werden aus konkreten Produktbedarfen abgeleitet und schrittweise als passendes Subset zentral in CAF gepflegt. Die Anforderungsgrundlage ordnet dafür die älteren Confluence-Requirements ein; die Mapping-Matrix hält Extraktionskandidaten fest. Beide ergänzen die Planung und ändern keine bestehenden Modulverträge.

Die Grenze

Die tragende Regel ist einseitig und wird nicht durch Konvention, sondern durch Architekturtests durchgesetzt (ADR-06):

Ein Produkt darf von CAF abhängen. CAF darf nie von einem Produkt abhängen.

Konkret darf kein CAF.Modules.*-Projekt ein CAF.Applications.*-Projekt oder -Paket referenzieren, in keiner Version, und keinen produktfachlichen Namespace oder Begriff verwenden. Eine Verletzung ist ein Build-Fehler, kein Review-Befund.

Entscheidungsregel: gehört etwas nach CAF?

Ein Belang gehört nur dann in einen CAF-Baustein, wenn alle Punkte zutreffen:

  1. Domänenneutral — er lässt sich ohne produktfachliche Begriffe beschreiben. DTOs, Permissions, Routen und Fachbegriffe eines Produkts bleiben beim Produkt.
  2. Belegter Bedarf — es gibt einen konkreten, getesteten Anwendungsfall. Eine vorsorgliche Abstraktion ohne Konsumenten ist ausdrücklich kein Grund.
  3. Stabil zusicherbar — die Fläche lässt sich in VERTRAG.md benennen und nach SemVer versionieren.

Trifft einer der Punkte nicht zu, bleibt der Belang im Produkt. Der Umzug nach CAF ist später mechanisch möglich, der Rückweg nicht.

Was CAF ausdrücklich nicht ist

Aus den Verträgen der Bausteine, nicht nachträglich interpretiert:

  • Kein Policy-Owner. Rollen, Permissions, Realm-Namen und Autorisierungsentscheidungen bleiben beim Produkt.
  • Kein Owner von Routing, Layout oder Render Mode. Der Host entscheidet.
  • Keine Benutzerverwaltung und kein Provisioning. CAF.Modules.Authentication ist ein OIDC-Client, keine Identitätsverwaltung.
  • Keine zweite Wrapper-API über Fremdbibliotheken. CAF.Modules.UI.Blazor integriert Cohesion, es kapselt es nicht in eine eigene Komponenten-API.
  • Kein Sammelbecken. Ein Baustein Common oder Utils ist keine gültige Antwort auf die Ownership-Frage.

Wann ein Baustein aus CAF herausgelöst wird

Extraktionsfähigkeit ist eine Eigenschaft des Abhängigkeitsgraphen, kein Grund, heute Projekte anzulegen. Ein zweites konsumierendes Produkt ist der Beleg, der eine weitere Assembly- oder Paketgrenze rechtfertigt — nicht die Vermutung, dass es eines geben wird.

Weiter: 02. Bausteine · verbindliche Arbeitsregeln: modules/AGENTS.md

02. Bausteine

Vier Bausteine unter modules/, alle bewusst nicht packbar (IsPackable=false, keine PackageId/Version) und je mit einer verbindlichen VERTRAG.md als Quelltext-Vertrag. Der Referenzhost konsumiert sie per ProjectReference; ein Pack-Skript existiert nicht.

Baustein Verantwortung Grenze
Authentication OIDC-Client: Authorization Code + PKCE gegen einen externen Identity Provider (referenzgetestet mit Keycloak), Claim-Mapping, Cookie-/Session-Policy, lokale und remote Abmeldung, Security-Stamp-Revalidierung keine Produktrollen, Permissions oder Realm-Policy; keine Benutzerverwaltung; kein Provisioning
Documents.Contracts DocumentId, vendor-neutrale DTOs, Dokument-/Content-/Filing-/Share-Interfaces, lesender Speicherinventar-Port, Permissions, Localization exportiert keine Volo.FileManagement-Typen; Filing- und Inventar-Port ausschließlich prozesslokal nach Consumer-Autorisierung
Documents (Runtime) dünner Adapter über ABP File Management: validierter Dateiinhalt, Metadatenzugriff, ablaufende und einzeln widerrufbare Direktfreigaben; besitzt nur CAFDocumentShareGrants ABP besitzt Descriptor und BLOB-Inhalt; keine parallelen Dokumententities
UI.Blazor Cohesion-Integration: AddCohesion, typisierte CAFCohesionOptions, frühe Lizenzvalidierung, Bundle-Contributors für CSS/JS, routenfreies CAFCohesionSmokePanel; dazu die CAF-Konventionen der Oberfläche, die jedes Produkt gleich hält: die Grid-Naht (Data/CAFGridDataAdaptor, CAFGridPageRequest/-Result, CAFGridToolbar — Seitengrößen, Spaltenwähler, geteilte Refresh-Id; Data/CAFGridColumns — das Breitenvokabular, nur blanke Zahlen, siehe grid-muster.md, Abschnitt 13) und der Fristbaustein (Time/CAFDeadline, CAFDeadlineChip — Zeitstempelkonvention, Restzeit → Ton) keine Produktroute, keine Fachkomponente, kein Render-Mode-Entscheid, keine Produktsprache (Texte kommen als Parameter); keine Cohesion-Fassade (siehe unten)

Die zugesicherte Fläche und die ausdrücklichen Nicht-Zusicherungen je Baustein stehen in dessen VERTRAG.md — verlinkt in der Übersicht. Dieses Kapitel fasst nur zusammen und ersetzt keinen Vertrag.

CAF-eigene Scan-/Bereinigungsprozesse können über den optionalen prozesslokalen IDocumentMutationGuard an die Mutationssperre eines Consumers gebunden werden. Der Guard läuft in der mutierenden ABP-Unit-of-Work vor der ersten Bestandsabfrage; die Reservierung bleibt bis Dispose bestehen, auch bei Rollback-Kompensation. Ohne Registrierung bleibt der Ablauf erhalten. Produktgeneration und Freigaberegeln gehören dem Consumer, nicht dem Documents-Adapter.

Produktseitige Shared-UI-Bausteine

Was in CAF.Modules.UI.Blazor nicht liegen darf — Fachwissen wie die Ton-Zuordnung eines Statusenums, die Stufen eines Verfahrens, ein Seitengerüst mit den Texten des Produkts — braucht trotzdem einen Ort, den Shell und alle Feature-*.Blazor erreichen, ohne einander zu referenzieren. Dafür darf ein Produkt ein eigenes Razor-Projekt für produktweite UI-Werte führen (Referenz: CAF.Applications.RAL.QualityMarks.HearingPortal.UI.Blazor mit HearingPortalPage, HearingPortalFilterBar, HearingStatusBadge/HearingPortalStatusTone, HearingWorkflowStepper, HearingPortalDropDownList). Regeln: es referenziert Contracts und CAF.Modules.UI.Blazor, nie eine Feature-Runtime oder ein Feature-*.Blazor; die Architekturtests klassifizieren es als Shared UI Building Block — die Kante Shell/Feature-Blazor → Produkt-UI ist die einzige, die diese Klassifikation erlaubt, jede andere Kante zwischen UI-Assemblies bleibt verboten. Die Dreiteilung Cohesion / CAF-Konvention / Produktwert ist in conventions/cohesion-boundary.md entschieden.

Persistierte Kennungen

CAF-Bausteine behalten das Präfix CAF in persistierten Bezeichnern (CAFDocumentShareGrants), unabhängig davon, welches Präfix das konsumierende Produkt verwendet. Der Präfix markiert Ownership, nicht Technologie: Beim Lesen einer Tabelle ist ohne Blick in den Quellcode erkennbar, wer sie besitzt — und es fällt auf, wenn ein wiederverwendbarer Baustein unbemerkt produktspezifisches Wissen aufnimmt.

Die Cohesion-Referenz-Ausnahme

Cohesion (Syncfusion-basiert) ist die verbindliche Komponentenbibliothek für jede von CAF oder einem CAF-Produkt erstellte Oberfläche. MudBlazor, rohes Syncfusion und Blazorise dürfen von Fachcode nicht direkt gerendert werden; ausgenommen sind die von ABP gelieferten MVC-Razor-Pages unter /Account/** auf dem LeptonX-MVC-Theme. Blazorseitig wird keine Vendor-Komponente mehr gerendert; Blazorise kommt allerdings transitiv ueber ABPs Blazor-Theming-Paket in den Graphen und wird auf Bundle-Ebene wieder entfernt.

Dabei gilt eine bewusste Ausnahme von der Regel „Fremdpakete nur über den zuständigen CAF-Baustein":

Jede Assembly, die Cohesion-Komponenten kompiliert, referenziert das Cohesion-Paket direkt per PackageReference — nicht über CAF.Modules.UI.Blazor.

Grund: Razor-Assets wirken zur Compile-Zeit (Komponenten-/TagHelper-Discovery, _Imports, Scoped CSS, Static Web Assets). Sie werden nicht verlässlich über eine ProjectReference-Kette reexportiert, anders als eine gewöhnliche Abhängigkeit auf eine kompilierte DLL. Ohne direkte Referenz bliebe ein Cohesion-Tag unaufgelöst und würde als leeres HTML-Element gerendert; die UI-Assemblies erzwingen deshalb RZ10012 als Fehler (WarningsAsErrors), womit der Build statt der Oberfläche bricht.

Daraus folgt die Rollenteilung:

  • CAF.Modules.UI.Blazor ist Runtime-Integration — Registrierung, Lizenzierung, Bundles, Policy — und wird ausschließlich vom Host eingebunden.
  • Razor-UI-Assemblies (Produkt-Shell, Feature-*.Blazor, und CAF.Modules.UI.Blazor selbst) referenzieren Cohesion direkt. Die Version wird zentral an einer Stelle festgelegt (Directory.Packages.props: Cohesion 3.*-*); die Projekte nennen keine eigene Version und kein VersionOverride — sonst lägen zwei Cohesion-Assemblies im selben Render-Baum. 3.*-* ist eine Floating-Version: sie löst die höchste verfügbare 3.x inklusive Prereleases auf, weil Cohesion mitentwickelt wird; ein Major-Wechsel bleibt eine bewusste Entscheidung. Bewusst kein Bereich wie [3.6.2-alpha,4.0.0): bei einem Bereich löst NuGet die niedrigste passende Version auf, die Abhängigkeit würde also still auf der Untergrenze festfrieren — und eine Untergrenze, die es auf dem Feed nicht wörtlich gibt, löst zusätzlich NU1603 aus (hier ein Fehler, weil Warnungen Fehler sind).

Bewusst in Kauf genommen: Zwei Restores desselben Commits können unterschiedliche Cohesion-Versionen auflösen. Das ist kein Versäumnis, sondern der Zweck — solange Cohesion mitentwickelt wird, ist dieser Build ein fortlaufender Integrationstest dagegen. Ein Lockfile würde eine Regression nicht verhindern, sondern ihre Entdeckung verschieben. Was es dafür braucht, ist Sichtbarkeit: die aufgelöste Version muss bei einem roten Build ablesbar sein. - Ein browser-wasm-Projekt darf das serverseitige Integrationsprojekt nicht referenzieren.

Diese direkte Referenz ist keine aufzuräumende Redundanz. Sie gegen CAF.Modules.UI.Blazor zu tauschen, bricht die Razor-Kompilierung.

Cohesion.Components und Cohesion.Components.Layout werden je Blazor-Projekt im _Imports.razor global importiert — so halten es die elf Feature-Blazor-Projekte des Referenzhosts; das _Imports.razor des Hosts selbst importiert keines von beiden. Generische Namen aus Layout wie Column können mit eigenen Komponenten kollidieren; aufgelöst wird das durch Umbenennen der eigenen Komponente, nicht durch Zurücknehmen des globalen Imports.

Kommerzielle Abhängigkeiten

Zwei Bausteine sind an kommerzielle Pakete gekoppelt, was für einen externen Konsumenten Feed-Voraussetzungen schafft:

  • Authentication → Volo.Abp.Account.Pro.Public.Web (lizenzierter ABP-Feed). Ein Architekturtest pinnt die Invariante „exakt einmal referenziert, exakt ein Vendor-DependsOn".
  • UI.Blazor → Cohesion aus dem GitLab-Gruppen-Feed (Quelle cohesion in NuGet.Config). Solange die aufgelöste Version ein Prerelease ist, bleibt auch der Baustein Prerelease-versioniert.

Cohesion nachschlagen statt raten

Cohesion liefert seinen Komponentenvertrag maschinenlesbar mit. Regel: Parameter werden nachgeschlagen, bevor Markup entsteht — nicht aus dem Gedächtnis rekonstruiert und nicht aus Syncfusion-Wissen abgeleitet. Cohesion besitzt seine API selbst; kein Syncfusion-Typ liegt auf einem öffentlichen Parameter, geraten wird also verlässlich falsch.

Zwei Wege, in dieser Reihenfolge:

  1. MCP-Server (Primärweg). Registriert in .mcp.json im Repository-Root (Server cohesion, node tools/cohesion-mcp/dist/index.js aus dem Cohesion-Checkout). Er beantwortet Komponenten-, Parameter-, Token- und Pattern-Fragen direkt.
  2. aidx/-Verzeichnis im NuGet-Cache (Offline-Weg). Das Paket bringt den Vertrag selbst mit, auch ohne Cohesion-Checkout und ohne laufenden Server:

text %USERPROFILE%\.nuget\packages\cohesion\<aufgelöste Version>\aidx\

Welche Version das gerade ist, sagt Get-ResolvedCohesionVersion bzw. der Statusbericht von setup.cmd -Verify. Hier steht bewusst keine feste Nummer: Directory.Packages.props:22 pinnt Cohesion nicht, sondern lässt die Version mit 3.*-* mitlaufen — jede hier genannte Nummer wäre binnen Tagen falsch. Inhalt:

Datei Zweck
llms.txt Kurzüberblick, Einstiegspunkt
llms-full.txt vollständiger Kontext zum einmaligen Laden
cohesion-catalog.json der Katalog: alle Komponenten der aufgelösten Version mit Kategorie, Basisklasse und vollständiger Parameterliste; componentCount im Kopf nennt die Zahl (sie wächst mit jedem Prerelease)
snippets/*.md Familien-Dateien (plus _TEMPLATE.md) mit je einem minimalen Beispiel

Zwei Fallen: llms.txt verweist intern auf docs/ai-dx/…, im NuGet-Paket liegt dieser Inhalt flach unter aidx/ — der genannte Pfad existiert im Paket nicht. Und der MCP-Server liest seinen eigenen Katalog aus dem Cohesion-Checkout; er kann damit von der restaurierten Paketversion abweichen. Versionsgenau zum Build ist nur aidx/.

Der Katalog entscheidet, welche Komponenten existieren — nicht die Erinnerung an eine frühere Version. In 3.6.2 sind CohesionSelect und CohesionSearchInput nicht enthalten; der Ersatz für eine Auswahlliste heißt CohesionDropDownList. Wer solche Namen ungeprüft schreibt, erzeugt Razor-Fehler statt UI.

Override-Register

Jeder lokale Behelf für eine Cohesion-Lücke steht hier mit der Gegenleistung, die ihn zurücknimmt. Ohne diese Spalte wird ein Workaround zum Dauerzustand, weil niemand mehr weiß, worauf er wartete.

Override Wo Wird zurückgenommen durch
Portal-H1 eine Stufe über der Template-Größe — UP-68 / RAL-QM-HP-103 (Änderung zu F1, person-004, 20.10.2026) applications/RAL/QualityMarks/HearingPortal/src/UI/Blazor/Pages/HearingPortalPage.razor.css: .ralqm-page--large-title ::deep .cohesion-page-header-template__title setzt ausschließlich font-size: 1.5rem; die vier Portalrouten schalten die Klasse über HearingPortalPage LargeTitle="true", interne Seiten nicht; seit RAL-QM-HP-118 (person-004, 22.10.2026) ebenso die vier Rechtsseiten /Impressum, /PrivacyPolicy, /CookiePolicy, /Barrierefreiheit in jedem Rahmen (anonyme Shell, interne Shell, Portallayout), damit ihre H1 über den eigenen h2/h3 (--coh-font-size-lg/-md, Zone 1) steht und die Rechtsseiten überall gleich aussehen. Grund: das Portal hat keine Schiene und keine Brotkrume, der Kopf trägt die Hierarchie allein, und die Kartentitel (eigenes Markup, --coh-font-size-lg) sollen unter der H1 stehen. CohesionPageHeaderTemplate nimmt die Titelgröße als Parameter oder Token (UP-68); dann Parameter statt Regel, Klasse und Regel entfallen.
Umbruch der Sekundärnavigation der Kopfleiste — UP-70 / RAL-QM-HP-118 (person-004, 22.10.2026) applications/RAL/QualityMarks/HearingPortal/src/Host/wwwroot/css/hearing-portal-chrome.css: body.abp-application-layout .cohesion-workspace-navbar__inner setzt ausschließlich flex-wrap: wrap; height: auto; min-height: calc(var(--coh-space-xl) + var(--coh-space-lg)) (die ausgelieferten 3,5 rem als Mindesthöhe, auf der Abstandsskala geschrieben), body.abp-application-layout .cohesion-workspace-navbar__secondary ausschließlich flex: 0 1 auto; min-width: 0, body.abp-application-layout .coh-navbar-links ausschließlich flex-wrap: wrap, alle drei in jeder Breite; keine Längenliterale, keine Farbe, kein !important, (0,2,1) gegen die restaurierten Scoped-Regeln (0,2,0). Befund (gemessen 21.10.2026, development 9e43fe99, Cohesion 3.6.3-alpha.0.19): NavBarLinks rendert die vier Rechtslinks der anonymen Shell als eine white-space: nowrap-Zeile (543 px de, 488 px en) in einem Container mit flex: 0 0 auto; der Full-Viewport-Shell-Container beschneidet (overflow-x: hidden). Bei 320 bis 390 px waren „Cookies“ und „Barrierefreiheit“ unsichtbar, Tab auf den verdeckten Link verschob die ganze Seite. Oberhalb von 768 px ist die innere Zeile der Leiste eine Zeile fester Höhe ohne Umbruch, in der weder Aktionen noch Sekundärnavigation schrumpfen; neben den drei Bedienelementen war der letzte Link bei 800 bis 1024 px (de) bzw. 800 bis 900 px (en) beschnitten und die Bedienelemente überdeckten die Brotkrume (Entscheidung person-004 vom 22.10.2026, in den Umfang genommen). Die erste Regel wirkt auf jede Kopfleiste des App-Layouts, auch auf die angemeldete interne Shell mit leerem Sekundärbereich: dort überdeckten bei 800 bis 1100 px die Bedienelemente die Brotkrume (allein __leading schrumpft, min-width: 0) und bei 800 px lag das Kontomenü außerhalb des Viewports; mitbehoben (Entscheidung person-004 vom 22.10.2026, gemessen auf acht internen Seiten), Folge: Leiste dort 76 bis 128 px statt 61 px, bei langer Brotkrume um 1200 px eine zweite Zeile für das Kontomenü. Das statische Fehlerdokument hat eine eigene Navigation im Aktionen-Slot und wird in Zone 1 (ErrorDocument.razor.css) begrenzt. Nachweis: NarrowLegalNavigationStyleTests (Spezifität gegen das restaurierte Paket, genau diese Deklarationen, Rücknahmebedingung als Gegenprobe) und die Browserstufen error-pages und customer-accessibility bei 320, 390 und 768 px. UP-70: CohesionAppShellTemplate lässt die Kopfleiste umbrechen, sobald Brotkrume, Aktionen und Sekundärnavigation nicht in eine Zeile passen (in jeder Breite; schrumpfender Container, umbrechende Liste oder zweite Zeile), oder führt die Sekundärnavigation in den Drawer, und der Aktionen-Slot darf schrumpfen; sobald ein restauriertes Paket beide Prüfsteine erfüllt und die sechs anonymen Routen bei 320, 390, 800 und 1024 px sowie die interne Kopfleiste bei 800 bis 1100 px ohne Produktregel bestehen (nichts überdeckt, nichts außerhalb des Viewports), entfallen alle drei Regeln und NarrowLegalNavigationStyleTests wird zur Negativprobe.
Terminaler Textfeld-Blur nach Sitzungsentzug — UP-67 applications/RAL/QualityMarks/HearingPortal/src/Host/wwwroot/session-activity.js: einmaliger Capture-Blur ausschließlich am bei bestätigtem Session-401 fokussierten Element, direkt nach leaving = true. Keine globale Fehlerfilterung und kein Guard bei bloßem Disconnect oder gewöhnlichem pagehide. Ausgelieferter Control-Lebenszyklusfix nach UP-67, danach echter Kontosperre-/Kennungswechselpfad mit getrenntem Transport und fokussierter Suche ohne Host-Behelf grün; normale Blur-Übernahme und temporäres Reconnect bleiben geprüft. Der Ausgangsfehler ist im vollständigen Lauf hp11privacy20261019c und in der kontrollierten Diagnose hp11blur20261019b reproduziert.
ContractManager: Tastaturfokus der Grid-Knöpfe, Seitengrößenwahl und Spaltenoptionen — UP-66 / RAL-LL-CM-13 applications/RAL/LogoLicense/ContractManager/src/Features/Catalog/Blazor/Pages/CatalogProductsPage.razor.css: eigener Grid-Scope und .cohesion-data-grid-host mit button:focus-visible bzw. [role="combobox"]:focus-visible und li:has(input[type="checkbox"]:focus-visible), innerer Ring aus Fokus-Tokens, ohne !important. Reale Entwicklungsproben am 17.10.2026: probe-q ohne sichtbaren Spaltenknopf-Fokus; diagnostic-refresh-focus in DE/EN rot ohne die eigene Regel und grün nach Wiederherstellung; Seitengrößenwahl in diagnostic-external-chooser-d ohne Stiländerung, korrigiert in diagnostic-grid-f. Checkboxoptionen ändern ursprünglich nur ihre Fläche mit 1,101:1 Kontrast. diagnostic-chooser-focus-green-c belegt in DE/EN rot nach Entfernen der Regel und grün nach identischer Wiederherstellung. diagnostic-chooser-contrast-positive misst den tatsächlichen Ring gegen innere/äußere Nachbarfläche mit 4,1195:1 bzw. 4,3383:1; beide begrenzten Proben sind keine kanonische Gesamtabnahme. Der gescopte Knopfselektor (0,4,1) gewinnt gegen die restaurierte Toolbar-Fokusregel (0,4,0). UP-66 verlangt sichtbaren, ungeclippten Fokus; Rücknahme erst nach ausgeliefertem Paketfix und echtem Browserlauf ohne Produktregel.
ContractManager: aktive Rechtsnavigation, UP-64 / RAL-LL-CM-3 applications/RAL/LogoLicense/ContractManager/src/Host/wwwroot/css/contract-manager-chrome.css: body.abp-application-layout .coh-navbar-links__link--active ändert ausschließlich die Textfarbe auf --coh-surface-fg. Kanonische LL-Diagnose cm3privacy20261016a am 16.10.2026: aktiver Text auf /PrivacyPolicy, #fe5000 auf #fffaf5, 16 px normal, 3,18:1 statt 4,5:1. ShellLegalNavigationContrastTests prüft echtes DE/EN-bUnit-DOM, Vorrang gegen das restaurierte Scoped-CSS und Ruhe-/Hoverkontrast in vier Paletten. Mutation zurück zur Markenfüllfarbe macht beide hellen Paletten rot. Rücknahme erst bei ausgelieferter eigener kontrastsicherer Textrolle gemäß UP-64 und bestandenem Paket-/Browservergleich ohne diese eigene LL-Kopie; aktiver Schatten und Seitenmarkierung bleiben bei Cohesion.
Kontrast der aktiven Rechtsnavigation — UP-64, seit 2026-10-15 (RAL-QM-HP-79) applications/RAL/QualityMarks/HearingPortal/src/Host/wwwroot/css/hearing-portal-chrome.css: body.abp-application-layout .coh-navbar-links__link--active setzt ausschließlich color: var(--coh-surface-fg) Befund: axe im Diagnoselauf der Stufe customer-accessibility am 15.10.2026 misst auf allen vier anonymen Rechtsseiten 3,18:1 (Markentext #fe5000 auf #fffaf5, 16 px normal). Im restaurierten Cohesion 3.6.3-alpha.0.17 liest NavBarLinks für den aktiven Text direkt --coh-color-primary; ein eigener aktiver Texttoken fehlt. Der Produktselektor gewinnt mit (0,2,1) gegen die ausgelieferte Scoped-Regel (0,2,0), ohne !important; Seitenmarkierung und Markenschatten bleiben bei Cohesion. SemanticColourContrastTests.Active_legal_navigation_text_outranks_the_restored_brand_rule_and_clears_AA_in_all_palettes prüft die tatsächlichen Paketregeln, ihre Spezifität sowie den Vordergrund auf Ruhe-/Hoverfläche in vier Paletten. Zurückgenommen durch UP-64: Cohesion liefert eine getrennte kontrastsichere aktive Textrolle (etwa --coh-navbar-link-active-color) oder einen entsprechenden Parameter; nach Entfernung des Behelfs bestehen die vier Rechtsseiten in allen Paletten ohne Kontrastbefund. Der vollständige Browserlauf hp79full20261015n besteht mit dem Behelf auf den vier anonymen Rechtsseiten ohne axe-A/AA-Befund. Die vier Paletten sind durch den genannten Paket-CSS-Kontrasttest belegt; dies ist kein Browsernachweis sämtlicher Paletten. UP-64 bleibt bis zur ausgelieferten und ohne Behelf geprüften Paketkorrektur offen.
Lesende Bezugsfelder der Sprach-Editoren abgesetzt (RAL-QM-HP-101 E19, Entscheidung person-004 vom 16.10.2026): background auf .e-input-group:has(input[readonly]) und …:has(textarea[readonly]) unter dem Bezugsbereich, je ::deep, Wert color-mix(in srgb, var(--coh-surface-muted) 8%, var(--coh-input-bg, var(--coh-surface-bg))) applications/RAL/QualityMarks/HearingPortal/src/Features/Hearings/Blazor/Pages/HearingTemplatesPage.razor.css (.hearing-templates__pane--reference) und applications/RAL/QualityMarks/HearingPortal/src/Features/Hearings/Blazor/Components/HearingCommunicationStepPanel.razor.css (.hearing-communication-step__pane--reference) und seit dem 16.10.2026 applications/RAL/QualityMarks/HearingPortal/src/Features/Hearings/Blazor/Pages/HearingCircularPage.razor.css (.hearing-circular__pane--reference, Rundnachricht); gemessen in ReadOnlyReferenceFieldStyleTests (Tokens statt Literale, kein !important, Spezifität über der Vendor-Regel .e-input-group) Befund (im restaurierten 3.6.3-alpha.0.17 gelesen): CohesionTextInput/CohesionTextAreaInput mit IsReadOnly="true" rendern readonly und aria-readonly, aber keine eigene Darstellung; ein lesendes Feld sieht aus wie ein bearbeitbares und, neben einem gesperrten Zielfeld (Enabled="false", grau), sogar bearbeitbarer. Rücknahmebedingung von UP-66: ein Paket, in dem IsReadOnly eine eigene Fläche oder ein Token (--coh-input-readonly-bg) trägt; dann entfallen beide Regeln und ReadOnlyReferenceFieldStyleTests wird zur Negativprobe.
Glyph für den Caret des Dropdown-Triggers (SPEC-RALQM-UI-01): content auf .cohesion-dropdownbutton .e-caret::before applications/RAL/QualityMarks/HearingPortal/src/Host/wwwroot/css/hearing-portal-chrome.css, Block „ZONE 2" oberhalb der Top-Bar-Menüs Befund: CohesionDropDownButton rendert im PopupContent-Pfad <span class="e-icons e-caret">, das nie einen Glyph bekommt. Alle 37 content-Regeln für .e-caret im ausgelieferten staticwebassets/css/syncfusion.css (geprüft gegen 3.6.3-alpha.0.13) verlangen einen Vorfahren wie .e-dropdown-btn; die Komponente erzeugt über ComputedCssClass aber cohesion-dropdownbutton. Die vier Regeln ohne solchen Vorfahren verlangen .e-image-editor und greifen hier ebenfalls nicht. Der Span war immer leer — sichtbar wurde der Defekt erst, als die Trigger ihre Beschriftung verloren und der Caret der einzige verbliebene Hinweis auf ein aufklappbares Menü war. Gewinnt ohne !important, weil es keine konkurrierende content-Deklaration gibt. Glyph aus Font Awesome (\f078, „Font Awesome 7 Free" 900), nicht aus dem Syncfusion-Icon-Font: das Produkt bindet Font Awesome selbst ein und hält es als einzigen Icon-Font auf dem Dokument. Zurückgenommen durch einen Upstream-Punkt an Cohesion — entweder ShowCaret/CaretIconCss an CohesionDropDownButton, oder ein Glyph für den Caret im PopupContent-Pfad. Zweiter, davon unabhängiger Upstream-Punkt aus demselben Pfad: CohesionDropDownButton setzt aria-expanded="false" hart und aktualisiert es beim Öffnen nie, jeder Trigger meldet dauerhaft „zugeklappt".
UP-708-02: Kontrast aktiver Modulbeschriftungen — zurückgenommen am 14.09.2026 Der direkte Farb-Override in Host/wwwroot/css/hearing-portal-chrome.css ist entfernt; Architektur- und Browserprüfung messen den ausgelieferten Vordergrund Cohesion MR !17, veröffentlicht und restauriert als 3.6.3-alpha.0.8, verwendet --coh-nav-fg. Integrierte CAF-Prüfung: Normal/Hover in allen vier Paletten mindestens 10,69:1; die alte Farbe fällt mit 3,57:1 durch. Desktop-Breite über öffentlichen Token --coh-nav-rail-width: 8rem, alle Modulnamen einzeilig bei 1024/1440 px, mobil bei 390 px ohne Überlauf. Nachweise und ursprünglicher Befund.
Modulschiene nur mit Modulen: UseModuleRail an CohesionAppShellTemplate hängt an _navItems.Count > 0 statt fest auf true zu stehen Shell/Components/Layout/HearingPortalShellLayout.razor, Parameterzeile samt Begründungsblock darüber AppModuleNavigation leitet seine Module aus NavItems ab. Ohne Module rendert es trotzdem — eine leere Schiene plus einen „Resources"-Umschalter — und verschiebt SecondaryItems aus der immer sichtbaren Fußzeile in das Kontextpanel, das hidden=true trägt, bis etwas es öffnet (ShowPanel ist _resourcesOpen oder ein gewähltes Modul). Für einen anonymen Besucher ist das ABP-Menü leer, das Panel öffnet also nie von selbst. Gemessen bei 1440×900 auf /PrivacyPolicy mit unbedingter Schiene: kein einziger sichtbarer Link auf /PrivacyPolicy oder /CookiePolicy — die Schienen-Fußzeile war sichtbar und enthielt nur den Umschalter, Kontext- und Mobil-Fußzeile enthielten beide Links und waren beide unsichtbar. Damit war die D1-Pflicht verloren: diese Fußzeile ist die einzige dauerhaft erreichbare Route zu beiden Seiten, sobald der Cookie-Hinweis weg ist. Zurückgenommen durch zwei Upstream-Punkte: (1) die Schiene hält SecondaryItems auch ohne Module ohne Klick erreichbar; (2) AppModuleNavigation beschriftet Umschalter und Paneltitel über Parameter statt mit den hartkodierten englischen Zeichenketten „Resources" (AppModuleNavigation.razor:60 und .razor.cs:90) — UI-Texte sind in diesem Produkt verbindlich Deutsch. — Upstream-Punkt (1) ist am 19.09.2026 gegenstandslos geworden: mit SecondaryPlacement="TopBar" (SPEC-RALQM-UI-01) laufen SecondaryItems gar nicht mehr über die Schiene, sondern über die Workspace-Leiste, die sie unabhängig von User rendert. Die gemessene D1-Lücke kann auf diesem Weg nicht mehr entstehen. Der Behelf selbst bleibt, aber nur noch aus dem kleineren Grund: eine Schiene ohne Module ist Rahmen um nichts. — Upstream-Punkt (2) ist seit 3.6.3-alpha.0.16 erfüllt (UP-52; hier bis 2026-10-10 als offen geführt): CohesionAppShellTemplate reicht ResourcesText und CloseModuleNavigationText durch, beide mit einer Vorgabe aus der Kultur der Oberfläche; die deutsche Satellitenressource im restaurierten 3.6.3-alpha.0.17 trägt „Ressourcen“. Damit wartet die Zeile auf keine Cohesion-Änderung mehr; was bleibt, ist eine Produktentscheidung und gehört beim nächsten Aufräumen aus diesem Register in die Beschreibung des Shell-Layouts.
Semantische Papierkorbtabelle mit Cohesion-Aktionen Features/Filing/Blazor/Pages/FilingTrashPage.razor Auslöser war das Clipboard-textarea direkt unter role=grid in 3.6.3-alpha.0.1: axe meldete aria-required-children (Browserdiagnose 18). Die restaurierte 3.6.3-alpha.0.2 ruft bei Created und DataBound prepareClipboard auf und markiert den erhaltenen Clipboard-Puffer mit aria-hidden="true". Dieser Paketbefund ersetzt keinen Browsernachweis. Die einfache Tabelle bleibt, solange sie das benötigte Verhalten abdeckt. Ein erneuter Grid-Einsatz verlangt tatsächlich benötigtes Grid-Verhalten und einen Portalnachweis für Kopieren, axe sowie Fokus ohne fokussiertes verborgenes Element. Auftrag in SPEC-RAL-QM-HP-19-ablage-papierkorb.md.
Filing-Dateiaktionen in einem CohesionDialog über dessen öffentliche ChildContent-Fläche Features/Filing/Blazor/Pages/FilingPage.razor und .razor.cs CohesionDropDownButton.PopupContent in 3.6.3-alpha.0.1 unterdrückte Enter und schloss bei Tab (Browserdiagnose 15). In der restaurierten 3.6.3-alpha.0.2 verwendet der öffentliche Popup-Pfad einen nativen Popover mit eigenem Tastaturhandler. Der Aktionsdialog bleibt bis zum realen Portalnachweis: alle Aktionen über Tab/Pfeile erreichbar, Enter/Space aktivieren, Escape und Schließen geben den Fokus ohne künstliche Fokussetzung zurück; auch schmale Ansichten bleiben bedienbar. Das korrigierte Dialog-Body-Mapping wird bereits über ChildContent konsumiert. Upstream-Auftrag in SPEC-RAL-QM-HP-19-ablage-papierkorb.md.
Produkt-Stylesheet malt html/body — aus dem Register genommen am 2026-09-18 Host/wwwroot/css/hearing-portal-chrome.css, gebündelt über HearingPortalModule.ConfigureBundles Kein Override mehr, sondern Produkt-Chrome. Der Eintrag sah diesen Schritt selbst vor („wird nicht mehr zurückgenommen, sondern beim nächsten Aufräumen aus diesem Register in die normale Chrome-Beschreibung verschoben"). LeptonX' Blazor-Hälfte ist entfernt, Cohesion fasst html/body bewusst nicht an — die Regel ist damit die einzige Quelle dieser Deklaration und braucht keine Rücknahmebedingung. Die frühere Überschriftenregel ist bereits 2026-09-09 gemessen und entfernt.
Markenfarbe als Textfarbe für nicht aktive Sidebar-Gruppenlabels abgedunkelt — zurückgenommen am 2026-09-19 Der color-mix-Block in src/Host/wwwroot/css/hearing-portal-chrome.css (65 % --coh-color-primary auf --coh-surface-fg, begrenzt auf --group:not(.coh-sidebar-nav__item--active)) ist entfernt Rücknahmebedingung war eine kontrastsichere Textrolle für Gruppenbeschriftungen. Im Paket 3.6.3-alpha.0.13 gelesen: die ausgelieferte Gruppenregel .coh-sidebar-nav__item--group deklariert nur font-weight: 600 und keine Farbe mehr; Gruppen erben wie jeder Eintrag die Navigationsfarbe des Containers .coh-sidebar-nav (--coh-nav-fg, Rückfall --coh-surface-fg). Der Behelf mischte damit Markenfarbe in einen Text, der ohne ihn Flächentext ist. SemanticColourContrastTests (Active_sidebar_labels_inherit_the_shipped_foreground_and_clear_AA_in_all_four_palettes) verlangt seither, dass kein Produkt-Stylesheet eine Farbe auf .coh-sidebar-nav__label setzt, dass die Gruppenregel farblos bleibt, und misst die geerbte Farbe auf --coh-surface-bg in allen vier Paletten. Aktiver Selektor bereits am 2026-09-10 zurückgenommen: Cohesion 3.6.3-alpha.0.1 malt aktive Einträge einschließlich aktiver Gruppen weiß auf --coh-color-primary-strong; der alte Mix ergab darauf 1,21:1 in orange-light, die Pakettokens ergeben 4,53:1 in orange-light/dark und 5,07:1 in neutral-light/dark.
CohesionPageHeaderTemplate: Außen-Padding 1rem 1.5rem 0 auf 0 0 var(--coh-space-md) gesetzt — zurückgenommen am 2026-09-19 Die Padding-Deklaration in applications/RAL/QualityMarks/HearingPortal/src/UI/Blazor/Pages/HearingPortalPage.razor.css ist entfernt; HearingPortalPage.razor gibt dem Template Padding="0 0 var(--coh-space-md)". Die Trennlinie --coh-surface-border unter dem Kopf bleibt in derselben Regel — sie war nie ein Override, das Template zeichnet keine, sie ist Produkt-Chrome Rücknahmebedingung war ein Upstream-Parameter für das Außen-Padding. 3.6.3-alpha.0.13 liefert CohesionPageHeaderTemplate.Padding („Optional outer CSS padding. Omit to retain the responsive template spacing.“), gerendert als Inline-style auf dem header, das gegen die Scoped-Regel 1rem 1.5rem 0 gewinnt. AuditLogDetailUiTests.Detail_head_states_the_page pinnt den Stil auf dem Kopf. Die zweite Hälfte (Umbruch bei 390 px) war bereits am 12.09.2026 entfallen: das Bundle trägt flex-wrap: wrap auf __bar/__actions und min-width: 0 auf __titles/__actions.
Token --coh-color-surface im Produkt-Root als var(--coh-surface-bg) definiert — zurückgenommen am 2026-10-10 Die Deklaration samt Kommentar ist aus dem Root-Block der Produkt-Themewerte in applications/RAL/QualityMarks/HearingPortal/src/Host/wwwroot/css/hearing-portal-chrome.css entfernt Rücknahmebedingung von UP-10 anders erfüllt als hier vorgesehen: die Paletten deklarieren den Token nicht und werden es nicht tun (Cohesions Bewertung vom 2026-10-10, Punkt 3: optionaler Konsumenten-Haken in design/token-contracts.json), aber kein Bauteil malt seine Fläche mehr allein aus ihm. Im restaurierten 3.6.3-alpha.0.17 gelesen: CohesionPanel malt var(--coh-panel-bg, var(--coh-surface-bg, #ffffff)) (seit 3.6.3-alpha.0.3); der Name steht nur noch dreimal im Bundle von CohesionEditableTable (Kopf, Wechselzeile, Fuß), jeweils hinter --coh-table-* und mit Rückfall --coh-surface-bg. Die frühere Angabe dieser Zeile, auch CohesionTextEditor lese den Token, trifft auf 0.17 nicht zu: der Editor liest --coh-color-surface-secondary und --coh-color-surface-hover (Rückfall --coh-card-bg), die eine Suche nach dem Namen als Teilzeichenkette mitfindet. Die Deklaration malte zuletzt nichts, das Produkt rendert keine der beiden Komponenten. Konsumentenprüfung der Bewertung (ein Panel in orange-dark behält die Seitenfläche): Browsernachweis ausstehend.
ValidateOnInput="@true" an jedem CohesionTextInput/CohesionTextAreaInput innerhalb eines <EditForm> — zurückgenommen am 2026-09-19 72 Attribute in 16 Dateien unter Features/{Institutions,Hearings,Authorization,Identity,Languages,Settings,ValueLists}/Blazor/ und UI/Blazor/Account/ entfernt; kein Produktmarkup trägt das Vendor-Attribut mehr Gemessen im vollen BrowserGate (Stufe 6): unter einem kaskadierten EditContext rendert Syncfusion kein oninput, solange ValidateOnInput aus ist; der Wrapper hob ValueChanged nur aus diesem Input-Pfad — @bind-Value wäre damit in jedem Formular im Browser tot gewesen. Rücknahmebedingung seit 3.6.3-alpha.0.3 erfüllt: alle drei Wrapper setzen AddComponentParameter(…, "ValidateOnInput", EditContext != null) selbst, am IL geprüft (Sequenz 61 SfTextBox, 39 SfNumericTextBox, 23 Textarea); das durchgereichte Attribut lag im Splat nach der Wrapper-Zuweisung und erzwang außerhalb eines Formulars fälschlich true. Der Behelf stand bis zum 2026-09-19 nur noch, weil das volle BrowserGate keine Formularstufe erreichte; Nachweis für den Rückbau: das volle BrowserGate (41 Stufen, mit axe, Tastatur- und Rechteprüfung) lief am 2026-09-19 auf 3.6.3-alpha.0.13 mit entfernten Attributen durch alle Formularstufen (Anlage, Einstellungen, Institutionen, Konten, Portal); die einzige rote Stelle war die Konsolen-Bilanz am Ende, ein bekannter Vendor-Teardown-Fehler im Schritt history der Kontenliste, nicht die Formularbindung.
HearingPortalDropDownList — Produkt-Picker um CohesionDropDownList, der einen leeren ValueChanged-Echo bei gehaltenem Wert verwirft, den Wrapper per @key neu montiert und nur bei geändertem Futter zum Wrapper durchrendert (Stufe 6, Schritt 7; Nachtrag 2026-09-07) Applications/…/HearingPortal/UI/Blazor/Inputs/HearingPortalDropDownList.razor; 62 Picker in 22 Dateien, davon 25 auf den drei Formularseiten (HearingDetailPage 18, HearingCreatePage 5, HearingRepliesPage 2) — die Zeile nannte bis 12.09.2026 „16 Picker", gezählt vor dem Designdurchgang Gemessen im vollen BrowserGate (44 Läufe, Server-Probes): der Wrapper (alpha.0.6) absorbiert nur Echos, die dem gebundenen Wert entsprechen, übernimmt sonst Syncfusions null als eigenen Wert und rendert das Control leer — nach jedem Pick und jedem Re-Render hinter dem Seitengerüst. Zurückgenommen, sobald der Wrapper einen leeren Echo bei nicht-leerem Value selbst verwirft (UP-15 in cohesion-upstream.md); dann rendern die Seiten CohesionDropDownList wieder direkt.
Avatar-Initialen der Mitarbeitendenkonten-Liste (.staff-accounts__avatar ::deep .e-avatar) auf Kartenfläche und Flächentext Features/Authorization/Blazor/Pages/StaffAccountsPage.razor.css Syncfusion malt die Initialen #6b7280 auf #e5e7eb (3,9:1) bzw. #9ca3af auf #4b5563 (2,6:1, dunkles Blatt); CohesionAvatar hat keinen Farbparameter. Kartenfläche + Flächentext liegen in allen vier Paletten >= 12:1 (Messung der Überschriftenregel, 2026-09-09). Zurückgenommen, sobald Cohesion den Avatar aus Tokens färbt.
Seiten fokussieren den Auslöser nach dem Abbrechen eines CohesionConfirmDialog (und nach der bestätigten Deaktivierung in der Liste) selbst (RAL-QM-HP-10) UI/Blazor/Inputs/ElementFocus.cs. Behelf hinter dem Kit-Dialog (drei Seiten): Features/Institutions/Blazor/Pages/InstitutionsPage.razor, InstitutionEditPage.razor und seit RAL-QM-HP-3 InstitutionGroupEditPage.razor (OnAfterRenderAsync, Feld _returnFocusTo); die zehn weiteren Verwender des Dialogs in anderen Features sind nicht verdrahtet (Stand 18.09.2026: 13 Seiten; beim Anlegen dieser Zeile am 11.09.2026 waren es zwei verdrahtete und sieben weitere). Kein Behelf, reguläre Seitenfunktion (zwei Seiten): InstitutionGroupAssignPage.razor (Fokus auf den Korb-Umschalter, RAL-QM-HP-3) und Features/Hearings/Blazor/Pages/HearingDetailPage.razor (Rückfrage „Zugang entziehen oder wieder freigeben“, RAL-QM-HP-5: Fokus auf den Bereich, zurück zum Auslöser, nach dem Erfolg auf die Gegenaktion) rufen denselben Helfer ohne Kit-Dialog – dort gibt es keine Fokusfalle, die die Rückgabe übernehmen könnte Gemessen im BrowserGate, Stufe institutions-maintenance (isolierter Lauf 2026-09-09; integrierter Lauf ausstehend): nach dem Schließen eines CohesionConfirmDialog 3.6.2-alpha.0.13 liegt der Fokus auf dem <body>. Ursache aus dem Kit gelesen: das Panel wird fokussiert, bevor die Fokusfalle den Öffner merkt (UP-23 in cohesion-upstream.md). Nach einem bestätigten Löschen ist der Auslöser fort, dort bleibt der Fokus auf dem Dokument; nach einer bestätigten Deaktivierung unter dem Statusfilter Aktiv ebenso (die Zeile verschwindet), die Rückgabe ist dort bestmöglich und die nächste vom Benutzer ausgelöste Abfrage (ReloadAsync) verwirft sie. Stand 18.09.2026: Laut Kit-Quelle ist die Reihenfolge seit 3.6.3-alpha.0.6 umgekehrt (focustrap.activate vor dem Panel-Fokus; festgehalten am 12.09.2026 im Kommentar von ElementFocus.cs); aufgelöst wurde an diesem Tag 3.6.3-alpha.0.12. Im Browser ist das nicht gemessen – die Rücknahmebedingung gilt deshalb als unbelegt, nicht als erfüllt. Zurückgenommen, sobald ein BrowserGate-Lauf der Stufe institutions-maintenance mit entfernten Aufrufen den Fokus auf dem Öffner zeigt; dann entfallen die Aufrufe der drei Seiten hinter dem Kit-Dialog. ElementFocus selbst bleibt: Die beiden Seiten ohne Kit-Dialog brauchen ihn unabhängig davon. Der Rückbau ist ein eigener Vorgang.
CohesionTimeline je Ladung per @key neu montiert (RAL-QM-HP-7) — zurückgenommen am 2026-09-19 @key="@_timelineGeneration", Zähler und Erklärkommentar in Features/Hearings/Blazor/Components/HearingHistoryList.razor entfernt Gemessen in bUnit auf 3.6.3-alpha.0.6: die Timeline sammelte ihre CohesionTimelineItem beim Registrieren und ließ ein Item, das ein Render entfernt hatte, nicht los — drei Einträge blieben drei nach Einschränkung auf zwei. Rücknahmebedingung war die Abmeldung des Items beim Dispose (UP-24). 3.6.3-alpha.0.13 liefert sie (Changelog „Timeline entries removed from the markup stop rendering … Consumers can drop the @key remount of the whole timeline“). Nachweis: HearingHistoryListTests.Restricts_by_event_type_and_institution_and_counts_the_hits zählt nach der Einschränkung zwei und nach der Institution einen .hearing-history__entry ohne Schlüssel; mit 3.6.3-alpha.0.12 und entferntem Schlüssel ist derselbe Test rot (Mutationsprobe 2026-09-19, siehe MR).
Pager-Behelf zurückgenommen am 01.10.2026 (RAL-QM-HP-1, RAL-QM-HP-74) PageSizes="null" und Fehlerkommentar aus applications/RAL/QualityMarks/HearingPortal/src/Features/Hearings/Blazor/Workspace/HearingOpenTasksPanel.razor entfernt; acht Zeilen je Seite bleiben Rücknahmebedingung von UP-35 mit veröffentlichtem 3.6.3-alpha.0.16 erfüllt: ohne Parameter keine Auswahl; konfigurierte Größen lokalisiert und nach Auswahl, Escape und Fokuswechsel weiter bedienbar (isolierter Paket-Testhost). Panel_pager_renders_no_page_size_dropdown sichert den Produkt-DOM ohne Behelf.
Grid-Chrome, die Cohesion nicht themt: Werkzeugleiste, untere Kopfzeilenlinie, Seitenzahl-Kasten des Pagers — zurückgenommen am 2026-10-01 Der Zone-2-Block „GRID CHROME COHESION DOES NOT THEME“ (acht Regeln auf .e-toolbar, .e-tbar-btn, .e-gridheader, .e-headercell, .e-pagercontainer, .e-ddl-icon unter .cohesion-data-grid-host) ist aus applications/RAL/QualityMarks/HearingPortal/src/Host/wwwroot/css/hearing-portal-chrome.css entfernt; kein Produktstil adressiert den Grid-Host mehr Rücknahmebedingung von UP-36 erfüllt: 3.6.3-alpha.0.16 veröffentlicht --coh-grid-toolbar-bg, -color, -icon-color und -border-color (aidx/design-tokens.json) und malt Werkzeugleiste, untere Kopfzeilenlinie und .e-pagercontainer aus --coh-grid-* (cohesion.css, Regeln auf .e-grid.cohesion-data-grid, mit !important). Live nach dem Löschen gemessen (1440 px, orange-light, /anhoerungen): Werkzeugleiste rgb(255, 255, 255) = Fläche des Grids, Kopfzeile rgb(245, 245, 244), Zeilen rgb(255, 255, 255) — Werte und Aufnahme unverändert gegenüber der Brücke; die ausgelieferte hearing-portal-chrome.css enthält keine der Regeln mehr. Nicht im Browser gemessen: die drei anderen Paletten. applications/RAL/QualityMarks/HearingPortal/tests/Authentication/ProductChromeStylesheetTests.cs: der Stolperdraht Vendor_grid_chrome_still_paints_literals_and_publishes_no_toolbar_token und die Spezifitätsprüfung sind gelöscht; The_restored_package_themes_the_grid_toolbar_header_line_and_pager_from_grid_tokens hält die Lieferung fest, The_retired_bridges_stay_out_of_the_product_stylesheet die Löschung.
Höhe und Zentrierung der Picker — zurückgenommen am 2026-10-01 Die Komponenten-Tokens auf .ralqm-form und die eine Zentrierungsregel auf .e-input-group der drei Picker sind aus applications/RAL/QualityMarks/HearingPortal/src/Host/wwwroot/css/hearing-portal-chrome.css entfernt. Rest: die Klasse ralqm-form steht noch im Markup der Formulare (27 Razor-Dateien, gezählt am 2026-10-10 mit git grep -l über *.razor; die Zeile nannte bis dahin 24) und in ihren Vertragstests, trägt aber keinen Stil mehr; ihre Entfernung ist ein eigener mechanischer Schritt Rücknahmebedingung von UP-37 erfüllt: im Bundle von 3.6.3-alpha.0.16 tragen die Gruppen von cohesion-dropdownlist-host, cohesion-datepicker-host und cohesion-datetimepicker-host align-items: center und eine Höhe aus ihrem Komponenten-Token mit Rückfall 2.5rem, ohne Größenklasse. Live nach dem Löschen gemessen (1440 px, /anhoerungen, /anhoerungen/neu, /institutions/new): Feldhöhen 40 px mit innerer Eingabe 28 px, der Textbereich 114 px — Zahlenreihen identisch zur Messung mit der Brücke, Sicht auf die Aufnahme: Text mittig. applications/RAL/QualityMarks/HearingPortal/tests/Authentication/ProductChromeStylesheetTests.cs: Container-Test, Zentrierungs-Test und Stolperdraht sind gelöscht; The_restored_bundle_sizes_and_centres_the_three_pickers_without_a_size_class liest die drei Regeln aus dem Bundle. HearingPortalFilterBar setzt weiter --coh-input-box-height: 2.5rem auf seiner Wurzel — gleich dem neuen Rückfall, harmlos, nicht angefasst.
Tooltip-Blase invertiert zur Seite — zurückgenommen am 2026-10-01 Die Regel --coh-tooltip-bg / --coh-tooltip-color auf dem Wurzelelement ist aus applications/RAL/QualityMarks/HearingPortal/src/Host/wwwroot/css/hearing-portal-chrome.css entfernt Rücknahmebedingung von UP-38 erfüllt: cohesion-orange-dark.css und cohesion-neutral-dark.css (3.6.3-alpha.0.16, Zeilen 139 und 140) deklarieren --coh-tooltip-bg: var(--coh-surface-fg) und --coh-tooltip-color: var(--coh-surface-bg) — wörtlich die Brücke des Produkts. applications/RAL/QualityMarks/HearingPortal/tests/Authentication/ProductChromeStylesheetTests.cs: der Stolperdraht The_shipped_dark_palettes_do_not_separate_the_tooltip_bubble_from_the_page und die Struktur-Prüfung sind gelöscht; The_restored_palettes_ship_a_tooltip_bubble_that_stands_apart_from_the_page rechnet Blase gegen Seite und Karte (mindestens 3:1) und Text gegen Blase (mindestens 4,5:1) in allen vier Paletten aus dem restaurierten Paket. Im Browser nicht nachgemessen.
Modulschiene schließt ihr Panel außerhalb des Menüs — zurückgenommen am 2026-10-01 Collapsed="@_railPanelClosed" am CohesionAppShellTemplate, das Feld _railPanelClosed und CohesionNavMapper.HasActive samt Tests sind entfernt; das Shell-Layout setzt PreselectFirstModule="false" Rücknahmebedingung von UP-40 erfüllt: AppModuleNavigation.PreselectFirstModule (Vorgabe an, „Select the first module on initial routes outside the menu“) schaltet die Vorwahl ab. Gemessen (Chromium, jeweils Vollladen, 1440 px): /konto, /Impressum und /Gdpr/PersonalData — Panel verborgen, kein Modul offen, keines aktiv; /anhoerungen — ein Modul aktiv, Panel sichtbar. Damit ist auch die Lücke des Befunds geschlossen („nach einem Vollladen nicht im Browser gemessen“). Die Nebenwirkung der Brücke entfällt: wer das Panel von Hand zugeklappt hatte, bekam es beim Wechsel auf eine Menüseite wieder geöffnet. ShellRailCollapseRenderTests liest den gerenderten Schienen-DOM für beide Fälle und geht rot, wenn der Schalter fehlt (Mutation gesehen); ShellChromeTests hält die Verdrahtung fest.
Stat-Kachel der Dashboard-Kennzahlen füllt ihre Rasterzelle — zurückgenommen am 2026-10-01 Die Regel .hearing-dashboard__kpi ::deep .cohesion-stat-card-template ist aus HearingDashboardPage.razor.css entfernt; die Karten setzen Fill="true" am CohesionStatCardTemplate Rücknahmebedingung von UP-41 erfüllt: CohesionStatCardTemplate.Fill („Stretch the card to its containing grid or flex item's height“) reicht an CohesionCard.Fill durch. Gemessen (Chromium, 1440 px, /anhoerungen/dashboard): sechs Kacheln, alle 135 px hoch wie ihre Zelle, Inhalt bei allen 17 px unter der Oberkante — gleich der Messung mit der Brücke. HearingDashboardUiTests liest Fill an den sechs gerenderten Karten (ohne das Attribut rot, Mutation gesehen); HearingDashboardKpiLayoutTests.No_rule_reaches_into_the_stat_card ersetzt den Test, der die Regel an diese Zeile band.
Zeilenmenü der Grids an die Palette gehängt — zurückgenommen am 2026-10-10 Der Zone-2-Block „THE GRID'S ROW MENU“ (acht Regeln auf .e-contextmenu-container.e-grid-menu ul und dessen Einträgen) ist aus applications/RAL/QualityMarks/HearingPortal/src/Host/wwwroot/css/hearing-portal-chrome.css entfernt, mit ihm der Stolperdraht Cohesion_still_leaves_the_grid_row_menu_unthemed in applications/RAL/QualityMarks/HearingPortal/tests/Authentication/ProductChromeStylesheetTests.cs Rücknahmebedingung von UP-56 erfüllt: 3.6.3-alpha.0.17 hängt das Grid-Menü selbst an. SfGrid setzt CssClass="e-grid-menu" fest auf Zeilen- und Spaltenmenü, und Cohesions gemeinsame Menüregeln wählen jetzt auch .e-contextmenu-container.e-grid-menu (23 Treffer im restaurierten staticwebassets/css/cohesion.css); die Menüs von DataGrid, TreeGrid und MasterDetailGrid lesen damit dieselben --coh-context-menu-*- und --coh-popup-*-Token wie CohesionContextMenu, kein neues Token. Der Stolperdraht hätte genau daran rot gemeldet. Cohesion belegt die Palette in Chromium mit RemainingUpstreamTests.RowMenu_FollowsThePopupPalette (laut Bewertung vom 2026-10-10, hier nicht nachgefahren). Messung im Produkt (vier Paletten, Rechtsklick auf eine Institutionenzeile): Browsernachweis ausstehend.
Theme-Provider erst nach expliziter Wahl oder gespeichertem Wert montiert — zurückgenommen am 2026-10-10 (Entscheidung O7 der Datenschutz-Spezifikation des HearingPortals) applications/RAL/QualityMarks/HearingPortal/src/Shell/Components/Layout/HearingPortalShellLayout.razor montiert CohesionThemeProvider wieder bedingungslos, mit PersistInitialTheme="false"; Bedingung _themeChosen, Lesezugriff und Neudurchsetzung im Layout entfallen. Der Stolperdraht Cohesion_theme_provider_still_offers_no_way_to_skip_the_first_render_write in applications/RAL/QualityMarks/HearingPortal/tests/Authentication/ShellThemePersistenceTests.cs hält die Parameterliste von 3.6.3-alpha.0.16 fest und gehört mit der Brücke gelöscht Rücknahmebedingung von UP-58 erfüllt: CohesionThemeProvider.PersistInitialTheme (Vorgabe true) seit 3.6.3-alpha.0.17. Cohesion.xml: bei false wendet der erste Render den gespeicherten oder den Parameterwert an, ohne zu schreiben; erst eine spätere Änderung von Theme oder SetThemeAsync speichert. staticwebassets/js/cohesion.js: applyTheme(themeName, storageKey, availableThemes, persist) kehrt bei persist === false vor dem Schreiben zurück. Damit gilt O7 ohne Produktbrücke, und die Kosten der Brücke (erneutes Schreiben beim Montieren, ein Umlauf mit altem Theme, kein dir am body beim Erstbesuch) entfallen. Im Browser nicht gemessen, wie schon der Befund.
Vertikaler Stepper ohne eigene Höhe — zurückgenommen am 2026-10-10 Die beiden --rail-Regeln (.hearing-workflow-stepper--rail { min-height: 21rem; } und display: flow-root; min-height: inherit auf .cohesion-stepper-host) sind aus applications/RAL/QualityMarks/HearingPortal/src/UI/Blazor/Workflow/HearingWorkflowStepper.razor.css entfernt Rücknahmebedingung von UP-60 erfüllt: in 3.6.3-alpha.0.17 ist die senkrechte Navigation eine Flex-Spalte, die den Host füllt, die Schrittliste steht im Fluss (row-gap: var(--coh-stepper-vertical-gap, var(--coh-space-lg, 1.5rem)) im Bundle), die Spur läuft zwischen dem ersten und dem letzten Indikator; ohne Höhe nimmt der Stepper die Höhe seiner Schritte. Der Prüfstein verlangt die Messung im Browser (sieben Schritte auf /anhoerungen/neu): visuell gemessen am 2026-10-11 mit einer BrowserGate-Stufe auf einer versandten Anhörung, in allen vier Paletten (orange/neutral × hell/dunkel) — eigene Höhe ohne Containerhöhe, gleichmäßige Abstände, Spur von Schritt zu Schritt. Die Bildschirmfotos liegen lokal, nicht im Repository; eine automatisierte Messung an Host, Navigation und Leiste gibt es nicht.
Fußlinks der Teilnahmekarten in der Kartenfarbe — zurückgenommen am 2026-10-10 (bis dahin ohne eigene Zeile in diesem Register) Die Farbdeklarationen der Fußklasse in applications/RAL/QualityMarks/HearingPortal/src/Features/Hearings/Blazor/Portal/MyParticipationsPage.razor.css (.hearing-portal__participation-footer a.hearing-portal__action, (0,3,1) gegen die Vendor-Regel bei (0,2,1)) sind entfernt; die Fußklasse selbst trägt seit 2026-10-11 wieder die Form (nächste Zeile) Rücknahmebedingung von UP-27 erfüllt, geliefert seit 3.6.3-alpha.0.15 (Cohesion c846a9c), gelesen im restaurierten 3.6.3-alpha.0.17: [b-…] .cohesion-card.e-card .e-card-actions a setzt color: inherit bei (0,4,1), die Markenfarbe trägt nur noch Rand und die Tönung von Hover, Fokus und Aktiv (12 %). axe auf portal/meine-teilnahmen ohne die Klasse: ohne Verstoß im Volllauf cohesion017full02 (2026-10-10, 45 Stufen, Browser/axe/Tastatur/Berechtigungen PASSED).
Form der Fußaktionen der Teilnahmekarten — wieder eingesetzt am 2026-10-11 (Entscheidung person-001 nach dem Vergleich der Bildschirmfotos) applications/RAL/QualityMarks/HearingPortal/src/Features/Hearings/Blazor/Portal/MyParticipationsPage.razor.css: .hearing-portal__participation-footer a.hearing-portal__action und …--primary setzen Polsterung, Ecke, Rahmenstil und -stärke (Primäraktion 2 px) und Schriftgewicht bei (0,3,1), keine Farbe Befund: ohne die Regel zeichnet das Vendor-Blatt (.e-card .e-card-actions a, (0,2,1)) jede Fußaktion als 30-px-Chip mit 1-px-Rand; mit den Farben der Kartenregel (UP-27) unterscheiden sich Haupt- und Nebenaktion nur im Schriftgewicht. Farben setzt die Regel nicht, sie würde gegen die Kartenregel bei (0,4,1) ohnehin verlieren. SemanticColourContrastTests (The_participation_card_action_takes_the_card_foreground_from_the_shipped_card_footer_rule) verlangt: keine Farbdeklaration und kein border-Kurzwert in den Aktionsregeln, Vorrang vor der Vendor-Regel, schwererer Rand der Primäraktion (Mutationen rot gesehen: 1 px an der Primäraktion, border-color, border-Kurzwert). Zurückgenommen durch UP-63: Tokens oder eine Primär-Variante für Fußaktionen der CohesionCard.
Grid-Lesestand im Adaptor (CAFGridDataAdaptor.CaptureReadState) — zurückgenommen am 2026-10-10 (bis dahin ohne eigene Zeile in diesem Register) Basismethode und Nachladen in modules/UI/src/Blazor/Data/CAFGridDataAdaptor.cs und die 23 Überschreibungen in den Grid-Adaptoren der Anwendung sind entfernt Rücknahmebedingung von UP-57 erfüllt: CohesionDataGrid.RefreshAsync in 3.6.3-alpha.0.17 (Cohesion.xml) holt bei einem Grid mit Datenmanager eine Aktualisierung zwischen Ladeereignis und Created nach Created einmal nach; eine Aktualisierung vor dem Ladeereignis bleibt verworfen (ein Laden beim Erstaufbau), und GoToPageAsync lädt auch auf der aktuellen Seite. Prüfstein im Produkt: Directory_search_applied_while_the_first_read_is_still_running_is_not_lost und Directory_reload_requested_while_the_first_read_is_still_running_is_not_lost in applications/RAL/QualityMarks/HearingPortal/tests/Authentication/StaffAccountGridUiTests.cs grün ohne Brücke — erfüllt am 2026-10-10 (Authentication-Tests 744/744).
„WCAG AA, part two“: Sidebar-Abschnittstitel, Brotkrumen-Link und primäres Badge — nachgetragen am 2026-10-10, bis dahin ohne Zeile in diesem Register und ohne UP-Kennung applications/RAL/QualityMarks/HearingPortal/src/Host/wwwroot/css/hearing-portal-chrome.css, Block „WCAG AA, part two“: .coh-sidebar-nav__section-title und .cohesion-workspace-navbar__crumb a auf 70 % --coh-surface-fg über --coh-surface-bg, .coh-badge.coh-badge--primary mit abgedunkeltem Hintergrund Befund (Audit --audit --login, Wert aus dem Blockkommentar): 3,32:1 am Abschnittstitel, 4,40:1 am Brotkrumen-Link, 3,30:1 am primären Badge, orange-light. Der Block nennt sich selbst einen Vendor-Override, der in das Register gehört, und stand trotzdem nie hier. Stand des Pakets (im restaurierten 3.6.3-alpha.0.17 gelesen, wie von Cohesions Bewertung vom 2026-10-10, Punkt 9, für 0.16 bestätigt): der Abschnittstitel liest var(--coh-nav-muted, var(--coh-surface-muted, #5d5d5d)), der Brotkrumen-Link var(--coh-surface-muted, #5d5d5d), nicht mehr die im Kommentar dokumentierten color-mix-Werte (55 % bzw. 65 %); --coh-surface-muted prüft Cohesion in jeder Palette mit scripts/check_contrast.py auf AA. Das primäre Badge malt weiter --coh-color-primary unter --coh-color-on-primary. Zurückgenommen, wenn eine Nachmessung ohne den Block alle drei Stellen in allen vier Paletten über 4,5:1 zeigt — Nachmessung ausstehend. Bleibt eine Lücke, bekommt sie eine UP-Kennung in der Upstream-Liste.
ContractManager: Glyph für den Caret des Dropdown-Triggers (RAL-LL-CM-67; Kopie der ersten Zeile dieser Tabelle und damit ein eigener Override): content auf .cohesion-dropdownbutton .e-caret::before applications/RAL/LogoLicense/ContractManager/src/Host/wwwroot/css/contract-manager-chrome.css, Zone-2-Block unter den Kopfleisten-Steuerelementen; wirkt auf das Sprach- und das Farbmenü der Kopfleiste (ContractManagerShellLayout.razor) und das Webkategorie-Menü des Katalogs (CatalogProductsPage.razor, RAL-LL-CM-13) Befund wie in der HearingPortal-Zeile, am 11.10.2026 gegen das restaurierte 3.6.3-alpha.0.17 erneut gelesen: Keine content-Regel für .e-caret in staticwebassets/css/syncfusion.css adressiert cohesion-dropdownbutton; alle verlangen einen Vorfahren wie .e-dropdown-btn, einen Menü- oder Bildeditor-Container. Gewinnt ohne !important, weil es keine konkurrierende content-Deklaration gibt; Glyph aus Font Awesome (\f078, 900). Zurückgenommen durch denselben Upstream-Punkt wie die HearingPortal-Zeile (Caret-Glyph oder ShowCaret/CaretIconCss im PopupContent-Pfad von CohesionDropDownButton); beide Kopien gehen im selben Änderungssatz.
ContractManager: Kontrast nach WCAG AA, Teil 2 (RAL-LL-CM-67): color auf .coh-sidebar-nav__section-title und .cohesion-workspace-navbar__crumb a (70 % --coh-surface-fg auf --coh-surface-bg) sowie background-color auf .coh-badge.coh-badge--primary (--coh-color-primary-strong mit 6 % --coh-overlay-color), jeweils unter body.abp-application-layout, ohne !important applications/RAL/LogoLicense/ContractManager/src/Host/wwwroot/css/contract-manager-chrome.css, Block „ZONE 2 - WCAG AA“ Befund (übernommen aus dem HearingPortal, orange-light): Badge 3,30:1, Abschnittstitel der Seitennavigation 3,32:1, Brotkrumen-Link 4,40:1, alle unter 4,5:1. Stand im restaurierten 3.6.3-alpha.0.17 (am 11.10.2026 aus dem Paket gelesen und gegen --coh-surface-bg gerechnet, nicht im Browser gemessen): Abschnittstitel und Brotkrume malen nicht mehr die Mischung, sondern --coh-nav-muted bzw. --coh-surface-muted, mit 6,35:1 (orange-light), 6,59:1 (orange-dark), 5,81:1 (neutral-light) und 5,94:1 (neutral-dark). Für diese beiden Selektoren ist die Rücknahmebedingung damit erfüllt, und die 70-%-Mischung des Behelfs (5,10:1 in orange-light) liegt unter dem ausgelieferten Wert. Der Graustufen-Teil bleibt bewusst stehen, solange die gleichlautende HearingPortal-Regel steht, damit beide Anwendungen gleich aussehen (ADR-03 des ContractManagers: Behelfe werden so übernommen, wie sie im HearingPortal stehen, und gemeinsam zurückgenommen); nach cohesion-boundary.md ist er bis dahin in beiden Anwendungen ein bekannter Fehler. Der Badge bleibt weiß auf --coh-color-primary mit 3,30:1 (orange), 4,08:1 (neutral-light) und 2,84:1 (neutral-dark); dieser Teil bleibt nötig. Zurückgenommen: der Graustufen-Teil im selben Änderungssatz wie die HearingPortal-Regel; der Badge-Teil, sobald Cohesion .coh-badge--primary in allen vier Paletten mit mindestens 4,5:1 ausliefert.
ContractManager: Inhaltsabstand der App-Shell (RAL-LL-CM-67): padding-block: var(--coh-space-md), padding-inline: var(--coh-space-lg) und --coh-action-bar-inset-end: calc(-1 * var(--coh-space-md)) auf body.abp-application-layout .cohesion-app-shell-t__content applications/RAL/LogoLicense/ContractManager/src/Host/wwwroot/css/contract-manager-chrome.css, Block „ZONE 2 … the content gutter“ Befund (im restaurierten 3.6.3-alpha.0.17 gelesen): .cohesion-app-shell-t__content deklariert kein Padding, nur Flex, Überlauf, scrollbar-gutter und in der Modul-Variante einen Außenabstand. Ohne die Regel beginnt die Überschrift jeder Seite auf der Kante der Modul-Rail und direkt unter der Kopfleiste. Die Werte kommen aus der Abstandsskala, die angedockte Aktionsleiste (CohesionActionBar) wird über das veröffentlichte Token --coh-action-bar-inset-end wieder bündig. Keine konkurrierende Deklaration, kein !important. Zurückgenommen, sobald die App-Shell einen eigenen Inhaltsabstand oder ein Token dafür ausliefert.
ContractManager: Menüschalter der Kopfleiste im statischen Fehlerdokument ausgeblendet (RAL-LL-CM-67): .error-document ::deep .cohesion-workspace-navbar__menu { display: none; } applications/RAL/LogoLicense/ContractManager/src/Host/Components/ErrorDocument.razor.css Befund (im restaurierten 3.6.3-alpha.0.17 gelesen): Das Fehlerdokument rendert CohesionAppShellTemplate statisch, ohne Circuit. Unterhalb des Umbruchpunkts zeigt die App-Shell den Menüschalter der Kopfleiste (display: inline-flex), der dort weder eine Schublade noch einen Ereignis-Handler hat, also ein toter Schalter wäre. CohesionWorkspaceBarTemplate.ShowMenuButton existiert, CohesionAppShellTemplate reicht ihn aber nicht durch. Zurückgenommen, sobald die App-Shell den Menüschalter über einen Parameter abschalten lässt; dann setzt das Fehlerdokument diesen Parameter statt der Regel.

Die vier ContractManager-Zeilen gehören zum Grundgerüst RAL-LL-CM-67. Dessen Produkt-Chrome ist eine Kopie der HearingPortal-Fassung; jede kopierte Zone-2-Regel ist ein eigener Override mit eigener Zeile und wird mit ihrem HearingPortal-Gegenstück zurückgenommen. Die HearingPortal-Gegenstücke von Inhaltsabstand (hearing-portal-chrome.css) und ausgeblendetem Menüschalter (applications/RAL/QualityMarks/HearingPortal/src/Host/Components/ErrorDocument.razor.css) stehen bisher nicht in diesem Register.

Mit der restaurierten Cohesion-Version 3.6.3-alpha.0.2 entfallen die Filing-Overrides für Spaltenausrichtung und Sortierbutton-Polsterung, die zusätzliche Anzahl-/Seitengrößenleiste, Dialoginhalt im Footer und aria-hidden="false" an Bestätigungsdialogen. DLL und ausgelieferte Scoped-CSS-/JS-Assets enthalten die entsprechenden Korrekturen. Filing konsumiert AlwaysShowPager, PageSizeOptions, PageSizeText, ChildContent, InitialFocusSelector und PreventClose direkt. Die angepassten bUnit-Prüfungen und der ungefilterte integrierte BrowserGate sind in ral-qm-hp-19-review-gate-5 am 2026-09-11 um 14:01:52 MESZ bestanden. Der reale Filing-Nachweis umfasst Anzahl/Seitengröße samt zugänglicher Beschriftung, Dialoge/Fokus, Spaltenausrichtung, Tastatur, Mobilansicht und axe. Die oben genannten Rücknahmebedingungen für Aktionsdialog und Papierkorbtabelle bleiben bestehen.

Rückbau am 12.09.2026: drei Zeilen entfallen, gegen das wiederhergestellte 3.6.3-alpha.0.6 belegt. Alle drei waren schon vor dem Sprung auf .0.6 gegenstandslos — sie wurden mit 3.6.3-alpha.0.3 hinfällig oder, bei den <select>-Bridges, durch CAFs eigenen Designdurchgang. Aufgefallen sind sie erst bei der Abnahme von .0.6.

Eine vierte Zeile — ValidateOnInput — erfüllt ihre Rücknahmebedingung ebenfalls und bleibt trotzdem stehen. Der Grund steht in der Zeile selbst: sie ist die einzige der vier, deren Rückbau die Formularbindung der ganzen Anwendung berührt, und der Nachweis dafür ist ein Tastendruck im Browser, nicht ein grüner Unit-Test. Lieber eine dokumentierte Altlast als eine Entfernung, die niemand gemessen hat.

  • Stepper-Beschriftung. Der Block malte nichts mehr: Cohesions Regel auf .e-step-selected/.e-step-completed .e-step-text-container.e-text trägt inzwischen !important, der Produktblock bewusst keines — und ein Autoren-!important schlägt jede normale Autorendeklaration, unabhängig von der Spezifität. Am laufenden Host auf /anhoerungen/neu (orange-dark) gemessen: rgb(254, 80, 0) bei font-weight 600, also Cohesions Token und Cohesions Gewicht. Die ausgelieferten Werte halten AA in allen vier Paletten (schlechtester Fall 4,99:1, deckungsgleich mit der Messung). Der zugehörige Test prüfte nur den Produktblock und blieb deshalb grün, während er eine Farbe zusicherte, die der Browser nicht rendert; er prüft jetzt die ausgelieferte Regel.
  • Semantische Badges. Alle vier Varianten lesen seit .0.3 --coh-color-{warning,error,info,success}-fg, und jede Palette deklariert diese Rollen. Der Produkt-Mix gewann über Spezifität und ersetzte damit einen entworfenen Wert durch eine Näherung — in allen sechzehn Kombinationen die schlechtere (schlechtester ausgelieferter Wert 5,55:1 gegen 4,61:1 des Overrides).
  • Native <select>-Bridges. Die Zeile nannte 29 Stellen in 10 Dateien. Es sind null — und zwar null rohe <select>, <input>, <button> und <textarea> in src/**/*.razor insgesamt. Die Migration auf CohesionDropDownList erledigte Stufe 4/5; die Zeile war Buchhaltung ohne Gegenstand. Was die Stellung hält, ist nicht diese Zeile, sondern die leere Allow-Liste RawFormElements = [] in UiDesignContractBaseline.cs, die jeder Datei Budget 0 gibt.

Nicht in der Tabelle, aber im selben Zug zurückgebaut: der workspace__card-fill-Behelf auf dem Arbeitsbereich (CohesionCard.Fill leistet mehr — Flex-Spalte auf Host und Karte, Inhaltsbereich absorbiert den Rest, Fußzeile an die Unterkante) sowie die Zweit-Hälfte des Seitenkopf-Overrides.

Die beiden Marken-Overrides — Hex-Fallbacks für --brand und --brand-ultra-light — sind zurückgenommen und deshalb aus der Tabelle verschwunden. Host/wwwroot/global-styles.css definiert die drei Produkt-Aliase heute einmal aus Cohesion-Tokens: --brand = var(--coh-color-primary), --brand-primary = var(--coh-color-primary-strong), --brand-ultra-light als color-mix gegen --coh-surface-bg. Damit gilt die Richtung, die dieses Register für Marken-Werte fordert: Cohesion-Tokens führen, das Produkt aliasiert. Eine Näherung ist bewusst dabei — --coh-color-primary-strong ist #d54300 statt des früheren #a44300 (Begründung im Kopf der Datei). Benutzt werden die drei Aliase derzeit allerdings nirgends mehr: außerhalb von global-styles.css verweist unter src/ keine Datei auf sie. Sie stehen als Anschlusspunkt bereit, nicht als wirksame Zuweisung.

Ein zweiter Fall hat das Register nie als Zeile erreicht, weil er kein Behelf war, sondern ein bewusster Verzicht: der einzeilige Kontoblock der App-Shell. Die Vorlage zeigt unter dem Namen die Rolle; Cohesions NavBarUserMenu konnte das nicht, und ein nachgebautes Vendor-DOM verbietet Zone 3 der Cohesion-Grenze — also blieb die Zeile weg (App-Shell-Spezifikation D3.1, Upstream-Punkt 17 der App-Shell-Spezifikation). Cohesion 3.6.2-alpha.0.13 liefert CohesionNavUser.Subtitle; seit dem 2026-09-09 füllt HearingPortalShellLayout es aus den RALQM-Produktrollen des angemeldeten Benutzers. Der Punkt steht hier, damit die Gegenleistung nachvollziehbar bleibt: ein Upstream-Punkt, der geliefert wurde, und ein Produkt, das ihn am selben Tag angeschlossen hat — ohne dass je ein Override zurückzunehmen war.

Stand gegenüber Cohesion 3.6.3-alpha.0.17 (gelesen am 2026-10-10): die Tabelle oben ist der vollständige Stand. Ein Block ohne Zeile wurde an diesem Tag gefunden und nachgetragen („WCAG AA, part two“, Hinweis aus Cohesions Bewertung vom 2026-10-10, Punkt 9). Vier Overrides des zugrunde liegenden Playbooks sind in 3.6.2 bereits upstream zurückgenommen und stehen deshalb nicht hier.

Die Versionswechsel im Überblick: 3.6.3-alpha.0.13 (Cohesion-MR !22, „Upstream findings remediation“, 18.09.2026) schloss am 2026-09-19 vier Zeilen: Gruppenlabel-Mix, Kopf-Padding, ValidateOnInput und den Timeline-Schlüssel. 3.6.3-alpha.0.16 schloss am 2026-10-01 fünf Zeilen (Grid-Chrome, Picker, Tooltip-Blase, Modulschienen-Panel, Stat-Kachel) und den Pager-Behelf. 3.6.3-alpha.0.17 schloss am 2026-10-10 vier Zeilen (Token --coh-color-surface, Zeilenmenü, Theme-Provider, senkrechter Stepper) und zwei Brücken, die nie eine Zeile hatten und nur mit ihrer Rücknahme eingetragen sind (Fußlinks der Teilnahmekarten, UP-27, deren Form am 2026-10-11 als eigene Zeile zurückkam, UP-63; Grid-Lesestand im Adaptor, UP-57). Am selben Tag entfielen zwei Tokenwerte am eigenen Stepper-Wrapper (UP-59, Zone 1, deshalb nie im Register) und vier Wartezeiten im BrowserGate (UP-28; Gate-Brücken, kein Override). Den Browsernachweis dieser Rücknahmen haben inzwischen geliefert: der Volllauf cohesion017full02 (2026-10-10) für die Fußlinks (UP-27), die Volläufe cohesion017full02 und final20261011 (2026-10-11) für die Wartezeiten (UP-28), der Testlauf vom 2026-10-10 für den Grid-Lesestand (UP-57) und eine Sichtmessung in allen vier Paletten am 2026-10-11 für Stepper-Linie (UP-59) und senkrechten Stepper (UP-60). UP-27 steht seit dem 2026-10-10, die übrigen seit dem 2026-10-11 im Archiv. Aus steht er noch für den Token --coh-color-surface (UP-10), das Zeilenmenü (UP-56) und den Theme-Provider (UP-58); die Zeilen sagen es einzeln.

Offen bleiben der Caret-Glyph des Dropdown-Triggers, die Modulschiene nur mit Modulen (ohne offene Cohesion-Bedingung, siehe Zeile), die beiden Filing-Zeilen, der Produkt-Picker HearingPortalDropDownList (die Bibliothek trägt seit alpha.0.13 Splat-Caching und ShouldRender an allen drei Auswahl-Wrappern; der Abbau verlangt den Portalnachweis aus UP-15), der Avatar-Behelf, die Fokusrückgabe hinter dem Kit-Dialog (eigener Vorgang mit Gate-Stufe institutions-maintenance) und der Block „WCAG AA, part two“ (Nachmessung ausstehend) und die Form der Fußaktionen der Teilnahmekarten (UP-63).

Nicht in der Tabelle, weil es ihn nicht gibt: einen Host-seitigen Logfilter für den Circuit-Abbruch aus Syncfusions ComponentDispose (Cohesion KI-008, Vendor-Anteil von UP-16). Die Upstream-Liste nannte bis 2026-10-10 „Host-seitige Logfilterung bleibt“; git grep nach KI-008, ComponentDispose und AddFilter über applications/RAL/QualityMarks/HearingPortal/src und modules findet nichts, und Cohesion liefert keinen. KI-008 bleibt in Bibliothek und Produkt unmitigiert.

Dieses Register wird bei jedem Cohesion-Versionswechsel neu gelesen, denn genau dort nimmt ein Upstream-Fix einen Behelf zurück — und ein Behelf, der nach dem Fix bleibt, ist ab dann ein Bug.

Weiter: 03. Erweiterung durch ein Produkt

03. Erweiterung durch ein Produkt

Wie ein Produkt CAF konsumiert — beschrieben am RAL Gütezeichen Anhörungsportal, dem am weitesten ausgebauten Konsumenten. Der zweite Konsument, der LL ContractManager, nutzt bisher CAF.Modules.Authentication und CAF.Modules.UI.Blazor und folgt derselben Struktur. Andere Hosts können denselben Modulvertrag übernehmen, ohne Produktrouten oder Berechtigungen zu kopieren.

Repository und gemeinsame Prüfungen

Jedes Produkt besitzt applications/<Kunde>/<Sparte>/<App>/{src,tests,docs,etc,tools}. App-Solution, Visual-Studio-Startdatei und ABP-Metadaten liegen in dessen src. CAF-Code und -Tests liegen unter modules/<Modul>/{src,tests}; CAF-Architektur bleibt unter docs/arc42. Die Gesamt-Solution CAF.slnx enthält alle Projekte; CAF.Framework.slnx enthält nur CAF. App-Solutions enthalten alle eigenen Projekte und Tests sowie die transitiv benötigten CAF-Projekte.

Die Dienstbereiche services/e-invoicing-api/, services/keycloak/, services/zammad/ und services/alfresco/ ergänzen die Repositorystruktur. CAF-7 übernimmt die vollständige E-Invoice-API samt Tests und notwendiger Registry-/Solution-/Guard-/Gatebasis als eigenständigen zustandslosen HTTP-Dienst. Namespace ist CAF.Services.EInvoicing, Service-ID e-invoicing-api. Keycloak, Zammad und Alfresco bleiben unabhängige Definitionsvorhaben. Der API-Import erweitert den Projektgraphen, begründet jedoch keine ABP-Modulkante oder Datenbank. Kundeninstanzen bleiben beim Kunden, fachliche Verwendung bei der App. Die Dienstesicht und Dienstekarte trennen den tatsächlichen Import-/Nachweisstand von Releases und Kundenbetrieb in CAF-7.

Das Anwendungsregister verbindet diese Ownership mit Solutions, Gate-Einstiegen und Berichten. Ein neuer ausführbarer Host braucht vollständige Gate-Metadaten. Unregistrierte Projekte, fehlende Projekte und unauflösbare Referenzen lassen die Prüfplanung fehlschlagen. CAF-Änderungen prüfen CAF und ihre transitiven Consumer; App-Änderungen nur die Pflichtschritte der betroffenen App-Gates. Die Vereinigung der ausgeführten Framework-/App-/Service-Solutions muss die Gesamt-Solution abdecken; zusätzliche Root-Projekte ohne Gate-Zuordnung stoppen die Planung. architectureInputs und app-eigene gateInputs registrieren zusätzliche Dateiinhalte, die .NET-Tests lesen, einschließlich Markdown. Die Auswahl folgt deren alten und neuen Zuordnungen. Quellcode in App-Stubs verlangt ebenfalls die gemeinsamen Architekturguards. Browser-, axe-, Tastatur- und Browser-Berechtigungsprüfungen sind separat zuschaltbar und standardmäßig aus. Serverseitige Berechtigungstests bleiben Pflicht. Die Gate-Regeln bestimmen Ref-Auswahl und Nachweisbindung.

Die Projektauswertung liegt gemeinsam in tools/_msbuild.py und verwendet MSBuild einschließlich Imports und bedingter Referenzen. Basis und Tipp werden aus getrennten Quellständen bewertet. Die allgemeinen Architekturguards liegen in tests/Architecture und besitzen keine App-Projektreferenz. Der zentrale Schritt architecture prüft sie auch bei reinen CAF- Teständerungen; daraus folgt kein App-Browserstart. Produktregeln bleiben bei den Anwendungen und erweitern den gemeinsamen Graphen innerhalb ihrer eigenen Testassembly.

Berichte entstehen zuerst im App-docs/publish, danach im Kunden-docs/publish und zuletzt im Root-docs/publish. Der zentrale Publisher prüft lokale Links und Kunden-Grenzen, bevor er die erzeugten Bundles übernimmt. Ein App-Stubs-Eintrag erzeugt eine Übersicht, aber keinen erfundenen Bericht. Das Umzugsspec führt die Abnahmekriterien und den aktuellen Nachweisstand. Der Kundenmodus --customer ral erzeugt und prüft nur RAL und dessen Apps. Der vollständige Publisher bleibt der Einstieg für CAF/Pages. Die Review-Korrekturen beschreibt CAF-REPO-02.

Einbindung

Ein Baustein wird über die ABP-Modulkette eingebunden, nicht über direkte Typreferenzen:

  1. ProjectReference (bzw. PackageReference außerhalb dieses Repositorys) vom Host auf den Baustein.
  2. Die ABP-Modulklasse des Bausteins in die DependsOn-Liste des Hostmoduls aufnehmen, z. B. typeof(CAFModulesUiBlazorModule).
  3. Den typisierten Optionsbaum des Bausteins über die Konfiguration des Hosts füllen. Die Optionen validieren beim Start und brechen fail-fast ab, wenn Pflichtwerte fehlen.

Der Host ist Composition Root: Er lädt Module, verkabelt Middleware und Routing, besitzt den gemeinsamen DbContext und erzeugt Migrationen — aber keine eigene Fachlogik und keine neuen Fachentities.

Was das Produkt beitragen muss

CAF sichert bewusst nicht zu, was produktspezifisch ist. Das Produkt bringt mit:

Belang Warum beim Produkt
Rollen, Permissions, Grants Autorisierungsentscheidungen sind fachlich, nicht neutral
Realm-/Mandantennamen, Client-IDs umgebungs- und produktspezifisch
Routing, Layout, Render-Mode-Entscheid der Host entscheidet zentral
Benutzerverwaltung und Provisioning Authentication ist reiner OIDC-Client
Fachliche Bedeutung von Dokumenten Documents liefert nur den neutralen Vertrag; Sichtbarkeit, Unveränderlichkeit und Download-Autorisierung trägt das Produkt
Globale Bundles des Hosts UI.Blazor liefert Contributors, der Host besitzt das Bundle

Erweiterungspunkte

Belegt und heute genutzt:

  • Typisierte Options mit Startvalidierung — jeder Baustein exponiert einen Optionsbaum, den der Host füllt. Standardmäßig deaktivierte Pfade (z. B. Cohesion ohne Lizenzschlüssel) verhindern, dass Tests oder Hilfshosts versehentlich etwas Unlizenziertes registrieren.
  • ABP-Bundle-Contributors — der Baustein liefert benannte Contributors, der Host fügt jeden genau einmal dem tatsächlich verwendeten globalen Bundle hinzu. Doppelte Registrierung lädt Assets zweimal.
  • Opt-in-Assets — bewusst nicht im Core enthaltene Assets (Tailwind Preflight, Font Awesome, Cohesion-Themes) ergänzt der Host explizit nach dem Core-Contributor, weil sie LeptonX-/MudBlazor-Styles zurücksetzen oder überschreiben können.
  • Routen- und render-mode-freie Komponenten — der Baustein liefert Komponenten ohne Route und ohne @rendermode, damit der Host Autorisierung und Interaktivität steuert.
  • Permission-freie Ports — IDocumentContentPort prüft bewusst keine Berechtigung. Der aufrufende Use Case des Produkts muss den Objektzugriff vollständig geprüft haben, bevor er den Port aufruft. Eine ID, URL oder ein Dateiname verleiht selbst nie Zugriff.
  • Von außen implementierte Ports — braucht ein Baustein eine Auskunft, die nur das Produkt geben kann, wird sie als Port deklariert und vom Produkt implementiert, statt eine Rückabhängigkeit zu erzeugen.

Verträge ändern

Wer die zugesicherte Fläche eines Bausteins ändert, aktualisiert dessen VERTRAG.md im selben Änderungssatz. Die dort dokumentierte SemVer-Regel (brechend nur mit Major, additiv mit Minor, Korrekturen mit Patch) beschreibt die Absicht für den Fall einer späteren Paketierung — heute gibt es keine Paketversion, weil die Bausteine nicht packbar sind. FrameworkPackagingTests pinnt beides: die Nicht-Packbarkeit (keine PackageId, keine Version, kein PackageReadmeFile) und dass jede VERTRAG.md existiert, nicht leer ist und ihre zwei Pflichtabschnitte trägt.

Die Zuordnung von Testeingaben zum Push-Gate wird in beide Richtungen geprüft: Registry-Muster müssen versionierte Dateien treffen, und Markdown-Lesezugriffe der .NET-Tests müssen für deren eigenes Gate registriert sein. Die testexklusive Einbindung über Directory.Build.targets verändert keine CAF-Runtime- oder ABP-Modulgrenze. Ein Microsoft-Compiler-Analyzer sperrt direkte BCL-Dateileser außerhalb der gemeinsamen Testimplementierung. Verfahren, Pfadsemantik und Grenzen beschreibt die Testkonvention.

Offen

Der Pfad für einen Konsumenten außerhalb dieses Repositorys existiert nicht: Die Bausteine sind bewusst nicht packbar, es gibt also keinen Feed-, Versions- und Upgradeweg. Ein zweites Produkt im selben Repository konsumiert sie per ProjectReference und braucht das auch nicht. Siehe Bekannte Lücken.

Zurück: 01. Zweck und Abgrenzung · 02. Bausteine

04. Anforderungen und Entwicklungsrichtung

Stand: 13.09.2026. CAF bedeutet Core Application Framework. Dieses Kapitel hält die aktuelle Zielrichtung und die fachliche Einordnung der älteren Requirements fest. Es ist eine Anforderungsgrundlage für die Weiterentwicklung, keine Zusage, sämtliche genannten Funktionen zu bauen. Die geltenden Modulverträge bleiben in Kapitel 2 verankert.

Produktbedarf führt die Weiterentwicklung

Zuerst entsteht das RAL Gütezeichen Anhörungsportal (QualityMarks/HearingPortal), danach der LogoLicense ContractManager, zunächst für Stiftung Warentest. Aus den Anwendungen soll ein Subset gemeinsamer Funktionen nachträglich in CAF-Module überführt und zentral gepflegt werden. Diese Richtung wurde am 13.09.2026 vom Benutzer vorgegeben. Der parallele LogoLicense-Dokumentationsentwurf konkretisiert den nächsten Bedarf; er ist noch keine implementierte zweite Anwendung. EnvironmentalLabel bleibt ein weiterer App-Stub und liefert in dieser Betrachtung noch keinen belastbaren Wiederverwendungsnachweis.

Der Nutzen: Anwendungen konzentrieren sich auf ihre Fachregeln, während gemeinsam verwendete Funktionen konsistent weiterentwickelt und korrigiert werden. Es entsteht keine Verpflichtung, jede ähnliche Funktion zu vereinheitlichen. Ausgangspunkt einer Extraktion ist ein konkreter Anwendungsfall mit einer kleinen, stabil beschreibbaren gemeinsamen Schnittstelle.

Cohesion ist das vorhandene Beispiel für eigenständige Wiederverwendung: Die separat gepflegte Razor Class Library liefert generische UI-Komponenten. CAF integriert sie und ergänzt anwendungsneutrale UI-Konventionen. Produktoberflächen und Fachtexte entstehen in der Anwendung. Die Apps konsumieren gemeinsame Bausteine; „ableiten“ verlangt keine gemeinsame Basisklasse. Eine gemeinsame CAF-Implementierung bedeutet auch keine gemeinsame Kundendatenbank und keinen zentral betriebenen Dienst. CAF-Bausteine bleiben derzeit Quellcode-Bausteine im Repository; Cohesion besitzt bereits eine eigene Paketgrenze.

Gelesene Quellen und Verbindlichkeit

Ausgewertet wurden die Seite Reqs (Version 1, 12.01.2026; leerer Seitentext) und ihre 20 Unterseiten im Space OLCAF. Die Unterseiten wurden am 13.09.2026 vollständig als HTML gelesen, einschließlich der Requirement-Yogi-Kennungen in den Tabellen. Der folgende Katalog dokumentiert den gelesenen Versionsstand. Er enthält eine thematische Synthese, keinen vollständigen Einzelanforderungsexport. Der Workflow-Bereich enthält nur ein Gerüst ohne ausgefüllte Requirement-Zeilen.

Code Design Principles, Basisarchitektur und Projektverwaltung aus Confluence wurden auf Benutzerwunsch nicht einbezogen. Die Seite „Platform“ gehört zum verlinkten Requirements-Baum; ihre Anforderungen werden deshalb berücksichtigt, ihre alten Lösungsvorschläge jedoch nicht als neue Architekturentscheidung übernommen. Aktuelle Benutzervorgaben und Repositoryregeln gehen historischen Vorgaben vor.

Quelle im Requirements-Baum Version / Änderungsdatum Fachlicher Inhalt und heutige Einordnung
Platform 24 / 18.12.2025 Berechtigungen, Audit, Sprache, Konfiguration, Betrieb; Multi-Tenancy und Broker-Vorgaben bleiben zurückgestellt.
Account Module 34 / 16.12.2025 Anmeldung, Konten, Rollen, MFA und Self-Service; auf Keycloak, ABP und Produktpolicy aufteilen.
DMS Module 10 / 16.12.2025 Versionierung, Suche, Archivierung, OCR und Freigaben; deutlich breiter als CAF Documents.
Mail Module 53 / 16.12.2025 Versand, Postfachzugriff, Serienversand und Status; getrennte Fähigkeiten prüfen.
User Interface Module 4 / 16.12.2025 Wiederverwendbare, zugängliche Oberflächen; Cohesion und CAF-Integration als vorhandene Basis.
Data Storage Module 4 / 16.12.2025 Upload, Download und Speicherorte; vorhandene ABP-Datei-/BLOB-Funktionen bevorzugen.
Customer Module 7 / 16.12.2025 Firmen, Kontakte, Adressen, Dubletten und VAT-Prüfung; gemeinsame Semantik noch nachzuweisen.
Business Transactions Module 3 / 16.12.2025 Belege, Nummern, Konditionen, Buchhaltung und E-Rechnung; E-Invoice als schmalen Kandidaten betrachten.
Product Module 4 / 16.12.2025 Artikel, Leistungen, Preise und Upgrades; kein identisches Modell für Testprodukte und Gütezeichen voraussetzen.
Contracts Module 4 / 16.12.2025 Verträge, Laufzeiten, Konditionen und Folgebelege; zunächst Produktfachlichkeit.
Ticket Module 10 / 16.12.2025 Fallbearbeitung, Zuordnung, Historie und Benachrichtigung; kein gemeinsames Ticketmodell ableiten.
Workflow Module 2 / 16.12.2025 Leeres Anforderungsgerüst; keine fachlich spezifizierte Engine.
Text Template 12 / 15.12.2025 Platzhalter, Ausgabe, Vorschau, Versionen und Sprachen; aussichtsreicher Bedarf zum Abgleich.
Analytics Module 3 / 16.12.2025 Auswertungen und Dashboards; Kennzahlen und Sichtbarkeit bleiben fachlich.
AI Module 4 / 16.12.2025 Assistenz und Wissenssuche; hier noch kein bestätigter gemeinsamer Anwendungsfall.
Testing Support 5 / 17.12.2025 Isolierte Testidentitäten und automatisierte Prozessprüfung; Testwerkzeuge von Produktfunktionen trennen.
Data Transfer Module 3 / 12.12.2025 Dateiübertragung und zeitgesteuerter Austausch; Protokolladapter von fachlichem Import trennen.
Chat Module 3 / 10.12.2025 Direkte Echtzeitkommunikation; kein bestätigter Bedarf dieser beiden Anwendungen.
Documentation Module 6 / 12.12.2025 Strukturierte, versionierte Benutzer-/API-Dokumentation; vorhandene Doku-Pipeline zuerst nutzen.
Monitoring Module 3 / 10.12.2025 Verfügbarkeit, Leistung und Verlauf; Betriebswerkzeuge von Fachprozessüberwachung trennen.

Der aktuelle Produktabgleich stützt sich auf die HearingPortal-Architektur, die LogoLicense-Anforderungen und deren Quellenkatalog. Die Matrix in Kapitel 5 nennt konkrete Produktbezüge. Die dortigen LogoLicense-Story-IDs sind lokale Entwürfe, keine freigegebenen Jira-Aufträge.

Anforderungsziele für CAF

Die folgenden Ziele sind die aktuelle Synthese. Sie ersetzen keine Quell-ID und erteilen keinen Implementierungsauftrag. Für die spätere Abnahme muss jeder ausgewählte Umfang konkretisiert werden.

Ziel Erwartetes Ergebnis Grundlage / Abgrenzung
Gemeinsame Fähigkeiten einmal pflegen Anwendungen nutzen denselben kleinen Vertrag, ohne Fachmodelle anderer Produkte übernehmen zu müssen. Benutzervorgabe 13.09.2026; bestehende CAF-Verträge
Konsistente Oberflächen Gemeinsame Komponenten, Sprache und Bedienkonventionen unterstützen zugängliche Produktseiten. BR-UI-001 bis -003, FR-UI-001 bis -006, NFR-CAF-016; Cohesion ist die Komponentenbasis.
Verlässlicher Zugang Wiederverwendbare Anmeldung und Sitzungsmechanik bei produktspezifischer Kontobindung und Autorisierung. BR-ACC-001 bis -003, NFR-CAF-009; getrennte Realms bleiben vorgegeben.
Sichere Dateifunktionen Neutrale Datei-/Freigabeoperationen mit expliziter fachlicher Zugriffsprüfung durch den Aufrufer. FR-DS-001, FR-DMS-003/-009; kein pauschales DMS- oder Archivversprechen.
Nachvollziehbare Kommunikation Versand, Vorlagen und technische Fehlerbehandlung können bei gleichem Bedarf wiederverwendet werden. FR-MAIL-001/-007/-008, FR-TEMP-002 bis -006; ABP zuerst, Fachauslöser im Produkt.
Wiederverwendbare E-Rechnung Ein abgegrenzter Vertrag könnte aus freigegebenen Rechnungsdaten ein Format erzeugen und validieren. FR-BT-009, NFR-CAF-086; vom Benutzer ausdrücklich als Kandidat genannt.
Nachweisbare Qualität Ausgewählte Funktionen haben messbare Abnahmefälle, einschließlich Fehlern, Berechtigungen und Wiederholungen. NFR-CAF-034/-052/-053; Paketinstallation allein belegt keine Erfüllung.

Historische Vorgaben mit Klärungsbedarf

Quellaussage Heutige Behandlung
BR-PLAT-006 bis -008 und FR-PLAT-007 bis -010 verlangen Tenants. Multi-Tenancy bleibt deaktiviert. Mehrere RAL-Anwendungen sind kein automatischer Tenant-Bedarf.
FR-PLAT-004 und TR-PLAT-013/-016 setzen Events bzw. RabbitMQ voraus; Mail TR-002/-003 nennt Kubernetes und REST/gRPC. Fachliche Integrationsziele bleiben lesbar; daraus entstehen weder Broker noch Microservices. Synchrone Contracts und bestehende ABP-Mechanismen bleiben zulässig.
FR-PLAT-006, FR-DMS-001/-002/-005/-008 und NFR-CAF-045 verlangen Volltext, Versionen, Retention, OCR und revisionssichere Archivierung. Keine Erweiterung von CAF Documents durch diese Altquelle. Für LogoLicense ist Alfresco Community Edition als DMS festgelegt; konkrete Version, Schnittstellen und Archivgarantien sind offen.
Account-Requirements enthalten LDAP, Self-Service, MFA und zusätzliche Sitzungsregeln. Keycloak-/ABP-Fähigkeiten und konkrete Produktfreigaben prüfen; der CAF-Default bleibt erhalten. RAL-QM-HP-52 aktiviert im HearingPortal ein freigegebenes Inaktivitätsprofil (15 Minuten, acht Stunden absolut) mit weiterhin fünf Minuten Status-/Stamp-Revalidierung.
NFR-CAF-006 verlangt REST für die gesamte Fachlogik; NFR-CAF-064 verlangt Sprachwechsel ohne Reload. Keine flächendeckende neue API und kein Wechsel des Render-Modells. Abnahme je tatsächlichem Produktbedarf präzisieren.
Plattformquelle nennt pauschal Audit aller Aufrufe und unveränderliche Historie. Fachhistorie und technisches Audit unterscheiden; Ereignisse, Datenminimierung und Aufbewahrung je Anwendungsfall festlegen.
Viele NFR enthalten (x), (y) oder (z); Normen werden teils pauschal genannt. Last, Antwortzeit, RTO/RPO, Fristen und Nachweisverfahren sind offen. Keine erfundenen Zahlen und keine Compliance-Zusage aus einer Quellformulierung.
FR-BT-009 nennt XRechnung UBL/CII und ZUGFeRD; NFR-CAF-086 nennt EN 16931 und ZUGFeRD 2.x. Als Formatwunsch erhalten. Konkrete Profile, Versionen und Validatoren vor Umsetzung auswählen; hier erfolgt keine rechtliche oder aktuelle Normenprüfung.

Vorgehen und offene Präzisierungen

  1. HearingPortal am konkreten Fachbedarf weiterentwickeln; vorhandene CAF-, ABP- und Cohesion-Funktionen nutzen.
  2. Bei der Verfeinerung von LogoLicense-Stories die Kandidatenmatrix heranziehen und echte Gemeinsamkeiten sowie abweichende Regeln mit Beispielen festhalten.
  3. Nur einen stabilen gemeinsamen Anteil zur Extraktion auswählen. Zunächst reicht eine Dokumentation des Vertrags und seiner Grenzen; technische Zerlegung folgt einer eigenen Aufgabe.
  4. Bei späterer Umsetzung Vertrag, Konsumenten und erforderliche Tests gemeinsam ändern. Eine zusätzliche Paket- oder Dienstgrenze benötigt einen eigenen Anlass.

Die nächste fachliche Klärung betrifft vor allem den Rechnungsumfang (Erzeugen, Empfangen, Validieren, Übertragen), die Unterschiede der Vorlagenverwaltung und die externe DMS-Schnittstelle. Releaseumfang und Produktentscheidungen bleiben im bestehenden LogoLicense-Anforderungsdokument. CAF-weite Fragen werden hier geführt: Welcher gemeinsame Vertrag ist stabil, welche Daten besitzt er, und wer benötigt eine unabhängige Paketversion? Die Kandidatenmatrix ist die einzige ergänzende Zuordnung; ein zusätzlicher Roadmap- oder Entscheidungslog wird daraus nicht abgeleitet.

05. Mapping-Matrix der Wiederverwendungskandidaten

Stand: 13.09.2026. Arbeitsgrundlage für die spätere Verfeinerung der Produkte, ohne Codeänderung, Modulerweiterung oder Releasezusage. Zielrichtung und Confluence-Quellen stehen in Kapitel 4. Die Einordnung ist eine Ableitung aus diesen Quellen und dem aktuellen Dokumentations-/Quellstand, kein neuer Funktionsnachweis.

Leseregel und Produktbezüge

  • Basis nutzen: Es gibt bereits einen CAF-/Cohesion-Vertrag. Seine Eignung für LogoLicense muss am jeweiligen Anwendungsfall geprüft werden.
  • Abgleichen: Beide Produkte zeigen verwandten Bedarf. Der gemeinsame Anteil ist ein Kandidat, kein beschlossenes Modul.
  • Später prüfen: Konkreter Bedarf besteht bislang nur in einem Produkt oder der Vertrag ist offen.
  • Produkt / Werkzeug: Fachverantwortung beziehungsweise Entwicklungs-/Betriebswerkzeug; derzeit kein zusätzlicher CAF-Runtimebaustein.

HP bezeichnet das Gütezeichen-Anhörungsportal. LL bezeichnet den LogoLicense-Anforderungsentwurf. Die LL-US-Verweise führen in die Story-Entwürfe. Ein ähnlicher Name, derselbe Kunde oder derselbe Provider genügt nicht als gemeinsame Fachsemantik.

Für vier bereits im HearingPortal vorhandene Fähigkeiten liegen inzwischen einzelne Extraktionsentwürfe vor. Sie konkretisieren gemeinsame Implementierung, Produktadapter und gleichzeitige Entfernung der ersetzten Produktlogik. Die folgenden Einordnungen bleiben Kandidatenbewertungen; die Entwürfe sind noch nicht umgesetzt.

Mapping-Matrix

Fähigkeit / Quelle HP-Bezug LL-Bezug Gemeinsamer Anteil und Grenze Einordnung / Auslöser
Anmeldung; BR-ACC-002, NFR-CAF-009 CAF Authentication, produktseitige Kontobindung FR-LL-001 bis -006; LL-US-001 bis -003 OIDC-/Session-Mechanik nutzen. Realms, Provisionierung, Mitgliedschaften und Rollen bleiben produktspezifisch. Basis nutzen; LL-Anmeldepfad und Kontobindung konkretisieren.
UI; FR-UI-001 bis -006/-010 Cohesion und CAF UI.Blazor; Produktseiten FR-LL-088 bis -100; LL-US-009/014/015 Komponenten in Cohesion; neutrale Integrations-/Bedienkonventionen in CAF. Fachseiten und Statusbedeutung im Produkt. Basis nutzen; neue generische Komponenten bei tatsächlicher UI-Lücke in Cohesion ergänzen.
Dateien und direkte Shares; FR-DS-001, FR-DMS-003/-009 CAF Documents; Teilnahme-/Dokumentgrants im Hearing FR-LL-039 bis -048/-097; LL-US-015/020/022/023 Binärinhalt und schmale Freigabeoperationen. Geschäftszuordnung, Versionierung und Archivpflichten nicht pauschal übernehmen. Basis nutzen; für LL den passenden Anteil neben dem DMS abgrenzen.
Mailversand; FR-MAIL-001/-007/-008 HearingOutboxProcessor nutzt ABP IEmailSender; Versand- und Lifecycle-Regeln im Feature FR-LL-007/-010/-083; LL-US-017 Persistente Versandaufträge, technische Zustände und Zustellversuche. Empfängerwahl, Versandfreigabe und Fachhistorie bleiben im Produkt. Abgleichen; Draft EmailDelivery konkretisiert den vorhandenen Mehrwert über IEmailSender und die vollständige Verbraucherumstellung.
Vorlagen und Ausgabe; FR-TEMP-002 bis -006 RAL-QM-HP-26: HearingCommunicationTemplateAppService, gebundene Revisionen und geschützter TextTemplates-Inhaltsport über ABP FR-LL-011/-012; LL-US-016 Vorlage, Version, Sprache, validierter Datensatz und Ausgabe als möglicher Vertrag. Hearing-Zwecke, Bindung und LL-Vertragsinhalte nicht verallgemeinern. Abgleichen; Semantik von Vorschau, fehlenden Platzhaltern und freigegebener Version anhand beider Produkte prüfen. PDF/Word-Ausgabe ist gesonderter Umfang.
E-Invoice-API; FR-BT-009, NFR-CAF-086 Kein Rechnungsbedarf im aktuellen HP-Zuschnitt dokumentiert FR-LL-049/-050/-085; LL-US-011/012; zusätzlich Benutzervorgabe Formatabbildung und Validierung eines neutralen Rechnungsdatensatzes. Tarife, Freigabe, Nummernvergabe und Buchhaltungsstatus bleiben vorerst in LL. Später prüfen, hoher fachlicher Wert; LL-Fälle und Formatprofile konkretisieren. Zweiter Konsument noch offen.
Postfacheingang; FR-MAIL-002 bis -004/-009 Kein belegter allgemeiner Postfachvertrag FR-LL-008/-083; LL-US-018 Technischer Abruf und deduplizierbare Nachrichteneingänge denkbar. Zuordnung zu Lizenz-/Missbrauchsfällen bleibt LL. Später prüfen; Provider, Authentifizierung und Zuordnungsregeln klären. Kein Teil des reinen Versandvertrags.
Externe DMS-Anbindung; FR-DMS-001/-005, NFR-CAF-045 Documents liefert Dateifunktionen und fachliche Archivreferenzen, kein Voll-DMS FR-LL-039 bis -048/-086; NFR-LL-005/006; LL-US-020 Alfresco Community Edition ist als LL-DMS festgelegt. Gemeinsamer Ablage-/Abrufvertrag, konkrete Schnittstelle, Metadaten und Archivgarantien sind noch zu klären. Später prüfen; konkrete LL-DMS-Schnittstelle zuerst. Keine automatische Verbreiterung von CAF Documents.
Firmen, Kontakte, Adress-/VAT-Prüfung; FR-CUST-001 bis -007 Institutions besitzt Institution-/Kontaktpolicy FR-LL-016/-025 bis -027; LL-US-003/004/009 Eine neutrale Adress-/VAT-Prüfung könnte separat nutzbar sein. Institutionsbindung, Firmenvertretung und Dublettenentscheidung sind Fachregeln. Abgleichen; gemeinsame Prüfeingaben/-ergebnisse belegen. Kein zentrales Kunden-Stammdatenmodell voraussetzen.
Technische Zustandsprüfungen; BR-MONI-001/-002 Periodischer HealthCheckService, Snapshots, Zeitgrenzen und Statusendpunkte im Host FR-LL-079/-080; NFR-LL-007; LL-US-031 Standardbasierte Ausführung und Auswertung; Ressourcen und Zugangsregeln konfiguriert der Host. Keine Pflichtreferenz jedes Fachmoduls auf CAF-Monitoring. Abgleichen; Draft HealthChecks. Der aktuelle OutboxHealthCheck prüft SMTP, keinen Versandrückstau.
Störungen und technische Benachrichtigung; BR-MONI-001/-002 RAL-QM-HP-37: persistente Störungen im Hearings-Feature FR-LL-079/-080; NFR-LL-007; LL-US-031 Fehlerhistorie, Auflösung und gebündelte Meldung. Fachprozessvollständigkeit, Zuständigkeit und Retry-Freigabe bleiben beim Produkt. Abgleichen; Draft Incidents mit Datenübernahme und verbleibender Produktintegration.
Datentransfer / Import; FR-DT-001/-002/-006 Kein gemeinsamer Dateiübertragungsvertrag dokumentiert FR-LL-061/-062/-084; LL-US-005/006; XML als Haupteingang bestätigt Transportadapter kann neutral sein. XML-Mapping auf StiWa-Produkte, Veröffentlichungen und Urteile gehört LL. Später prüfen; Transport ist noch offen, XML allein belegt weder SFTP noch eine gemeinsame API.
Audit, Settings, Localization; BR-PLAT-001/-003/-004 Bestehende ABP-Funktionen und Produktadministration NFR-LL-004/005/010; LL-US-003/016 ABP-Mechanismen weiterverwenden. Ereigniskatalog, Fachhistorie und freigegebene Konfiguration gehören den Produkten. Produkt / Werkzeug; nur eine zusätzliche stabile CAF-Policy könnte ein neues Modul rechtfertigen.
Allgemeine Verwaltungsoberflächen; UI und ABP-Administration Eigene Cohesion-Seiten für Rollen/Permissions, Sprachen, Auditlogs, Einstellungen und Textvorlagen LL nutzt dieselbe technische Basis; konkrete angebotene Verwaltungsbereiche noch festzulegen Gemeinsame Bedienung und UI-Verhalten über vorhandenen ABP-Diensten. Produktrollen, Provisionierung und Fachvorlagen bleiben beim Produkt. Abgleichen; Draft Administration beschreibt optionale UI-Bereiche ohne zweiten Verwaltungsbackend.
Prozesse, Verträge, Tickets und Kataloge; FR-CNTR-001/-002, FR-TICK-001, FR-PROD-001 Anhörung, Teilnahme, Fristen, Antwort und Bescheidung FR-LL-013 bis -015/-028 bis -038/-051 bis -069; LL-US-005 bis -013/024 bis -028 Fachzustände, Freigaben, Laufzeiten und Berechtigungen unterscheiden sich. Einzelne neutrale Hilfsfähigkeiten erst nach konkretem Vergleich. Produkt / Werkzeug; kein gemeinsames Workflow-, Vertrags- oder Ticketmodell aus ähnlichen Abläufen.
Reporting, Tests und Dokumentation; BR-ANLY-001, BR-TEST-002, BR-DOC-001 Produktberichte, QualityGate/BrowserGate, Markdown-Reporting FR-LL-070 bis -082; LL-US-029 bis -032 UI-Primitives sowie Test-/Dokumentationswerkzeuge können gemeinsam genutzt werden. Kennzahlen, Testdaten und Akzeptanzfälle bleiben fachlich. Produkt / Werkzeug; kein Runtime-Modul nur zur Codeablage und kein Testmodus mit produktiven Nebenwirkungen.

Noch kein Kandidat dieser beiden Produkte: AI-Assistenz/Wissenssuche (BR-AI-001/-002), Echtzeitchat (BR-CHAT-001) und ein allgemeines Vertrags-/Produktverwaltungssystem. Die Quellen bleiben im Katalog sichtbar. Ohne bestätigten Bedarf folgen daraus keine Module oder Stories. Massenmail/Newsletter (FR-MAIL-005/-006; LL-US-019) ist ebenfalls kein automatisch enthaltenes Merkmal des Versandkandidaten.

Beispiel: schmaler E-Invoice-Vertrag

Das vom Benutzer genannte Beispiel eignet sich für einen bewusst kleinen Zuschnitt. LL besitzt den Anwendungsfall Rechnung; ein späterer CAF-Baustein könnte dessen technische Formatausgabe übernehmen. Das ist ein Vorschlag, noch keine festgelegte API:

Teil Vorgeschlagene Verantwortung
Eingabe Vom Produkt freigegebener Rechnungsstand mit Aussteller, Empfänger, Positionen, Beträgen, Steuerangaben, Währung, Datum und Belegnummer; Referenz und gewünschtes Formatprofil.
CAF-Kandidat Struktur-/Formatvalidierung, Abbildung in das ausgewählte E-Rechnungsformat, nachvollziehbare Validierungsbefunde und Ausgabe mit Angabe von Profil-/Validatorversion.
Ausgabe Erzeugtes Dokument und maschinenlesbare Befunde; Referenz auf die geprüfte Eingabe. Ein Ergebnis ist nicht automatisch versandt, gebucht oder archiviert.
LogoLicense Vertrags-/Preislogik, Steuern und Rundungsregeln als fachliche Vorgabe, Genehmigung, Belegnummern, Storno/Korrektur, Zuordnung zur Lizenz und erforderliche Berechtigungen.
Separat klären Empfang, Versandkanal, externe Addison-Übergabe, Zahlungsabgleich, Ablage und Archivierung. Eine gemeinsame Erzeugung erzwingt keinen gemeinsamen Übertragungsdienst.

Vor einem Umsetzungsauftrag werden Beispielrechnungen einschließlich fehlerhafter Daten, Korrektur-/Stornofällen und Wiederholungen gesammelt. Danach sind Profile/Versionen, Validator, Fehlervertrag und Idempotenz festzulegen. Die konkrete API-Form (In-Process-Vertrag oder Remote-API) bleibt offen; ein CAF-Modul verlangt keinen eigenen Dienst. Eine zweite Anwendung wäre ein starker Wiederverwendungsbeleg. Sie ist nach der geltenden CAF-Regel keine starre Voraussetzung, wenn schon ein getesteter Anwendungsfall einen bewusst stabilen, anwendungsneutralen Vertrag trägt.

Wann aus einem Kandidaten eine Extraktion wird

Für jeden ausgewählten Kandidaten müssen sich fünf Fragen konkret beantworten lassen:

  1. Welche realen Anwendungsfälle teilen Eingaben, Ergebnisse und Fehlerbedeutung?
  2. Was leisten vorhandenes ABP, Cohesion oder ein bestehender CAF-Vertrag bereits?
  3. Welche Fachregeln und Daten verbleiben ausdrücklich in jedem Produkt?
  4. Ist der gemeinsame Vertrag ohne Produktnamen stabil beschreibbar und testbar?
  5. Welchen nachweisbaren Wartungsnutzen bringt der Umzug gegenüber einer einfachen Lösung im Produkt?

Die konkrete Vertiefung des HearingPortal-Bestands erfolgt jetzt in den vier Drafts: Administration, HealthChecks, Incidents und EmailDelivery. Ihre vorgeschlagene Reihenfolge und die Verbindungen zwischen Störungen und Zustellung stehen im Spec-Index. Fachliche Vorlagenregeln werden weiterhin zwischen den Produkten abgeglichen. E-Invoicing wird aus LL heraus konkretisiert; beim HP wird dafür kein Bedarf erfunden. DMS benötigt den konkreten externen Schnittstellenvertrag. Die Reihenfolge ist eine Empfehlung für die Verfeinerung, keine Änderung der Releaseplanung.

Bei einer späteren Extraktion werden VERTRAG.md, Modulgrenzen, Produktkonsumenten, Architektur und erforderliche Tests im selben Änderungssatz angepasst. Dazu gehört ausdrücklich die Entfernung der ersetzten Produktimplementierung; bloßes Kopieren in CAF gilt nicht als Extraktion. Die gemeinsamen Extraktionsbedingungen machen diesen Wechsel überprüfbar. Bis dahin bleiben Matrix und Specs ein Entwurf; die vorhandene Laufzeitstruktur wird durch sie nicht verändert.

06. Dienste und Kundenbetrieb

Repository und Framework

Das CAF-Monorepo umfasst CAF-Framework-Bausteine und Kundenanwendungen. services/ ergänzt die Struktur um eigenständige technische Dienstverantwortungen. CAF als Framework bleibt der anwendungsneutrale Code unter modules/. Die Strukturentscheidung steht im Konventionsregister G-10.

Die angenommene Strategie CAF-23 legt unabhängige Versionen für Anwendungen und Dienste sowie eine gemeinsame Frameworkversion für die bestehenden Quellmodule fest. App-eigene Module und Application Services folgen ihrer Anwendung; RAL-Auth erhält ein gemeinsames Theme-/ Konfigurationsbundle. MM verantwortet Release- und getrennte Rolloutfreigaben. G-12 führt die angenommenen Startversionen und die Trennung von Produktversion, automatischer Buildnummer und Artefaktidentität. Die Implementierung ergänzt Versionsquellen, ownerbezogene MSBuild-Metadaten und das RAL-Auth-ZIP. Die vollständige Abnahme samt Releaseablage-/Berechtigungsnachweisen führt CAF-23. Als vollständige Dauerablage ist Hetzner S3 in Falkenstein beschlossen: private Buckets caf-release-archive und caf-release-acceptance, COMPLIANCE zehn Kalenderjahre mit jährlicher Verlängerung im Archiv und ein Tag für Abnahmedaten. Version-ID, Hash und Größe binden alle Releasebytes einschließlich OCI-Layern, Quellständen und Nachweisen. GitLab bleibt CI-/Imageverteilung und atomare Versionsreservierung; dessen löschbarer Paketindex ist nicht mehr die Dauerablage. Der Releaseweg prüft zusätzlich archivierte Historie, Fristen, Schutzregeln, CI-Herkunft und MM-Identität. Reale Release-/Restore-/Consumerabnahmen und aktiver Fristbetrieb sind in der Spec belegt; die Quellmodulgrenze bleibt erhalten.

Aktuelle Bausteinsicht

flowchart TB
    R["CAF-Monorepo"] --> M["modules/\nCAF-Framework"]
    R --> S["services/\nE-Invoice-Import und unabhängige Dienstdefinitionen"]
    S --> E["e-invoicing-api/"]
    S --> K["keycloak/"]
    S --> Z["zammad/"]
    S --> A["alfresco/"]
    R --> P["applications/\nKundenanwendungen"]
    P --> C["RAL/etc/\nkonkreter Kundenbetrieb"]
    R --> D["docs/services/\nkanonische Dienstekarte"]

CAF-6 lieferte diese vier Dokumentationsgerüste. Der vollständige E-Invoice-Import einschließlich Tests und Service-Gatebasis ist seit 20.10.2026 als konkreter CAF-7-Schnitt beauftragt und lokal begonnen; sein ausgeführter Nachweisstand steht in der Spec. Vorhandene Keycloak-Dateien bleiben bei RAL und den App-Lifecycles. Zammad besitzt mit CAF-25 eine lokale Compose-Bereitstellung; deren Serverabnahme bleibt offen. Alfresco bleibt ein eigenes Definitionsvorhaben.

Zuständigkeiten und Schnittstellen

Verantwortung Eigentümer
In-Process-Mechanismus mit stabilem wiederverwendbarem Vertrag CAF-Modul
Verhalten eines eigenständig betriebenen Dienstes Dienst
Konkrete Instanz, Endpunkte und kundenweite Konfiguration Kunde
Realm-Anforderungen einer Sparte und Client einer Anwendung Sparte bzw. Anwendung, mit kundenverantworteter Provisionierung
Fachregeln, Rollen, Objektgrants und Verwendung der Integration Anwendung

Die Dienstekarte führt den aktuellen Stand pro Dienst. Ihre Service-READMEs und services/AGENTS.md sind die Einstiegspunkte im Quellbaum. Die bestehende Produkt- und Betriebsarchitektur bleibt maßgeblich für ausführbare Pfade. Eigenentwickelte Dienste beschreiben ihre Details in einer eigenen arc42-Karte, für E-Invoice unter Service-arc42. Eigene Specs und der künftige Nummernkreis EINV folgen dem gemeinsamen Prozess. Bestehende CAF-Querschnittsvorgänge bleiben an ihrem bisherigen Ort. Die interne Reportingnavigation ergänzt einen kundenneutralen Servicebereich, ohne öffentliche Kundenberichte zu erweitern; Entscheidung in G-10, Nachweise in CAF-21.

Einführung ausführbarer Dienste

Ein ausführbarer Dienst benötigt vor seiner Übernahme eine explizite Ownership, vollständige Solution-/Guard-/Gate-Zuordnung, Schnittstellen- und Kompatibilitätsnachweise sowie einen eigenen Releaseweg. CAF.slnx muss weiterhin alle eigenen .NET-Projekte erfassen. HTTP-Vertragsabhängigkeiten erfordern eine zusätzliche, belegte Auswahl neben MSBuild-Projektkanten.

Reine Compose-Betriebsdefinitionen registrieren runtime: compose, Manifest, Definitionsversion, Gate-Einstieg und CI-Job. Sie besitzen keine .NET-Projekte oder leeren Solutions. Der Planer wählt ihre realen Providerproben; fehlende, leere, übersprungene oder falsch gebundene Ergebnisse blockieren lokale und Server-Gates.

Die notwendige Register-/Solution-/Guard-/Gatebasis gehört zum begrenzten Import in CAF-7. Eigenständige Betriebssystem-Releases und Kundenbereitstellung besitzen eigene Vorgänge. Ein Quellsnapshot oder ein grüner Build bestätigt keine Zielsystem-, Konformitäts- oder Produktionsabnahme.

E-Invoice als eigenständiger Dienst

Die bestätigte Ausgangsentscheidung vom 20.10.2026 steht in G-10: services/e-invoicing-api/ besitzt die vollständige eigene HTTP-API, ihre Tests und den Releasevertrag. Service-ID ist e-invoicing-api, der .NET-Namespace CAF.Services.EInvoicing. Die gemeinsame Quellrevision erzwingt kein gemeinsames Deployment mit einer CAF-Anwendung. Interne Typumbenennungen dürfen HTTP-Routen, JSON-Nachrichten, API-Key- und Fehlervertrag nicht unbemerkt ändern.

Die API bleibt für den Import zustandslos und benötigt weder ABP noch Datenbank, Keycloak oder ContractManager. HTTP-Consumer und später der ContractManager liefern PDF und Rechnungsdaten derselben freigegebenen Fassung. Nummern, Fachstatus, SQL-Lesen, Persistenz und Versand bleiben bei ihnen. Der Dienst erhält keinen Zugang zur Legacy-SQL-Datenbank. CAF-Module sind kein erforderlicher Zwischenschritt.

flowchart LR
    REPO["CAF-Monorepo: eigener E-Invoice-Dienst"] --> REL["Eigene versionierte Artefakte\nWindows / Linux, SHA und Vertragsversion"]
    LEG["HTTP-Consumer\nPDF/JSON derselben Fassung"] -->|"HTTPS + API-Key"| API["E-Invoice-API\nzustandslos, ohne Datenbank"]
    REL --> API
    API --> PDF["PDF-Verarbeitung + XML-Einbettung"]
    API --> VAL["Gebundene XSD-/Schematron-Regeln\nMustang/Java bei vertiefter Prüfung"]
    PDF --> OUT["Dokument und prüfbare Befunde"]
    VAL --> OUT
    OUT --> LEG
    CM["Später: ContractManager\neigene Fach-/Persistenzhoheit"] -. "gleicher HTTP-Vertrag" .-> API

Die bestehende Schematron-Strecke ist kein vollständiger Peppol-Nachweis; ein Anhang allein belegt kein konformes hybrides PDF. Die reale Konformitätsregression ist CAF-12, die Validatorhärtung CAF-9. API- und Validatorversionen werden für eigene Releases gebunden und gemeinsam dokumentiert; Java wird nicht automatisch durch ein .NET-Publish mitgeliefert. Separate Windows-/Linux-Artefakte werden in CAF-10 und CAF-11 auf sauberen Zielsystemen abgenommen.

Windows-Testumgebung, lesendes Kundeninventar und IIS-Servicebetrieb mit Rückweg sind CAF-13, CAF-15 und CAF-17. Die VB.NET-Anbindung und deren Schattenvergleich übernimmt der Benutzer extern; CAF-14 und CAF-16 gehören nicht mehr zum aktiven Plan. Windows Server/IIS ist das priorisierte eigenständige Betriebsziel. Der HTTP-Vertrag setzt keine konkrete Clientimplementierung oder gemeinsame App-Auslieferung voraus. Die passive Kundeninstallation bleibt bis zu ihrem konkreten Betriebsauftrag erhalten. Der tatsächlich installierte Commit ist zu belegen, nicht aus einer vermuteten Commitdifferenz abzuleiten. Die ersten Planungspakete bleiben CAF-Querschnitt; ein neuer Dienstscope ist für den Import nicht erforderlich. Die ContractManager-Fachintegration bleibt RAL-LL-CM-29/-30 und wird nicht durch den Legacybetrieb ersetzt.

Zammad-Betrieb und App-Adapter

PO-Entscheidung vom 24.10.2026: Zammad wird als Standardprodukt unabhängig betrieben. CAF-19 schärft allgemeine Dienstdefinition und Betriebsvertrag; konkrete Instanzen bleiben im Kundenbetrieb. Der erste Adapter läuft im LogoLicense ContractManager, dessen bestehende Datenbank auch Referenzen, ausstehende Aufträge und Rückmeldungen hält. Ein zusätzlicher Middleware-Service oder eine zusätzliche Middleware-Datenbank gehören nicht zu diesem Schnitt.

UZ (EnvironmentalLabel) kann später denselben technischen Adapter gegen eine andere Instanz verwenden. App- und Instanzbindung gelten für Konfiguration, Credentials, Providerkennungen, Aufträge und Rückmeldungen. Gemeinsamer Code bedeutet keine gemeinsame Instanz oder Datenbank. Eine Extraktion erfolgt erst mit einem konkreten zweiten Consumer und seiner Umstellung; kein Zugriff auf die Runtime oder Tabellen einer anderen App. Vertrag und Entscheidung stehen in CM55 und ADR-06. CAF-19 konkretisiert die erste Produkt-/Plattformbindung im Betriebsvertrag. Entwicklung erfolgt auf Windows mit Linux-Containern, Staging auf Linux; Linux-Produktion ist vorgesehen, die konkrete Topologie bleibt offen. CAF-25 liefert jetzt getrennte lokale Instanzen mit gepinnten Images, geschützter Konfiguration und lesender Readiness. Der LL-Wrapper ruft den Dienst explizit auf; der App-Start tut dies nicht. CI nutzt den vorhandenen Linux-Runnerpool, dessen Dockerfähigkeit noch nachzuweisen ist. Providervertrag, Adapter und Betriebsabnahme bleiben CM73/CM74/CM76 zugeordnet.

CAF-Modularisierung

Eine gemeinsame Repositoryablage entscheidet keine CAF-Extraktion. Erst ein konkret benötigter anwendungsneutraler Vertrag rechtfertigt einen gemeinsamen Baustein. Bei einer Extraktion werden Implementierung und erster Consumer gemeinsam umgestellt; die ersetzte Produktimplementierung wird entfernt. Die bestehende Entscheidungsregel und die Kandidatenmatrix gelten weiter.

Zammad-Folgeplanung vom 25.10.2026

Die Dienstdefinition CAF-19 wird durch CAF-25 (Bereitstellung), CAF-26 (instanzbezogene Updates) und CAF-27 (Recovery über Systemgrenzen) umgesetzt. Die Aufgaben bleiben im CAF-Nummernkreis. CAF-25 ist beauftragt und liefert unter services/zammad die gepinnte lokale Compose-Bereitstellung mit Lifecycle und Gate. Lokales Gesamtgate und Linux-/WSL-Probe sind bestanden; die verpflichtende Linux-CI-Abnahme steht aus. CAF-26/27 bleiben Entwürfe.

Die app-eigene Basis liegt in CM72 bis CM75, ihre spätere LL-Betriebsfreigabe in CM76. Ein Versionsmanifest bindet Zammad, Compose, Begleitimages, Adapter und Konfigurations-/Job-Payloadschema. LL und später UZ wählen und aktualisieren ihre Instanzen unabhängig. Eine gemeinsame Skriptversion bedeutet keinen gemeinsamen Rollout. App-Start, Betriebsinstallation und Update bleiben getrennt.

Ungewisse externe Wirkungen erfordern belegte Korrelation oder gesperrte Klärung. Restoreproben müssen auch auseinanderlaufende App-/Zammad-Stände behandeln; keine blinde Wiederholung von Artikeln/Mails und kein pauschaler RALLL-Restore. Testkopien bleiben vor dem ersten Start quarantänisiert. Details und Abhängigkeiten stehen in der LL-Verteilungssicht. Die lokale CAF-25-Bereitstellung liefert noch keinen App-Adapter und keine Kundenbetriebsfreigabe. Maßgeblich bleibt die Nachweismatrix der jeweiligen Spec.