Commit Graph

110 Commits

Author SHA1 Message Date
dom
3a6e008269 feat: 3 optimisations vitesse — batch QC, pipeline CPU/GPU, QC sur Dell
1. Batch QC : la validation justifications (gemma3:12b) est différée et
   exécutée en une seule passe après tous les documents du groupe.
   Réduit les swaps modèle de 2 par document à 2 pour le groupe entier.

2. Pipeline CPU/GPU : prepare_document (extraction, anonymisation, edsnlp)
   tourne sur CPU pendant que le GPU traite le document précédent via
   un ThreadPoolExecutor(1) en prefetch.

3. QC sur Dell : si la machine secondaire (192.168.1.11) est disponible,
   les appels QC sont envoyés là-bas en parallèle du codage principal,
   éliminant tout swap modèle sur le GPU principal.

Refactoring associé :
- _postprocess_dossier() extrait la logique vetos/décisions/GHM/finalizer
- call_ollama() accepte ollama_url pour cibler un serveur spécifique
- _is_secondary_available() avec cache 60s pour éviter le polling

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 15:45:17 +01:00
dom
2fb7b46a7c Merge branch 'feat/parallel-rag-pipeline' — optimisation flux LLM 2026-03-08 14:35:54 +01:00
dom
b0aa83f664 fix: adapter tests RAG à la nouvelle parallélisation (enrich_dp_only + enrich_das_and_actes)
Les agents d'optimisation ont splitté _enrich_with_rag en _enrich_dp_only
et _enrich_das_and_actes mais n'ont pas mis à jour les mocks dans test_rag.py.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:35:39 +01:00
dom
f94d8496cb feat: monter OLLAMA_MAX_PARALLEL défaut à 4
Le défaut de 2 était sous-optimal pour la RTX 5070 (12 Go VRAM).
Ollama gère la concurrence interne et queue les requêtes
excédentaires. Un pool de 4 workers Python permet de mieux
saturer le GPU sur les appels DAS/actes parallèles.

Le .env peut toujours override cette valeur via OLLAMA_MAX_PARALLEL.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:17:24 +01:00
dom
355a33acde feat: paralléliser DAS_LLM + RAG DP + DP selector
Restructure le pipeline dans extract_medical_info() :

AVANT : DAS_LLM séquentiel → ThreadPool(RAG complet + DP_selector)

APRÈS :
  Groupe 1 (ThreadPool max_workers=3) :
    - DAS_LLM : extraction DAS supplémentaires
    - RAG DP : enrichissement DP seul (via enrich_dp)
    - DP selector : sélection NUKE-3
  Groupe 2 :
    - enrichissement DAS + actes (via enrich_das_and_actes)

Le RAG DP ne dépend pas du DAS_LLM, donc les deux peuvent
s'exécuter en parallèle. Le Groupe 2 attend le DAS_LLM car
il enrichit les DAS trouvés par celui-ci.

Ajoute aussi des timings sur les groupes et la validation QC.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:17:18 +01:00
dom
f5a6122495 feat: timings granulaires appels LLM (RAG, DAS, DP, QC)
Ajoute des mesures time.monotonic() autour de chaque appel LLM dans
rag_search.py : enrich_diagnostic, enrich_acte, extract_das_llm.
Format de log : logger.info("⏱ [RAG-DP] 14.2s — texte")

Découpe enrich_dossier() en 2 fonctions exportées :
- enrich_dp() : enrichit seulement le DP (parallélisable)
- enrich_das_and_actes() : enrichit DAS + actes en parallèle
L'ancienne enrich_dossier() reste comme wrapper rétro-compatible.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:16:38 +01:00
dom
0cafb47e8d feat: batching CPAM par modèle pour réduire les swaps VRAM
Restructure le flux CPAM pour regrouper les appels LLM par modèle :
- Phase 1 (cpam model) : extraction + argumentation de TOUS les contrôles
- Phase 2 (validation model, 1 swap) : validation adversariale de tous
- Phase 3 (cpam model, si correction nécessaire) : correction des échoués

Nouvelle fonction generate_cpam_responses_batched() qui orchestre les 3 phases.
L'ancienne generate_cpam_response() reste intacte (rétrocompatible, utilisée
par le viewer pour la régénération unitaire).

Structure intermédiaire _CpamDraft (dataclass) pour transporter l'état entre phases.
Fonctions de phase extraites : _phase_generate, _phase_validate, _phase_correct,
_phase_finalize.

