Files
Omika/docs/diagnostics/T24-A-prompt-ia-referentiel.md
2026-10-23 18:46:50 +02:00

144 lines
7.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# T24-A — Prompt IA local + référentiel administrable ScreenCode/FeatureCode
> Statut : PRÉPROD LOCAL / recette manuelle. Aucun Git, aucune Production.
## 1. Générer le prompt IA (Partie A)
### Principe
Le centre Diagnostics génère un **prompt d'analyse local** depuis un diagnostic/erreur.
**Aucun appel IA externe** (OpenAI, ChatGPT ou autre) : le système se contente de :
```
diagnostic → construire un texte local → afficher le prompt → permettre « Copier »
```
Le prompt n'est **jamais enregistré en PostgreSQL** (génération à la demande uniquement, V1).
### Boutons
- **Détail diagnostic** (`/Diagnostics/{id}`) : bouton « Générer le prompt IA » à proximité du
contexte technique.
- **Détail erreur** (`/Erreurs/{id}`) : bouton « Générer le prompt IA » (depuis l'occurrence la
plus récente du groupe).
Un clic déclenche la génération **côté serveur** (handler Razor Pages `OnGetPromptAsync`), puis
affiche le prompt dans une modale dédiée avec un bouton **« Copier le prompt »** (réutilise
`OmikaCopy()`, aucune nouvelle librairie JS).
### Service partagé
La construction du prompt est centralisée dans `Omika.Diagnostics.Core` :
`DiagnosticPromptBuilder.Build(DiagnosticEventRecord, IReadOnlyList<DiagnosticEventRecord>?)`.
Le chargement des événements corrélés est partagé par
`DiagnosticsDetailModel.GetCorrelatedEventsAsync(...)` (utilisé par le détail diagnostic ET le
détail erreur). Aucune logique dupliquée.
### Informations incluses (si disponibles)
- **CONTEXTE** : ClientCode, Environment, ServerInstance, Source, Component, Platform,
OperatingSystem, OperatingSystemVersion, Manufacturer, Model, AppVersion, AppBuild,
ScreenCode, FeatureCode.
- **ERREUR** : EventCode, Level, Priority, ErrorCode, Timestamp, DurationMs.
- **MESSAGE** : Message (tronqué à 2000 caractères).
- **EXCEPTION** : ExceptionType, StackTrace (tronquée à 4000 caractères).
- **HTTP / MÉTADONNÉES** : uniquement les clés whitelistées (`method`, `statusCode`,
`routeTemplate`, `retryCount`, …) et valeurs simples non interdites.
- **CORRÉLATION** : TraceId, OperationId, SessionId.
- **IDENTITÉ TECHNIQUE AUTORISÉE** : LicenseNumber (numéro fonctionnel), DeviceKey et ActorKey
**tronqués** (pseudonymes HMAC-SHA256, jamais réversibles).
- **ÉVÉNEMENTS CORRÉLÉS** (si TraceId/OperationId) : chronologie compacte, **bornée à 25
événements**, sans stack trace (timestamp, level, eventCode, component, message court,
screen/feature).
### Informations exclues (jamais)
password, password_hash, ApiKey, api_key_hash, Bearer token, SigningKey, HmacKey,
ConnectionString, DeviceId brut, UserId brut, CollaborateurId brut, ClientId brut, email,
téléphone, IMEI, serial, MAC, secret de licence.
La politique **réutilise** les filtres existants : `DiagnosticForbiddenData`
(jetons interdits) et `DiagnosticMetadataPolicy` (whitelist des clés). Aucune seconde logique de
filtrage. Défense en profondeur : chaque valeur relue est re-vérifiée avant inclusion.
### Format
Le prompt commence par :
> « Analyse cette erreur Omika et aide-moi à déterminer sa cause probable. »
puis demande explicitement : cause probable, niveau de confiance, fichier/méthode à vérifier en
priorité, éléments de preuve, hypothèses alternatives, correctif recommandé, tests de
confirmation, dire si l'erreur semble volontaire/de test, distinguer faits confirmés et hypothèses.
### Exemple /dev/throw
L'événement de recette `API_HTTP_ERROR` / `InvalidOperationException` / `/dev/throw` /
`TELEMETRY_TEST_ERROR` / `Development` produit un prompt contenant naturellement ces données —
**aucune règle codée en dur** « /dev/throw ».
## 2. Référentiel administrable (Partie B)
### Règle absolue
`diagnostic_event` **reste la vérité** sur ce qui a réellement été observé. Le référentiel
(`diagnostics_reference`) est un **enrichissement** (libellé / description / ordre / état) et ne
détermine **jamais** quels événements sont acceptés. Un code observé non référencé reste visible
dans les filtres.
### Table `diagnostics_reference` (migration 011)
`id`, `reference_type` (`SCREEN_CODE` / `FEATURE_CODE`), `code` (normalisé TRIM+UPPER),
`label`, `description`, `enabled`, `sort_order`, `created_at_utc`, `updated_at_utc`.
- Unicité : `(reference_type, UPPER(code))` — index unique.
- **Code immuable** après création. Pour corriger un code : créer une nouvelle entrée + archiver
l'ancienne.
- **Archivage = `enabled=false`**, jamais de DELETE physique (V1).
### Ownership / GRANT (011)
- Propriétaire : `omika_diagnostics_owner`.
- `omika_diagnostics_web` : `SELECT`, `INSERT`, `UPDATE (label, description, enabled,
sort_order, updated_at_utc)` + `USAGE` séquence. **Aucun DELETE.**
- `omika_diagnostics_api` et `omika_diagnostics_worker` : **aucun droit** (testé négativement).
### Initialisation (idempotente)
Les **29 ScreenCode** et **3 FeatureCode** du catalogue applicatif sont seedés par la migration
avec leurs libellés (`ON CONFLICT DO NOTHING`). Un libellé modifié par un Admin n'est **jamais
écrasé** au redémarrage.
### Pages
- `/Referentiel` : consultation (Support + Admin) — sections Codes écran / Codes fonctionnalité
alimentées par le référentiel DB (libellé + description + état), repli catalogue statique si DB
indisponible.
- `/Referentiel/Admin` : **Admin uniquement** — liste (Type, Code, Libellé, Description, État,
Dernière modification, Actions), création, modification (libellé/description/état/tri),
archivage/réactivation, et section **« Codes observés non référencés »** avec **ajout rapide**.
### Procédure : ajout d'un nouveau code
1. Un événement arrive avec un `screen_code`/`feature_code` inconnu (ex. `FACTURE_DETAIL`).
2. Le code **apparaît automatiquement** dans les filtres Diagnostics (alimentés par
`diagnostic_event`), affiché `FACTURE_DETAIL (non référencé)`.
3. Dans `/Referentiel/Admin` → « Codes observés non référencés » → « Ajouter » (type + code
préremplis) → Admin renseigne le libellé/la description.
4. Le filtre affiche alors `Détail de facture (FACTURE_DETAIL)` — **sans modifier les données
historiques**. La recherche SQL utilise toujours le **code**, jamais le libellé.
### Dropdowns / filtrage
Les listes déroulantes continuent d'être alimentées par les codes **réellement observés** (jamais
`SELECT` sur `diagnostics_reference` uniquement). Si une référence existe : `Libellé (CODE)` ;
sinon : `CODE (non référencé)`. La valeur du filtre reste toujours le CODE.
## 3. Corrections UX (Partie C)
- Filtre « Acteur » → **« Acteur pseudonymisé »** + aide : « Identifiant pseudonymisé permettant
de retrouver les événements d'un même utilisateur. »
- Page/menu « Versions » → **« Versions Omika »**.
- « Version la plus représentée » → **« Version Omika la plus observée »** + note : « Les valeurs
correspondent aux événements observés, pas au nombre d'installations. »
## 4. Sécurité
- Prompt généré : 0 fuite de données interdites (testé — `DiagnosticPromptBuilderTests`).
- HTML : le prompt est affiché via `textContent` (aucune injection HTML).
- Aucun enregistrement du prompt (ni PostgreSQL, ni log).
- Migration 011 : aucune colonne secret, aucun mot de passe.
## 5. Tests
- `Omika.Diagnostics.Tests` : 574/574 (baseline 536 + 38 tests T24-A).
- `Omika.Tests` : 3366/3370 — 4 échecs environnementaux/préexistants (construction de vues
Avalonia ×2, course temporelle ShellViewModel, accès HFSQL), **aucune régression** liée à T24-A
(T24-A est isolé dans le sous-système Diagnostics, non référencé par Omika.Tests).
## 6. Migration 011
`infra/postgresql/011_diagnostics_reference.sql` — ordre final : `001 → … → 010 → 011`.
Idempotente, non destructive (aucun DROP/DELETE), aucun mot de passe.