p96 follow up
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
# RetrieX Patch p95 - Admin Role Matrix Hardening
|
||||
|
||||
## Ziel
|
||||
|
||||
Dieser Patch gleicht die im Admin sichtbare Rollenlogik mit der serverseitigen Zugriffskontrolle ab. Rollen sollen nicht nur in der Userverwaltung auswählbar sein, sondern an den relevanten Routen, Controllern und UI-Aktionen konsistent wirksam werden.
|
||||
|
||||
## Ausgangslage
|
||||
|
||||
Nach p93/p94 waren Userverwaltung, Aktiv/Inaktiv-Login-Blocker und Access-Denied-Seiten funktionsfähig. Bei der Rollenprüfung fielen aber mehrere Inkonsistenzen auf:
|
||||
|
||||
- `ROLE_EDITOR` existierte in der Hierarchie, wurde aber kaum als fachliche Serverberechtigung genutzt.
|
||||
- Einige Aktionen waren im UI nur für Super-Admins sichtbar, serverseitig aber nur durch den allgemeinen `/admin`-Zugriff geschützt.
|
||||
- Indexierungsprofile konnten serverseitig nicht streng genug zwischen Ansicht und kritischen Aktionen unterscheiden.
|
||||
- `admin_ingest_profile_remove` erlaubte noch `GET` als Methode.
|
||||
- Sidebar und Dashboard zeigten Links bzw. Aktionen, die für die jeweilige Rolle später nur in 403 endeten.
|
||||
|
||||
## Umgesetzte Zielmatrix
|
||||
|
||||
| Bereich | Effektive Rolle |
|
||||
| --- | --- |
|
||||
| Chat, Ask/SSE, History, Frontend-Messages | `ROLE_CHAT_USER` |
|
||||
| Admin-Dashboard, Guides, allgemeine Adminbasis, Ingest-Job-Ansicht | `ROLE_ADMIN_AREA` |
|
||||
| Dokumente, Dokumentversionen, Tags, Tag-Zuweisungen, Dokument-Ingest | `ROLE_EDITOR` |
|
||||
| Modell-/Retrieval-Konfiguration lesen/testen, Ingest-Profile ansehen | `ROLE_KNOWLEDGE_ADMIN` |
|
||||
| Userverwaltung, Logs, System Prompt, System Agent, Reset/Delete, Global Reindex, Profil-/Modell-Umschaltungen | `ROLE_SUPER_ADMIN` |
|
||||
|
||||
Die bestehende Hierarchie bleibt erhalten:
|
||||
|
||||
```yaml
|
||||
ROLE_SUPER_ADMIN: [ROLE_KNOWLEDGE_ADMIN, ROLE_EDITOR, ROLE_ADMIN_AREA, ROLE_CHAT_USER, ROLE_USER]
|
||||
ROLE_KNOWLEDGE_ADMIN: [ROLE_EDITOR, ROLE_ADMIN_AREA, ROLE_CHAT_USER, ROLE_USER]
|
||||
ROLE_EDITOR: [ROLE_ADMIN_AREA, ROLE_CHAT_USER, ROLE_USER]
|
||||
ROLE_ADMIN_AREA: [ROLE_USER]
|
||||
ROLE_CHAT_USER: [ROLE_USER]
|
||||
```
|
||||
|
||||
## Geänderte Dateien
|
||||
|
||||
### Controller / Security
|
||||
|
||||
- `config/packages/security.yaml`
|
||||
- ergänzt konkrete `access_control`-Regeln vor dem generischen `/admin`-Fallback
|
||||
- schützt Dokument-/Tag-Bereiche mit `ROLE_EDITOR`
|
||||
- schützt Modell-/Ingest-Konfigbereiche mit `ROLE_KNOWLEDGE_ADMIN`
|
||||
- schützt kritische Systembereiche mit `ROLE_SUPER_ADMIN`
|
||||
|
||||
- `src/Security/ApplicationRoles.php`
|
||||
- Dokumentation der zentralen Rollenquelle erweitert
|
||||
|
||||
- `src/Controller/Admin/DocumentController.php`
|
||||
- Dokumentliste/-details und alle Dokumentpflegeaktionen nun `ROLE_EDITOR`
|
||||
- Reset/Delete bleiben `ROLE_SUPER_ADMIN`
|
||||
- Rollenstrings auf `ApplicationRoles`-Konstanten umgestellt
|
||||
|
||||
- `src/Controller/Admin/DocumentTagController.php`
|
||||
- Tagbearbeitung auf Dokumentebene nun `ROLE_EDITOR`
|
||||
|
||||
- `src/Controller/Admin/TagController.php`
|
||||
- Tagliste, Taganlage, Löschung und Zuweisung nun `ROLE_EDITOR`
|
||||
|
||||
- `src/Controller/Admin/IngestProfileController.php`
|
||||
- Profilansicht nun `ROLE_KNOWLEDGE_ADMIN`
|
||||
- Profilanlage, Aktivierung und Löschung nun `ROLE_SUPER_ADMIN`
|
||||
- `remove` nur noch per `POST`
|
||||
- Aktivieren/Löschen prüfen jetzt serverseitig CSRF-Token
|
||||
|
||||
- `src/Controller/Admin/ModelGenerationConfigController.php`
|
||||
- `src/Controller/Admin/IngestJobController.php`
|
||||
- `src/Controller/Admin/AdminVectorLogController.php`
|
||||
- `src/Controller/Admin/AdminSystemLogController.php`
|
||||
- `src/Controller/Admin/SystemAgentController.php`
|
||||
- `src/Controller/Admin/SystemPromptController.php`
|
||||
- `src/Controller/Admin/UserController.php`
|
||||
- Rollenstrings auf zentrale `ApplicationRoles`-Konstanten umgestellt
|
||||
|
||||
### Templates
|
||||
|
||||
- `templates/admin/base.html.twig`
|
||||
- Sidebar blendet Rollenbereiche passend aus:
|
||||
- User: Super-Admin
|
||||
- Dokumente/Tags: Editor
|
||||
- System Prompt/Agent/Logs: Super-Admin
|
||||
- KI-/LLM-Setup und Ingest-Profile: Knowledge-Admin
|
||||
|
||||
- `templates/admin/dashboard/index.html.twig`
|
||||
- Global-Reindex-Button nur noch für Super-Admins sichtbar
|
||||
- Nicht-Super-Admins sehen einen Hinweis statt eines Buttons, der in 403 läuft
|
||||
|
||||
- `templates/admin/document/index.html.twig`
|
||||
- `templates/admin/document/show.html.twig`
|
||||
- `templates/admin/document/new_version.html.twig`
|
||||
- Dokumentpflege- und Versionsaktionen auf `ROLE_EDITOR` ausgerichtet
|
||||
- Dokumentlöschung bleibt `ROLE_SUPER_ADMIN`
|
||||
|
||||
- `templates/admin/ingest_profile/list.html.twig`
|
||||
- Profilanlage nur noch für Super-Admins sichtbar
|
||||
- Aktivieren/Löschen bleiben Super-Admin-Aktionen
|
||||
|
||||
- `templates/admin/tag/index.html.twig`
|
||||
- Taganlage, Zuweisung und Löschung nur für Editor sichtbar
|
||||
- Nicht-Editor sehen keine mutierenden Aktionen
|
||||
|
||||
## Nicht geändert
|
||||
|
||||
- RAG-/Retrieval-Logik
|
||||
- Scoring
|
||||
- Shop-Matching
|
||||
- PromptBuilder
|
||||
- AgentRunner
|
||||
- Chat-Antwortlogik
|
||||
- User-CRUD-Fachlogik aus p93
|
||||
- Error-Page-/Access-Denied-Grundlogik aus p94
|
||||
|
||||
## Lokale Checks
|
||||
|
||||
Ausgeführt im ZIP-Stand ohne `vendor/`:
|
||||
|
||||
```bash
|
||||
find src/Controller/Admin src/Security src/Repository src/Service/Admin -type f -name '*.php' -print0 | xargs -0 -n1 php -l
|
||||
python3 - <<'PY'
|
||||
from pathlib import Path
|
||||
import yaml
|
||||
|
||||
yaml.safe_load(Path('config/packages/security.yaml').read_text())
|
||||
print('[OK] yaml parse')
|
||||
PY
|
||||
```
|
||||
|
||||
Zusätzlich wurde eine einfache Twig-Balance-Prüfung auf `{% if %}`, `{% for %}` und `{% block %}` für die geänderten Templates durchgeführt.
|
||||
|
||||
## Empfohlene Checks in der Zielumgebung
|
||||
|
||||
```bash
|
||||
php bin/console cache:clear
|
||||
php bin/console lint:yaml config/packages/security.yaml
|
||||
php bin/console lint:twig templates/admin
|
||||
php bin/console debug:router | grep admin_
|
||||
php bin/console mto:agent:config:validate
|
||||
php bin/console mto:agent:regression:test
|
||||
php bin/console mto:agent:config:audit-source --details
|
||||
```
|
||||
|
||||
## Manuelle Rollentests
|
||||
|
||||
### `ROLE_ADMIN_AREA`
|
||||
|
||||
Soll können:
|
||||
|
||||
- `/admin/dashboard`
|
||||
- `/admin/guides`
|
||||
- `/admin/jobs`
|
||||
|
||||
Soll verweigert bekommen:
|
||||
|
||||
- `/admin/documents`
|
||||
- `/admin/tags`
|
||||
- `/admin/model-config`
|
||||
- `/admin/ingest-profiles`
|
||||
- `/admin/users`
|
||||
|
||||
### `ROLE_EDITOR`
|
||||
|
||||
Soll können:
|
||||
|
||||
- Dokumente ansehen/anlegen
|
||||
- Dokumentversionen hochladen
|
||||
- Versionen aktivieren
|
||||
- Ingest für Dokumentversionen starten
|
||||
- Tags anlegen/löschen/zuweisen
|
||||
|
||||
Soll verweigert bekommen:
|
||||
|
||||
- Userverwaltung
|
||||
- System Prompt
|
||||
- System Agent
|
||||
- Systemlogs / Vectorlog
|
||||
- Global Reindex
|
||||
- Dokumentlöschung / kompletter Reset
|
||||
- Ingest-Profil aktivieren/löschen
|
||||
|
||||
### `ROLE_KNOWLEDGE_ADMIN`
|
||||
|
||||
Soll können:
|
||||
|
||||
- alles aus `ROLE_EDITOR`
|
||||
- Modellkonfiguration ansehen/testen
|
||||
- Ingest-Profile ansehen
|
||||
|
||||
Soll verweigert bekommen:
|
||||
|
||||
- Userverwaltung
|
||||
- System Prompt/Agent
|
||||
- Logs
|
||||
- Profil-/Modell-Aktivierung und Löschung
|
||||
- Global Reindex
|
||||
- Reset/Delete
|
||||
|
||||
### `ROLE_SUPER_ADMIN`
|
||||
|
||||
Soll alles können.
|
||||
@@ -0,0 +1,197 @@
|
||||
# RetrieX Patch 96 - Follow-up Product Identity & Weak History Guard
|
||||
|
||||
## Ziel
|
||||
|
||||
Dieser Patch haertet zwei beobachtete Folgefrage-Fehlerklassen, ohne Retrieval, Scoring, Shop-Ranking oder Shop-Matching fachlich umzubauen:
|
||||
|
||||
1. **Preis-Folgeaktionen nach mehreren sichtbaren Produkten** duerfen nicht mehr auf den ersten generischen Modellanker zurueckfallen.
|
||||
- Fehlerfall: Antwort nennt `Testomat 2000 CLT` und `Testomat LAB CL`; der Button `Preis anzeigen` erzeugte nur `Testomat 2000`.
|
||||
- Neu: Wenn mehrere in der Antwort sichtbare Produkte erkannt werden, wird die Preis-Folgeaktion aus den konkreten Produktidentitaeten mit Produktnummern gebaut.
|
||||
|
||||
2. **Referenzielle Shop-Nachfragen mit schwacher Query** wie `suche im Shop nach der Information` duerfen den Produktfokus aus der History nicht verlieren.
|
||||
- Fehlerfall: Nach `Testomat 2000 THCL` wurde die Shopquery zu `information` statt zum Verlaufanker `testomat 2000 thcl`.
|
||||
- Neu: Schwache referenzielle Shopqueries, die nur aus Meta-/Info-/Noise-Tokens bestehen, werden mit dem letzten Produktmodellanker aus der History ersetzt.
|
||||
|
||||
## Geaenderte Dateien
|
||||
|
||||
- `src/Agent/AgentRunner.php`
|
||||
- `config/retriex/chat-messages.yaml`
|
||||
- `config/retriex/genre.yaml`
|
||||
|
||||
## Technische Umsetzung
|
||||
|
||||
### 1. Preis-Folgeaktionen behalten mehrere konkrete Produktidentitaeten
|
||||
|
||||
`buildFollowUpActionPriceQuery()` faellt bei mehreren angezeigten Produkten nicht mehr auf `answer_anchor` zurueck. Stattdessen wird eine begrenzte Produktliste aus den sichtbaren Shopprodukten gebaut, inklusive Produktnummern.
|
||||
|
||||
Beispiel erwarteter Button-Prompt:
|
||||
|
||||
```text
|
||||
Zeige mir die Preise zu folgendem Produkt bzw. den Produkten: Testomat 2000® CLT 100137; Testomat® LAB CL 116106.
|
||||
```
|
||||
|
||||
Der Prompt enthaelt bewusst `Produkt/Produkten` und `Preise`, damit die bestehende Product-List-Follow-up-Logik fuer mehrere Produkte greifen kann und einzelne Produktanker separat suchen kann.
|
||||
|
||||
### 2. Schwache referenzielle Shopqueries nutzen History-Modellanker
|
||||
|
||||
Neue Guard-Funktion:
|
||||
|
||||
```php
|
||||
guardWeakReferentialShopQueryWithHistoryModelAnchor()
|
||||
```
|
||||
|
||||
Sie greift nur, wenn:
|
||||
|
||||
- die aktuelle Frage referenziell genug ist, um History fuer Shopqueries zu nutzen,
|
||||
- die Shopquery keinen eigenen Produktmodellanker enthaelt,
|
||||
- der Prompt selbst keinen neuen Produktmodellanker enthaelt,
|
||||
- es kein Product-List-Follow-up ist,
|
||||
- es kein Indikator-/Zubehoer-/Reagenz-Follow-up ist,
|
||||
- die Query nur aus schwachen Meta-/Info-/Noise-Tokens besteht,
|
||||
- in der History ein Produktmodellanker gefunden wird.
|
||||
|
||||
Die schwachen Info-Woerter werden in `genre.yaml` gepflegt:
|
||||
|
||||
- `information`
|
||||
- `informationen`
|
||||
- `info`
|
||||
- `infos`
|
||||
- `details`
|
||||
- `detail`
|
||||
- `daten`
|
||||
- `angaben`
|
||||
|
||||
## Bewusst nicht geaendert
|
||||
|
||||
- Keine neue fachliche Produktliste im PHP-Core.
|
||||
- Keine neue Testomat-/THCL-/CLT-/LAB-CL-Sonderlogik im Core.
|
||||
- Keine Aenderung an Retrieval, Scoring, Ranking, Shopware-Suche oder PromptBuilder-Faktenregeln.
|
||||
- Bestehende Indikator-/Zubehoer-Follow-up-Guards bleiben priorisiert.
|
||||
|
||||
## Lokale Checks
|
||||
|
||||
Im Patch-Arbeitsverzeichnis ausgefuehrt:
|
||||
|
||||
```bash
|
||||
php -l src/Agent/AgentRunner.php
|
||||
python3 - <<'PY'
|
||||
import yaml, pathlib
|
||||
for path in pathlib.Path('config/retriex').glob('*.yaml'):
|
||||
with path.open(encoding='utf-8') as f:
|
||||
yaml.safe_load(f)
|
||||
print('all retriex yaml OK')
|
||||
PY
|
||||
```
|
||||
|
||||
Ergebnis:
|
||||
|
||||
- `AgentRunner.php`: Syntax OK
|
||||
- alle `config/retriex/*.yaml`: YAML OK
|
||||
|
||||
Nicht lokal ausfuehrbar, weil `vendor/` im ZIP nicht enthalten ist:
|
||||
|
||||
```bash
|
||||
bin/console mto:agent:config:validate
|
||||
bin/console mto:agent:regression:test
|
||||
bin/console mto:agent:config:audit-source --details
|
||||
bin/console mto:agent:config:audit-patterns --details
|
||||
```
|
||||
|
||||
## Testprompts nach Einspielen
|
||||
|
||||
### Fehlerfall 1: Preis-Folgeaktion nach zwei Chlor-Geraeten
|
||||
|
||||
```text
|
||||
mit welchem testomat kann ich freies chlor messen
|
||||
```
|
||||
|
||||
Erwartung in der Antwort:
|
||||
|
||||
- Hauptprodukte bleiben fokussiert auf die passenden Chlor-Geraete, insbesondere:
|
||||
- `Testomat 2000® CLT` / `100137`
|
||||
- `Testomat® LAB CL` / `116106`
|
||||
- Folgeaktion `Preis anzeigen` darf nicht mehr nur `Testomat 2000` materialisieren.
|
||||
|
||||
Danach den angezeigten Preis-Button klicken oder sinngleich testen:
|
||||
|
||||
```text
|
||||
Zeige mir die Preise zu folgendem Produkt bzw. den Produkten: Testomat 2000® CLT 100137; Testomat® LAB CL 116106.
|
||||
```
|
||||
|
||||
Erwartung:
|
||||
|
||||
- Shopquery/Split-Lookups fokussieren die konkreten Produktidentitaeten.
|
||||
- Es duerfen nicht breit alle `Testomat 2000` Varianten wie Fe, Antox, Br2, ClO2 oder Wartungskoffer als Hauptantwort erscheinen.
|
||||
|
||||
### Fehlerfall 2: schwache Info-Shopnachfrage verliert THCL-Anker
|
||||
|
||||
```text
|
||||
welche grenzwerte kann der testomat 2000 thcl messen
|
||||
```
|
||||
|
||||
Dann:
|
||||
|
||||
```text
|
||||
suche im shop nach der information
|
||||
```
|
||||
|
||||
Optional auch Tippfehler-Variante:
|
||||
|
||||
```text
|
||||
such eim shop nach der information
|
||||
```
|
||||
|
||||
Erwartung:
|
||||
|
||||
- Die finale Shopquery darf nicht `information` sein.
|
||||
- Erwarteter Verlaufanker: `testomat 2000 thcl`.
|
||||
- Shopantwort bleibt beim Geraet/Modellfokus und driftet nicht zu fremden Testomat-808-SiO2-Zubehoerteilen, Horiba-Testern oder allgemeinen Treffern ab.
|
||||
|
||||
### Gruener Gegenflow: Brauwasser bleibt stabil
|
||||
|
||||
```text
|
||||
ich suche ein wasseranalyse messgerät für eine Brauerei, um das brauwasser messen zu können
|
||||
```
|
||||
|
||||
Dann:
|
||||
|
||||
```text
|
||||
begründe deine auswahl
|
||||
```
|
||||
|
||||
Dann:
|
||||
|
||||
```text
|
||||
was kostet das gerät denn
|
||||
```
|
||||
|
||||
Erwartung:
|
||||
|
||||
- Auswahl bleibt auf `Testomat 2000® CAL` fokussiert, sofern die Begruendung CAL als Hauptempfehlung gesetzt hat.
|
||||
- Preis-Follow-up bleibt `testomat 2000 cal gerät` bzw. entsprechend CAL-fokussiert.
|
||||
- Keine Regression hin zu breiten `testomat 2000` Varianten.
|
||||
|
||||
### Bestehende Praezisionsregression: Indikator 300 bleibt stabil
|
||||
|
||||
```text
|
||||
Was ist der niedrigste Grenzwert für die Wasserhärte, welcher mit einem Testomaten überwacht werden kann?
|
||||
```
|
||||
|
||||
Dann:
|
||||
|
||||
```text
|
||||
mit welchem indikator wird der wert gemessen
|
||||
```
|
||||
|
||||
Dann:
|
||||
|
||||
```text
|
||||
was kostet der indikator
|
||||
```
|
||||
|
||||
Erwartung:
|
||||
|
||||
- `0,02 °dH` / `Testomat 808`
|
||||
- `Indikatortyp 300`
|
||||
- Shopquery weiterhin fokussiert, z. B. `testomat 808 300 indikator`
|
||||
- Nur die zwei exakten Indikator-300-Produkte, keine `300 S`-Varianten und keine anderen Codes.
|
||||
Reference in New Issue
Block a user