Gain estimé : de ~4*N swaps de modèle à 2-4 swaps (indépendant de N contrôles).
Sur RTX 5070 avec des modèles 24-32b, chaque swap coûte ~10-15s.
Pour 3 contrôles : économie estimée ~60-90s.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:10:34 +01:00
dom
d6b4e48989 feat: timings appels LLM CPAM (génération, validation, correction)
Ajoute des mesures time.time() autour de chaque appel Ollama dans le flux CPAM :
- [CPAM-EXTRACT] : extraction structurée (passe 1, role=cpam)
- [CPAM-GEN] : génération argumentation (passe 2, role=cpam)
- [CPAM-VALID] : validation adversariale (role=validation)
- [CPAM-CORR] : correction post-validation (role=cpam)

Permet de mesurer le temps réel de chaque phase et d'identifier
les coûts de swap de modèle VRAM entre les rôles cpam/validation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:09:42 +01:00
dom
0bfc1a9d6e fix: corriger 3 tests fusion alignés sur la logique Trackare > CRH
Les tests supposaient que le CRH gagnait à spécificité égale — en réalité
le bonus Trackare l'emporte (codage DIM établissement prioritaire).
Aussi : dp_selection synthétique créée par fusion quand aucun source n'existe.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 13:09:59 +01:00
dom
1da45b7c8a fix: résoudre doublon endpoint /health après merge des branches
Garde la version complète (Ollama check + timestamp) et utilise APP_VERSION.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 12:50:03 +01:00
dom
bd5f479832 Merge branch 'feat/test-coverage' 2026-03-08 12:44:27 +01:00
dom
234c19f6fe Merge branch 'feat/versioning-config' 2026-03-08 12:44:25 +01:00
dom
f0b0adca02 Merge branch 'fix/cleanup-repo'
# Conflicts:
#	t2a-viewer.service
2026-03-08 12:44:22 +01:00
dom
0c38bc261b chore: sauvegarde état courant avant merge des branches teammates
Modifications en cours : pipeline médical (cim10_extractor, dp_finalizer,
dp_selector, fusion, rag_search), viewer (helpers, detail.html),
cache ollama et référentiels.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 12:36:54 +01:00
dom
aed5c87bc3 feat: endpoint /health avec tests (8 tests)
Ajoute GET /health retournant un JSON avec :
- status: "ok"
- version: "2.1.0"
- ollama: true/false (connectivité testée avec timeout 2s)
- timestamp: ISO 8601 UTC

Tests couvrent : format JSON, champs requis, Ollama joignable/injoignable,
format timestamp ISO, type booléen du champ ollama.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 12:01:47 +01:00
dom
dcee7c960c feat: tests étendus pour src/medical/dp_finalizer.py (34 tests)
Couvre les cas non couverts dans test_dp_finalizer.py :
- R6 Z-code non whitelisté remplacé par DAS
- Fonctions internes (_family3, _code_in_candidates, _has_strong_evidence)
- _apply_r5 en appel direct (Z whitelisté, R-code avec candidat non-R)
- Détection source Trackare par document_type/reason/evidence
- Cas limites (code None, candidats vides, pas de dp_selection)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 12:01:04 +01:00
dom
caaa6deb14 feat: tests étendus pour src/quality/decision_engine.py (53 tests)
Couvre les règles non couvertes dans le fichier existant :
- Fonctions internes (_norm, _first_float, _parse_normal_range, etc.)
- Nettoyage hiérarchique (.9 vs code spécifique)
- D50 sans preuve martiale → downgrade D64.9
- D69.6 thrombopénie vs plaquettes normales → RULED_OUT
- decision_summaries pour toutes les actions (DOWNGRADE, REMOVE, RULED_OUT, NEED_INFO)
- Détection analytes (sodium, potassium)
- _age_band et cas limites de scoring

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 11:59:57 +01:00
dom
5ba3903569 feat: tests pour src/viewer/helpers.py (77 tests)
Couvre les filtres Jinja2 (confidence_badge, severity_badge, cma_level_badge,
decision_badge, human_where, format_doc_name, etc.), les fonctions de
statistiques (compute_group_stats, compute_dashboard_stats, compute_dim_synthesis),
et les utilitaires (_date_to_iso, _sort_qc_alerts, _compute_jours_restants).
Utilise pytest.mark.parametrize pour les cas multiples.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 11:58:28 +01:00
dom
768bb94193 feat: validation config au démarrage
- Ajoute validate_config() dans src/config.py :
  * Vérifie accessibilité Ollama (warning si injoignable)
  * Warning si ANTHROPIC_API_KEY absente (fallback cloud indispo)
  * Warning si modèles CPAM et validation identiques
  * Vérifie qu'au moins un modèle LLM est configuré
