Merge PR #311: QA-05 (Archive): Abnahme- & Compliance-Pruefung Archive
CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (push) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (push) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (push) Canceled after 0s
CI / Connect Security-Test-Gate (QA-01 AC4, Merge-Gate) (push) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (push) Canceled after 0s
CI / Web (dms-browser) (push) Canceled after 0s
CI / Web (pdf-viewer) (push) Canceled after 0s
CI / Web (shl) (push) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (push) Canceled after 0s

This commit is contained in:
patrick committed 2026-10-19 02:18:41 +02:00
commit dfc2f2fd97
1 file changed
+150
+150
View File
@@ -0,0 +1,150 @@
# QA-05 – Gesamtabnahme- & Compliance-Prüfung Archive
Stand: 2026-10-16. Testhost 192.168.1.204 (frischer Klon, `feature/qa-05-abnahme-und-compliance-prüfung-archive`,
abgezweigt von `main`). QA-05 führt keine eigenen fachlichen Prüfungen durch, sondern konsolidiert
die drei geforderten Einzelgates (QA-02, QA-03, QA-04) sowie ergänzend QA-06/QA-07 zu einer
Gesamtfreigabeentscheidung. Keine Änderung an Produktivcode oder an den Einzelprotokollen.
## Quellenlage
`main` enthielt zum Start dieses Tickets nur `QA-04-ABNAHMEPROTOKOLL.md` und
`QA-06-PRUEFPROTOKOLL.md` in `archive/docs/`. `QA-02-PRUEFPROTOKOLL.md`, `QA-03-PRUEFPROTOKOLL.md`
und `QA-07-PRUEFPROTOKOLL.md` lagen noch nicht in `main`, sondern nur auf den offenen
Feature-Branches. Diese wurden per `git fetch` gelesen, ohne zu mergen:
- `origin/feature/qa-02-prüfgate-retention-und-worm:archive/docs/QA-02-PRUEFPROTOKOLL.md`
- `origin/feature/qa-03-prüfgate-compliance-und-ediscovery:archive/docs/QA-03-PRUEFPROTOKOLL.md`
- `origin/feature/qa-07-last-leistungstest:archive/docs/QA-07-PRUEFPROTOKOLL.md`
`archive/docs/QA-04-ABNAHMEPROTOKOLL.md`, `archive/docs/QA-06-PRUEFPROTOKOLL.md` und
`archive/docs/RET-11-PRUEFPROTOKOLL.md` wurden direkt aus `main` gelesen.
## 1. Zusammenfassung der drei fachlichen Prüfgates (Akzeptanzkriterium 1/2)
| Gate | Gegenstand | Einzelergebnis laut eigenem Protokoll | Bewertung für QA-05 |
|---|---|---|---|
| **QA-02** | Retention & WORM (RET-03 Legal Hold, RET-04 WORM-Speicher) | Prüfung 1 (Legal Hold gegen Referenzdatensatz): **bestanden**, 7/7 PASS. Prüfung 2 (WORM-Überschreibschutz): **teilweise bestanden** – Anwendungs-/Dateisystem-Schreibschutz (chmod 0400, `ErrAlreadyExists`, `sudo -u nexarch`-Schreibversuch → Permission denied) real nachgewiesen; die zusätzliche Storage-Object-Lock-Ebene (`chattr +i`) auf Host 204 strukturell nicht prüfbar (7 Tests SKIP). Gesamtergebnis des eigenen Protokolls: "Teilweise bestanden". | **bestanden** im Sinne von Akzeptanzkriterium 1 – die für RET-03/RET-04 geforderte Kernfunktion ist nachgewiesen, der offene Rest ist exakt der unten konsolidierte WORM-Storage-Lock-Punkt, kein zusätzlicher Fund |
| **QA-03** | Compliance & eDiscovery (CMP-03 Export, CMP-06 Vier-Augen-Freigabe) | Beide Pflichtprüfungen **bestanden**: Export-Prüfsummen bei zwei unabhängigen Läufen gegen den Referenzdatensatz identisch; Vier-Augen-Freigabe mit zwei benannten, unabhängigen Testrollen sowohl im Erfolgsfall als auch beim (abgelehnten) Alleingang real verifiziert. Keine Regression in den bestehenden CMP-03/CMP-06-Pflichttests. | **bestanden** |
| **QA-04** | Backup & Restore (BAK-04 bis BAK-07) | Beide Nachhol-Prüfungen (realer Restore-Lauf DB+Objekt, anschließende Reconciliation) **bestanden**, Ergebnis leer/sauber. 5 Restrisiken benannt, keines blockiert laut eigenem Protokoll die Freigabe. Bereits mit Gegenzeichnung "Betreiber" versehen. | **bestanden** |
**Ergebnis Akzeptanzkriterium 1:** Alle drei fachlichen Prüfgates sind bestanden. QA-02 trägt dabei
einen explizit benannten, nicht neu durch QA-05 eingeführten Restpunkt (Storage-Object-Lock), der
unten konsolidiert wird.
## 2. Ergänzend konsolidiert (nicht Teil der drei Pflichtgates, aber laut Ausgangslage dieses Tickets relevant)
| Gate | Ergebnis |
|---|---|
| **QA-06** (Schnittstellen-Vertragstests) | **Bestanden**, bereits vorher in `main` gemergt. Contract-Tests (RET-05-Payloads) grün, Breaking-Change-Erkennung nachgewiesen, CI-Lauf real durchgeführt (Gitea-Actions-Run #30, Status success). |
| **QA-07** (Last- & Leistungstest) | AC1 (Legal-Hold-Abfrage unter Last: p95 = 30,3 ms ≤ 50 ms, Durchsatz 6564,5/s ≥ 3000/s, 0 Fehler über 6000 Anfragen) **bestanden**. AC3 (RET-05-Registrierung, 240 parallele Aufrufe, 0 Fehler, keine Race-Duplikate/-Verluste) **bestanden**. AC2 (WORM-Schreibpfad unter Last) **offen auf Host 204** aus demselben chattr-Grund wie QA-02/RET-11 – Race-Freiheit der Schlüssel-Kollisionslogik zusätzlich per Code-Analyse (POSIX-Atomarität von `O_EXCL`) verifiziert, kein fabriziertes PASS. |
## 3. Konsolidierte Restrisiken (Prüfung vor der Abnahme 2)
### 3.1 Zentrales Restrisiko: Storage-Object-Lock (`chattr +i`) auf keinem bisher geprüften Host nachweisbar
Dreifach unabhängig bestätigt:
1. `RET-11-PRUEFPROTOKOLL.md` (Host 131, unprivilegiertes LXC auf ZFS-Root): `chattr +i` scheitert
mit `EPERM`, obwohl `cap_linux_immutable` im Namespace-Bounding-Set erscheint – die reale
Kernel-Prüfung greift gegen die gemappte UID, nicht gegen echte Capabilities.
2. `QA-02-PRUEFPROTOKOLL.md` (Host 204): identischer Befund, 7 Tests SKIP.
3. `QA-07-PRUEFPROTOKOLL.md` (Host 204, unter Last): identischer Befund, 2 Lasttests SKIP.
Zur Verifikation im Rahmen dieser Abnahme wurde der Befund auf Host 204 am frischen
QA-05-Arbeitsverzeichnis ein viertes Mal real reproduziert (eigener, unabhängiger Probe-Lauf,
nicht aus den obigen Protokollen übernommen):
```
$ df -T /
rpool/data/subvol-1204-disk-0 zfs ... /
$ chattr +i probe.txt
chattr: Operation not permitted while setting flags on probe.txt
Exit-Code: 1
```
**Bewertung der Tragweite:** `wormstore.Store.Put` (archive/internal/wormstore/wormstore.go)
ruft `lockImmutable` unbedingt auf und entfernt bei Fehlschlag die bereits geschriebene Datei
wieder – fail-closed, kein WORM-Objekt ohne tatsächliche Storage-Sperre. Das verhindert eine
falsche Compliance-Zusage, bedeutet aber auch: auf einem Host, auf dem `chattr +i` nicht wirkt,
schlägt **jeder einzelne** `Put`-Aufruf fehl – keine Archivierung, nicht nur ein Audit-Gap.
`RET-11-PRUEFPROTOKOLL.md` (Prüfung 3, bestanden) dokumentiert bereits die Betriebsvoraussetzung:
das WORM-Basisverzeichnis muss auf einem chattr-fähigen Dateisystem (ext2/3/4, XFS, Btrfs) liegen,
ausdrücklich NICHT auf ZFS, und der Prozess braucht reale (nicht nur Namespace-gemappte)
`CAP_LINUX_IMMUTABLE`-Rechte. `STORAGE-KONZEPT.md` Abschnitt 2 führt für die Produktions-Zielstufe
"Stufe 1 (Einzel-LXC)" jedoch "lokales Dateisystem ODER ZFS" als gleichwertige Optionen – ohne
Verweis auf die engere WORM-spezifische Einschränkung aus RET-11. Beide bisher geprüften Hosts
(131 und 204) sind exakt die Kombination (unprivilegiertes LXC auf ZFS), die laut RET-11 nicht
funktioniert. Der erfolgreiche Pfad (echtes `chattr +i` auf einem konformen Host) wurde in diesem
Projekt bislang **auf keinem einzigen Host real nachgewiesen** – es existiert bisher nur die
Code-Analyse, dass es auf einem konformen Host funktionieren würde.
### 3.2 Weitere, nicht blockierende Restrisiken aus den Einzelgates
- **QA-02:** RET-06/RET-07 (Fristen-Konfiguration, Fristablauf-Benachrichtigung) wurden bewusst
nicht erneut geprüft (außerhalb des QA-02-Scopes); `golangci-lint` auf Host 204 nicht verfügbar
(Projektregel: keine Toolchain-Installation), `go build`/`go vet` liefen ersatzweise clean.
- **QA-03:** Der eDiscovery-Modul-Adapter wurde nur gegen fiktive Testmodule geprüft, nicht gegen
echte laufende DMS-/Mail-Instanzen; die Rollenberechtigung der Vier-Augen-Bestätigung selbst wird
nicht in diesem Paket geprüft (liegt, falls vorhanden, in einer höheren API-Schicht).
QA-03s eigenes Protokoll verweist diese Ende-zu-Ende-Prüfung ausdrücklich an QA-05 – der
vorliegende QA-05-Tickettext begrenzt den Auftrag hier aber bewusst auf Konsolidierung der drei
Gate-Ergebnisse, ohne eigene neue Prüfungen. Diese Diskrepanz wird hier offen benannt statt
stillschweigend übergangen: eine echte Ende-zu-Ende-eDiscovery-Prüfung gegen laufende
DMS-/Mail-Instanzen steht weiterhin aus und sollte als eigenes Folgeticket eingeplant werden.
- **QA-04:** fünf im Einzelprotokoll benannte Restrisiken (fehlende Rotations-Kohärenz zwischen
DB- und Objekt-Backup, manuelle BAK-04-Rollenvergabe je Mandant, BAK-08 deckt keine
Storage-Provider-Lücke bei externem, nicht-kompatiblem Storage, Core-FDN-03/FDN-09-Wiring-Lücke,
leerer Reconciliation-Testbestand) – laut Einzelprotokoll blockiert keines davon die Freigabe,
bereits mit Gegenzeichnung "Betreiber" bestätigt.
## 4. Freigabeentscheidung (Prüfung vor der Abnahme 3)
**Bedingte Freigabe des Archive-Boards, mit namentlich benanntem Restrisiko und Empfehlung für ein
Folgeticket.**
Begründung:
1. Alle drei geforderten fachlichen Prüfgates (QA-02, QA-03, QA-04) sind real, mit Messprotokoll
und ohne fabrizierte Ergebnisse bestanden. QA-06 und QA-07 bestätigen dies zusätzlich für
Schnittstellenverträge und Last.
2. Das verbleibende Risiko (Storage-Object-Lock/`chattr +i`) ist ein **Fail-Closed**-Verhalten:
`wormstore.Store.Put` gibt niemals eine WORM-Garantie vor, die storage-seitig nicht tatsächlich
besteht – der worst case ist eine verweigerte Schreibung (Verfügbarkeits-/Betriebsproblem),
niemals eine stillschweigend verletzte Unveränderlichkeits- oder Löschsperre
(Integritäts-/Compliance-Problem). Das ist exakt das in der Produkt-DNA geforderte Verhalten
("keine Freigabe auf Zuruf", hier technisch erzwungen statt nur organisatorisch versprochen) und
entspricht dem Verhalten von S3 Object Lock Compliance-Mode, an dem sich RET-11 orientiert.
3. Das Risiko ist kein neuer oder versteckter Befund, sondern seit RET-11 bekannt, in zwei weiteren,
unabhängigen Prüfläufen (QA-02, QA-07) sowie einer vierten Probe im Rahmen dieser Abnahme erneut
bestätigt, und in `RET-11-PRUEFPROTOKOLL.md` Prüfung 3 bereits als Betriebsvoraussetzung
dokumentiert.
4. Eine Freigabe ohne jede Einschränkung wäre dennoch nicht gerechtfertigt: der erfolgreiche Pfad
(ein Host, auf dem `chattr +i` tatsächlich greift) wurde in diesem Projekt bislang **auf keinem
einzigen Host real bestätigt** – nur per Code-Analyse. Zusätzlich widerspricht
`STORAGE-KONZEPT.md` Abschnitt 2 (ZFS als gleichwertige Stufe-1-Backend-Option) ohne Verweis auf
die RET-11-Einschränkung faktisch der dokumentierten WORM-Betriebsvoraussetzung – ein Ops-Team
könnte Stufe 1 unwissentlich auf ZFS provisionieren und würde dort erst im Betrieb feststellen,
dass jede WORM-geschützte Archivierung fehlschlägt.
**Bedingungen der Freigabe:**
- Folgeticket: realer End-to-End-Nachweis von `wormstore.Store.Put`/`Release`/`Destroy` auf
mindestens einem Host mit echtem (nicht Namespace-gemapptem) `CAP_LINUX_IMMUTABLE` auf einem
chattr-fähigen Dateisystem (ext4/xfs/btrfs, privilegierter Container oder VM), bevor WORM in
einer produktiven Stufe-1-Umgebung als abgenommen gilt.
- `STORAGE-KONZEPT.md` Abschnitt 2 um einen expliziten Verweis/Ausnahmevermerk ergänzen: das
WORM-Basisverzeichnis ist von der generischen "lokales Dateisystem oder ZFS"-Option
ausgenommen und benötigt zwingend ein chattr-fähiges Dateisystem mit realen
`CAP_LINUX_IMMUTABLE`-Rechten (vor erster produktiver Stufe-1-Inbetriebnahme).
- Offene, nicht blockierende Folgepunkte aus Abschnitt 3.2 (insbesondere die noch ausstehende
echte Ende-zu-Ende-eDiscovery-Prüfung gegen laufende DMS-/Mail-Instanzen, von QA-03 an QA-05
verwiesen, hier aber nicht in dessen Scope) als eigenes Ticket einplanen.
## 5. Unterschriften
- **Umsetzung:** Claude (Agent), 2026-10-16 — Konsolidierung durchgeführt, Quelldokumente geprüft,
chattr-Befund auf Host 204 eigenständig reproduziert, Protokoll erstellt.
- **Gegenzeichnung:** aussteht (wie bei früheren QA-Gates wird das Gegenlesen im Pull Request
nachgetragen, sobald eine zweite Person verfügbar ist; blockiert nicht das technische
Inkrafttreten dieses Protokolls).