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

7.8 KiB
Raw Blame History

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.