- Appel automatique au démarrage du viewer Flask
- Ne fait jamais crasher l'app (warnings uniquement)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 11:49:12 +01:00
dom
5b58886ebf feat: versioning sémantique (single source of truth)
- Crée src/__version__.py comme source unique de version (2.1.0)
- pyproject.toml utilise dynamic version via setuptools attr
- Affiche la version dans le footer de la sidebar (base.html)
- Ajoute endpoint /health avec version et status

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 11:47:44 +01:00
dom
828356eff1 fix: corriger le chemin gunicorn dans t2a-viewer.service
Le chemin ExecStart pointait vers /home/dom/ai/t2a/.venv/ (ancien projet)
au lieu de /home/dom/ai/t2a_v2/.venv/ (projet actuel).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 11:38:37 +01:00
dom
8f43759ba4 chore: compléter .gitignore et dé-tracker output/ (1603 fichiers)
Ajouts au .gitignore :
- output/ : données patient anonymisées et résultats pipeline (ne doivent pas être versionnées)
- unsloth_compiled_cache/ : cache de compilation Unsloth
- *.rttm : fichiers de diarisation audio
- /benchmark_*.py, /bench_pipeline.py : scripts de benchmark ponctuels (racine)
- training/ : artefacts d'entraînement

Suppression du tracking de output/ via git rm --cached (1603 fichiers, ~1.2M lignes).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 11:38:23 +01:00
dom
ae02c81572 chore: suppression fichiers parasites non liés au projet
- unsloth_compiled_cache/ : cache de compilation Unsloth (fine-tuning LLM, non lié)
- sans titre_diarization.rttm : fichier RTTM vide (transcription audio)
- sans titre_diarized.txt : transcription audio 241 Ko (medical_ai_scribe)
- sans titre_summary_v2.md : résumé audio 11 Ko (medical_ai_scribe)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 11:37:50 +01:00
dom
214a5d1914 fix: qualité codage — anti-hallucination LLM + négation regex + veto calibration
- Prompt DAS_EXTRACTION : ajout consignes anti-hallucination (zero invention,
  pas d'inférence de comorbidités, exiger citation exacte du texte)
- Prompt CODING_CIM10 : ajout consignes conditionnel et négation
- diagnostic_extraction.py : détection de négation avant les patterns regex DAS
  (bloque "pas d'embolie", "absence de sepsis", "sans signe d'IRC", etc.)
- veto_engine.py : VETO-03 conditionnel cherche maintenant PRÈS du concept
  (40 chars), "si" isolé ne déclenche plus de faux positif, ajout cues
  (possible, risque de, aspect de, à confirmer, à rechercher)
- veto_engine.py : négation enrichie (ne retrouve pas, sans signe/argument,
  écarté, infirmé, pas mis en évidence)

Batch analysis: VETO-02 63% from LLM hallucinations, VETO-03 63% false positives

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:59:02 +01:00
dom
a371626f40 feat: dictionnaire de codage + détection anomalies statistiques
- Script build_coding_dict.py génère le dictionnaire depuis le batch (240 dossiers)
- coding_dictionary.json : co-occurrences DP→DAS, fréquences, associations bio
- anomaly_stats.py : 8 checks (DP/DAS rare, DAS manquant, bio-DAS, âge atypique)
- Intégré dans le pipeline cim10_extractor post-DIM-senior

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:48:36 +01:00
dom
13fe9fa666 chore: mise à jour output pipeline (anonymized + structured)
Résultats de re-traitement pipeline v2 sur 261 dossiers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:14:42 +01:00
dom
c73515ac89 chore: mise à jour index FAISS (+15 référentiels ATIH) et cache ollama
- Index FAISS ref/proc enrichis avec 15 nouveaux documents ATIH/DGOS
- Métadonnées FAISS refactorisées (metadata_ref, metadata_proc séparés)
- Référentiels utilisateur ajoutés (5 docs)
- Nettoyage cache ollama (suppression backup gemma3)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:14:32 +01:00
dom
4b6e3cf6d5 feat: optimisations pipeline médical (bio_normals, GHM, DP selector, CIM-10)
- bio_normals: table de normes biologiques étendue (+200 analytes)
- bio_extraction: amélioration parsing valeurs biologiques
- cim10_extractor: règles supplémentaires extraction codes
- dp_selector: affinement sélection diagnostic principal
- ghm: estimation sévérité GHM enrichie
- validation_pipeline: correctifs mineurs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:14:13 +01:00
dom
63f61f196b feat: 8 optimisations vitesse + qualité pipeline CIM-10
1. Parallélisation intra-dossier (RAG + DP selector en parallèle)
2. Cache embeddings FAISS (_embed_cached avec LRU)
3. Lazy loading edsnlp (déjà singleton, vérifié)
4. Prompt DP amélioré avec règles PMSI/ATIH
5. Validation croisée Bio↔DAS (cohérence biologie/diagnostics)
6. Resélection DP après vetos/exclusions (reselect_dp_after_vetos)
7. Pré-filtrage R-codes (déjà implémenté dans exclusion_rules)
8. Cache embeddings texte (intégré dans rag_search)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 22:18:07 +01:00
dom
e6bd7406a4 chore: nettoyage YAML base.yaml + corrections templates viewer
- base.yaml: suppression commentaires verbose, normalisation quotes YAML
- Templates: corrections mineures cpam.html, detail.html, dim.html, index.html
- admin_rules.html: ajustements interface admin règles
- test_referentiels.py: mise à jour imports

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 22:07:00 +01:00
dom
79c447688c fix: ajouter liens navigation vers interface admin regles
- Lien sidebar base.html : "Regles metier" sous "Referentiels"
- Lien croise admin_referentiels.html → regles
- Boutons dashboard : "Gerer les referentiels" + "Regles metier"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 19:42:42 +01:00
dom
1e837c2758 feat: interface admin regles, refactoring viewer, README, pyproject.toml
- Nouveau module rules_manager.py : CRUD YAML pour les regles metier
- Nouveau blueprint bp_rules.py + template admin_rules.html :
  interface web pour activer/desactiver/ajouter/supprimer des regles
- Extraction helpers.py depuis app.py (filtres Jinja2, statistiques,
  scan dossiers, status systeme) — app.py passe de 1585 a 482 lignes
- Suppression backward-compat re-exports dans cim10_extractor et
  cpam_response (imports corriges dans les tests)
- README.md : architecture, modules, installation, utilisation
- pyproject.toml : dependencies completes, config ruff, pytest, coverage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 19:11:27 +01:00
dom
2478928798 chore: suppression scripts obsolètes, anciens benchmarks et fichiers de dev
- Suppression scripts racine : analyze_pdfs.py, rebuild_index.py,
  compare_cpam_models.py, test_cpam_quality.py, test_quality_tier_live.py
- Suppression docs obsolètes : rapport_analyse_pdfs.md,
  ANALYSE_COHERENCE_ET_AMELIORATIONS.md, patch_0+1.md
- Suppression outils CPAM legacy : extract_t2a_llm.py, parse_decision_ucr.py
- Suppression backups CPAM : *.xlsx_old
- Suppression hors-git : 19 archives .zip, cache gemma3.bak

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 16:49:26 +01:00
dom
4e2b4bd946 refactor: réorganisation référentiels, nouveaux modules extraction, nettoyage code obsolète
- Réorganisation data/referentiels/ : pdfs/, dicts/, user/ (structure unifiée)
- Fix badges "Source absente" sur page admin référentiels
- Ré-indexation COCOA 2025 (555 → 1451 chunks, couverture 94%)
- Fix VRAM OOM : embeddings forcés CPU via T2A_EMBED_CPU
- Nouveaux modules : document_router, docx_extractor, image_extractor, ocr_engine
- Module complétude (quality/completude.py + config YAML)
- Template DIM (synthèse dimensionnelle)
- Gunicorn config + systemd service t2a-viewer
- Suppression t2a_install_rag_cleanup/ (copie obsolète)
- Suppression scripts/ et scripts_t2a_v2/ (anciens benchmarks)
- Suppression 81 fichiers _doc.txt de test
- Cache Ollama : TTL configurable, corrections loader YAML
- Dashboard : améliorations templates (base, index, detail, cpam, validation)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 16:48:10 +01:00
dom
2578afb6ff chore: add .gitignore 2026-03-05 00:37:41 +01:00
dom
542797a124 fix: injecter les tags réels du dossier dans le prompt CPAM pour éliminer les tags génériques [TYPE-N]
Le LLM générait des tags génériques [BIO-N], [TRT-N] au lieu des vrais tags du dossier,
causant des warnings "preuve non traçable". Corrigé en 3 points :
- cpam_context: liste exhaustive des tags disponibles injectée dans le prompt
- templates: remplacement des patterns génériques par {tags_disponibles_str}
- cpam_validation: guardian step 4b résout les tags génériques résiduels

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 23:14:40 +01:00
dom
798cee463f feat: guardian déterministe + config modèles locaux + prompt TIM R1-R6
Guardian déterministe post-LLM (0 appel modèle, <1ms) :
- Corrige les valeurs bio hallucinées via confrontation dossier
- Step 1b : vérifie l'association test↔diagnostic via _BIO_THRESHOLDS
- Chemin bidirectionnel : CONFIRMÉ↔NON CONFIRMÉ selon bio réelle
- Force R3 : codes bio-infirmés → codes_non_defendables
- Step 2b : retire les codes bio-confirmés de codes_non_defendables
- Retire les moyens défendant des codes bio-contredits
- _safe_bio_replace() : regex protégeant les normes [X-Y]
- Nettoyage texte libre (conclusion, rappel, codes_nd, raisonnement)
- Score factuel déterministe avec pénalités

Config modèles pour déploiement local (DGX Spark) :
- CPAM : mistral-small3.2:24b (TIM complet, bonne précision bio)
- Validation : qwen3:32b (rapide, LOGIC-3 actif)
- Timeout : 120s → 600s pour modèles locaux

Ollama : migration /api/generate → /api/chat (messages format)

Prompt CPAM_ARGUMENTATION restructuré :
- R1-R6 non-négociables en tête (avant données)
- Champ raisonnement_interne (chain-of-thought structuré)
- 5 passes TIM avec références explicites aux règles

Test cpam_quality : métriques guardian dans le résumé

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 22:00:40 +01:00
dom
ce7a9650af feat: méthode TIM experte CPAM + moteur de règles étendu
CPAM — Méthode TIM (mémoire en défense) :
- Réécriture CPAM_ARGUMENTATION avec raisonnement 5 passes TIM
  (contexte admin → motif réel → confrontation bio → hiérarchie → validation défensive)
- _BIO_THRESHOLDS (19 entrées) + _build_bio_confrontation() pour
  confrontation biologie/diagnostic avec seuils chiffrés et verdicts
- _format_response() dual format : nouveau TIM (moyens numérotés, tableau
  bio, codes non défendables, conclusion dispositive) + rétrocompat legacy
- CPAM_ADVERSARIAL mis à jour pour vérifier honnêteté intellectuelle
- Tests adaptés + 12 nouveaux tests (bio confrontation, format TIM)

Moteur de règles :
- Nouvelles règles YAML : demographic, diagnostic_conflicts,
  procedure_diagnosis, temporal, parcours
- Bio extraction FAISS (synonymes vectoriels)
- Veto engine enrichi (citations, Trackare skip, règles démographiques)
- Decision engine : _apply_bio_rules_gen() + matchers analytiques

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 11:57:07 +01:00
dom
795110d2e6 fix: anonymisation — sur-anonymisation + fuites PHI + patterns sécurisés
- DR_NAME_PATTERN limité à 2 mots (évite capture "CHARLANNE Traitements")
- CIVILITE_NAME_PATTERN et DESTINATAIRE_PATTERN : chaque mot doit commencer
  par majuscule (évite capture de phrases entières comme noms)
- DATE_NAISSANCE_PATTERN : colon optionnel après "le" ("Né(e) le : DD/MM/YYYY")
- N_CSULT_PATTERN ajouté pour numéros de consultation anesthésie
- CONTACT_RELATION_PATTERN : +15 relations familiales (Neveu, Nièce, Oncle...)
- MEDICAL_TERMS_WHITELIST : +30 termes hospitaliers (scanner, traitement,
  viscerale, radiologie, consultation, etc.)
- FRENCH_STOP_WORDS : +20 mots courts (fort, aide, suite, avant, etc.)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 12:38:13 +01:00
dom
99069f150a feat: anonymisation qualité++ — 15 patterns, subparts tirets, fix entity registry
Bloc A: fix sous-parties dans _mappings, filtre NER anti-tag,
intégration patterns manquants (DESTINATAIRE, PRESCRIPTION_AUTHOR),
whitelist médicaments élargie (+60), villes retirées de whitelist.

Bloc B: CRH dedup chars 200-1000, CP_VILLE vrais codes postaux FR,
DR_NAME capital par mot, BACTERIO header tolère ligne vide.

Bloc C: DR_NAME negative lookahead multi-docteurs même ligne,
entity_registry split tirets (RITZ-QUILLACQ), fix early return
subparts dans _find_matching_entity, PRESCRIPTION_AUTHOR élargi
(Révisé/Traité, variable.), NOTE_AUTHOR élargi (Diététicienne,
Kiné, Ergo), + 8 nouveaux patterns (CONTACT_RELATION, MOD_PAR,
AIDE_NAME, SIGNATURE_LINE, VALIDE_PAR, INTERNE_SIGNATURE,
FOIS_NAME, MALADIE_NAME), adresses inline +ALLEE/IMP,
text_cleaner préserve abréviations médicales.

Validé sur 6 cas (21, 11, 104, 160, 50, 200). 70 tests OK.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 11:11:47 +01:00
dom
f4a23a5f43 feat: qualité anonymisation — sur-anonymisation, fuites PHI, nettoyage bruit
P0-A: stop words français + seuil subparts 5 chars + sweep conditionnel
P0-B: 6 nouveaux patterns PHI (DDN, Par, N Ipp, Adresse, DEMANDE, venue)
P2-C: cohérence pseudonymes (_find_matching_entity) + fix crochets
P1-B: text_cleaner.py — sidebar OCR, footers, dédup vitales, collapse blanks
P1-A: dédup CRH par SequenceMatcher (seuil 85%)
Tests: 34 nouveaux tests (996 pass, 0 fail)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 14:00:07 +01:00
dom
63354e75bc tests: dp_finalizer — 20 tests R1-R5 + pass-through + quality_flags + sérialisation
- TestR1CrhConfirmedOverridesTrackare (2 tests : override + cohérent)
- TestR2TrackareCorroborated (2 tests : exact + family3)
- TestR3TrackareSymptom (3 tests : override, review prudent, evidence faible)
- TestR4Ambiguous (1 test)
- TestR5Interdictions (4 tests : Z-code, Z-whitelist, R-code, allow_symptom)
- TestPassThrough (3 tests : CRH-only, Trackare-only, aucun DP)
- TestFinalizeDp (5 tests : flags merge, alertes append, sources set, sérialisation)

1063 tests passent, 0 régression.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 17:50:32 +01:00
dom
c7317af447 feat: dp_finalizer — arbitrage Trackare vs CRH-only avec traçabilité audit
Nouveau module src/medical/dp_finalizer.py :
- 5 règles d'arbitrage (R1-R5) : CRH CONFIRMED override, Trackare corroboré,
  symptôme R* override/review, ambigu REVIEW, Z-code/R-code interdits auto-confirm
- Traçabilité : dp_trackare, dp_crh_only, dp_final sur DossierMedical
- quality_flags dict (merge sans écraser) + alertes_codage (append)

Modèles config.py :
- DPCandidate, DPSelection (NUKE-3)
- get_dp_ranker_llm_enabled(), check_adversarial_model_config()
- Champs DossierMedical : dp_trackare, dp_crh_only, dp_final, quality_flags

Intégration :
- main.py : appel finalize_dp() après vetos/GHM (individuel + fusionné)
- benchmark : finalizer dans _rebuild_and_select(), dp_final dans output

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 17:50:07 +01:00
dom
cad0dd22b1 tests: alias DLBCL + garde-fou Trackare + e2e PDFs réels + gold CRH + benchmark enrichi
- 11 tests unitaires : TestAliasAndConclusionBonus (7) + TestTrackareSymptomGuard (4)
- Tests e2e sur PDFs réels (skip si absent) : méningite A87.0 + DLBCL C83.3 top1
- Gold CRH enrichi : 5 cas (2 réels ajoutés : 115_23066188, 132_23080179)
- Benchmark synthese : récupération conclusion depuis source_excerpt des DAS/traitements
- .gitignore : protection anti-PHI (real_crh_pdfs/, data/crh_samples/*.pdf)
- docs/PHI_POLICY.md : 7 règles de sécurité PHI
- Rapports debug : case 132 REVIEW (garde-fou actif), top errors, DIM pack

1043 tests passent, 0 régression.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 14:35:57 +01:00
dom
06a1be5425 feat: alias diagnostiques CIM-10 + scoring conclusion + garde-fou Trackare R-code
- DIAGNOSIS_ALIASES : mapping acronymes cliniques → CIM-10 (DLBCL→C83.3, SCA→I25.1, EP→I26.9, IDM→I21.9, etc.)
- Scoring 4b étendu : conclusion (+2) ajouté aux sections diagnostiques, matching par alias en plus du terme/code
- _collect_evidence : détection alias dans les sections pour preuves plus complètes
- Garde-fou Trackare : si DP est un R-code (symptôme) et que les sections CRH mentionnent un diagnostic étiologique via alias → verdict REVIEW au lieu de CONFIRMED, alerte DIM
- Case 74 : verdict attendu REVIEW (conclusion mentionne les 2 diagnostics, delta insuffisant)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 14:35:15 +01:00
dom
07c267539c tests: CRH sections + DP diag bonus + case 74 regression + fusion propagation
- test_extraction: +21 tests (sections diag_sortie/diag_principal/synthese,
  variantes titres, terminaisons, faux positifs mid-sentence, biosynthèse)
- test_dp_selector: +55 tests (flags, candidates, scoring, hardening DIM,
  bonus +4/+2, evidence excerpt, cas 74 D50→I25.1 corrigé)
- test_fusion: +39 tests (propagation dp_selection evidence/reason/verdict,
  source 2e dossier, pas de crash si aucun DP)
- fixtures: case_74_min.json + 3 fixtures DP existantes

Aucun mock utilisé — données synthétiques uniquement.
Le test cas 74 passe : I25.1 gagne sur D50 grâce au bonus diag_sortie +4.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 13:28:54 +01:00
dom
2701efb1d2 feat: CRH diag sections + DP scoring bonus + evidence by code
- crh_parser: 3 nouvelles sections (diag_sortie, diag_principal, synthese)
  avec garde-fou début de ligne pour éviter faux positifs mid-sentence
- dp_selector: NUKE-3 sélecteur DP déterministe (548 lignes)
  - build_candidates/score_candidates/select_dp
  - bonus +4 pour mention dans diag_sortie/diag_principal
  - bonus +2 pour mention dans synthese
  - hardening DIM : A1 evidence, A2 mono-fragile, A3 confidence cap
  - _collect_evidence match par terme OU code CIM-10
  - LLM tiebreaker optionnel (DP_RANKER_CONSTRAINED)
- fusion: propagation dp_selection depuis le dossier source du DP retenu

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 13:28:31 +01:00
dom
1e79b7cc52 feat: viewer — affichage qualité CPAM, traçabilité décisions DP/DAS, VetoReport et bio
- CPAM : badge quality_tier (A/B/C), bandeau requires_review, warnings catégorisés, force probante dossier
- DP/DAS : code suggestion barré → code final si modifié, ligne grisée si ruled_out, badges décision + règles
- DAS : badge needs_info avec détails, raison ruled_out sous la ligne
- VetoReport : section contestabilité avec verdict, barre score/100, tableau issues HARD/MEDIUM/LOW
- Biologie : badge Suspect avec tooltip, valeurs écartées en details pliable
- Nouveau filtre Jinja2 decision_badge, import _assess_dossier_strength (pas de duplication)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 10:56:15 +01:00
dom
cc642c1143 fix: max_tokens extraction CPAM et validation adversariale 1500→3000
Les deux appels tronquaient systématiquement (done_reason=length),
causant des JSON invalides et des faux positifs adversariaux.
num_predict n'a aucun impact sur VRAM ni sur les réponses courtes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 10:12:26 +01:00
dom
d192af74ec feat: évaluation force probante dossier + seuils qualité relaxés pour dossiers faibles
Score 0-10 basé sur les preuves objectives (bio/img/trt/actes).
Dossier faible (score < 3) : prompt LLM adapté + seuil adversarial
abaissé (score 2-3 → Tier B au lieu de C). Les éléments contextuels
(âge, IMC, urgence) restent dans le prompt mais hors du scoring car
ils ne constituent pas des preuves opposables à un contrôleur CPAM.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 09:19:43 +01:00