Commit Graph

118 Commits

Author SHA1 Message Date
Dom
e84cdee393 fix(server): durcissement sanitizer PII suite revue adversariale Qwen
- FN-1/2/3 : ajout RE_PRENOM_NOM (« Prénom NOM » inversé sans parens/crochets,
  ex. « Alix DATTIN ») ; 2e mot tout-majuscules -> 0 FP sur « Mozilla Firefox ».
- FN-4 (majeur, 228 events) : sanitize_event scanne désormais les titres
  RÉCURSIVEMENT (vision_info.window_capture.window_title et tout titre imbriqué),
  au lieu de 3 clés top-level hardcodées.
2 correctifs issus de la revue croisée Qwen. 11 tests verts, 0 FP.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 20:24:52 +02:00
Dom
30d8f65e9a feat(server): sanitize_event — assainissement PII au niveau event
sanitize_event(event, mapping) applique le principe « Léa apprend l'interface,
pas la donnée » (décision Dom 28/06) avant persistance :
- text_input -> contenu (text + raw_keys) remplacé par [SAISIE] (option b) :
  résout la fuite la plus grave (contenu médical) SANS NER ni détection ;
- titres de fenêtre (active_window_title + window/to/from.title) : identité
  patient tokenisée (anonymize_text), app/écran gardés ; cohérence par mapping.
Copie défensive (ne mute pas l'event d'origine). 4 tests (9 au total) verts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 19:53:09 +02:00
Dom
8e4d09594c feat(server): assainissement PII couche regex+structurelle (tokens typés cohérents)
pii_sanitizer.anonymize_text() remplace la PII par des tokens typés et
cohérents ([IPP_1], [AGE_1], [NOM_1]) : protège la donnée ET garde la structure
(type de champ) utile à l'apprentissage des variables. Sans modèle, déployable
partout. Filet regex (IPP/NIR/TEL/EMAIL/AGE, repris de anonymisation) + règles
structurelles cliniques (NOM (NAISSANCE) Prénom ; [Nom Prénom] PACS) + blacklist
logiciels anti-FP. 5 tests verts. Couche NER (noms libres) en complément ensuite.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 19:08:43 +02:00
Dom
4a38000e74 feat(agent_v1): helpers logging PII-safe (push-log-DGX, brique 4)
Module agent_v1/core/log_safe.py — 3 helpers purs pour assainir les logs
client à la source : _title_hash (SHA1[:8], corrélation sans révéler),
_sanitize_metadata (drop title/active_window/window_title), _path_ext
(extension seule). 6 tests unitaires verts. Module inerte (non encore wired) ;
le branchement dans le code runtime suit en étape supervisée.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 11:24:54 +02:00
Dom
2597ca9110 feat(server): endpoint GET /api/v1/agents/logs/{machine_id} (push-log-DGX, brique 3)
Route de diagnostic dashboard (read-only) : restitue les logs poussés par un
poste, rangés par machine_id. Bearer global ; volontairement sans garde fleet
(consultation d'un poste révoqué/en panne). limit=tail pour borner la réponse.
4 tests d'intégration verts ; store inchangé (briques 1-2 figées).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 10:47:08 +02:00
Dom
bbe897e614 feat(server): endpoint POST /api/v1/agents/logs (push-log-DGX, brique 2)
Reçoit un batch de logs client, range via AgentLogsStore par machine_id.
Garde-fous : auth Bearer (401), agent actif via _guard_agent_registry_access
(403 si révoqué/inconnu, + touch_last_seen), cap anti-flood 413 (G3 Qwen,
RPA_AGENT_LOGS_MAX_BATCH=1000). TDD 4/4 ; non-régression enroll 16/16.

refs DETTE-020 DETTE-021

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 16:25:14 +02:00
Dom
a29b7a2f21 feat(server): store de logs clients par machine_id (push-log-DGX, brique 1)
AgentLogsStore : append/read JSONL rangés par machine_id (fichier par jour),
anti path-traversal sur machine_id (entrée réseau), purge_old rétention 30j
(garde-fou G4 Qwen). TDD 3/3 vert. Pas encore wired (endpoint = brique 2).

refs DETTE-020 DETTE-021

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 16:14:28 +02:00
Dom
29cb466595 fix(lea): journalisation client vers fichier (DETTE-021)
setup_logging() branche un TimedRotatingFileHandler vers LOG_FILE (rotation
quotidienne + rétention 180j, Règlement IA Art.12) + console. Sous pythonw
(sans console), basicConfig->stderr était perdu => diagnostic terrain aveugle.
main.py appelle setup_logging au démarrage, avec fallback console si le fichier
est indisponible (ne jamais empêcher Léa de démarrer).

TDD: tests/unit/test_agent_v1_logging.py (3 tests RED->GREEN ; module chargé par
chemin pour éviter les imports lourds DETTE-011/013). py_compile main.py OK.

refs DETTE-021

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 16:44:31 +02:00
Dom
3b592dd867 feat(core): signature de trajectoire PII-safe + normalisée (R1/R2 amendés, QG Qwen)
Anonymisation déterministe de la cible par regex DÉDIÉES (email/date/tél/IPP →
tokens) avant hashing : deux sessions sur le même champ (patients/dates
différents) → même signature. Normalisation casse/accents/espaces (logique
action_executor._norm_text, redéfinie localement pour rester léger).

Choix QG Qwen (2026-06-25) : PAS de pii_blur (il protège les dates qu'on veut
neutraliser), PAS de NER (un hash d'identité doit être déterministe/portable
labo↔DGX). Noms propres sans titre non gérés (stratégie b ; gate = audit
agrégat by_text DGX avant prod). R2 fallback coords RETIRÉ (casserait F1).
R3 (machine_id hors hash) déjà conforme.

TDD: +4 tests (RED→GREEN, 9/9). Primitive non wirée (0 consommateur runtime)
→ changement de calcul sans impact.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 10:47:18 +02:00
Dom
c9b7cdabb7 fix(core): signature de trajectoire stable malgre le moteur de grounding (by_text)
Some checks failed
tests / Lint (ruff + black) (push) Failing after 1m53s
tests / Tests unitaires (sans GPU) (push) Failing after 1m49s
tests / Tests sécurité (critique) (push) Has been skipped
Le champ by_role remontait la methode de detection (yolo/ocr/vlm), instable entre
sessions : deux apprentissages du meme parcours detectes differemment produisaient
deux signatures -> fusion (create-or-update) ratee. On sort by_role de la signature
et on s'appuie sur le texte semantique de la cible (by_text), independant du moteur
de grounding. Fallback quand by_text vide : titre de fenetre / description VLM.

Test TDD: test_signature_stable_despite_grounding_role_difference (RED->GREEN).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 21:35:57 +02:00
Dom
74df0822e2 feat(core): adaptateur workflow->signature de trajectoire (BFS edges, cibles stables)
Extrait d'un workflow core (dict) la sequence ordonnee (action_type, target stable)
via traversee BFS depuis entry_nodes (comme le bridge d'import), en n'utilisant que
des champs stables (by_role/by_text/window) et en ignorant coords/IDs de noeuds.
Branche la primitive trajectory_signature sur de vrais workflows.

Test TDD: tests/unit/test_workflow_trajectory_signature.py (3 tests, RED->GREEN).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 18:22:30 +02:00
Dom
a86c1ebb83 feat(core): signature de trajectoire stable pour identite workflow (Phase 0, F1)
Primitive partagee (SP-4/SP-2/competences) : hashe la sequence ordonnee
(action_type, target) d'un parcours en ignorant les champs session-specifiques
(node_id, timestamp, coordonnees) -> deux apprentissages du meme parcours = meme
signature = base du create-or-update (decision F1). Le target stable peut etre
compose avec screen_signature() existante.

Test TDD: tests/unit/test_trajectory_signature.py (5 tests, RED->GREEN).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 18:14:23 +02:00
Dom
1d6efdb1b7 feat(dashboard): enrôlement lit l'adresse serveur depuis system_config.json
Câble l'éditeur adresses/ports du dashboard (services.streaming) vers le
RPA_SERVER_URL généré pour chaque agent Léa. Priorité config > env > défaut ;
host loopback/vide = non configuré (fallback env → pas de régression).
Permet de changer l'IP serveur (labo .45 → clinique .178) depuis l'UI sans
toucher l'env ni le code. +3 tests TDD.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 12:07:27 +02:00
Dom
ec1fb81054 fix(dashboard,worker): vérité produit P0 — dashboard+worker+VWB export
Some checks failed
tests / Lint (ruff + black) (push) Failing after 1m46s
tests / Tests unitaires (sans GPU) (push) Failing after 2m0s
tests / Tests sécurité (critique) (push) Has been skipped
War-room clôture DGX 2026-06-18 (recadrage Dom : graphe/apprentissage/mémoire/dashboard = surface produit P0).
Le dashboard et le statut worker affichaient des états faux ; corrige pour refléter la vérité du produit.

- dashboard FAISS: distingue index brut / metadata HMAC invalide / runtime / absent (plus de faux "inactif")
- dashboard process-mining: 503 explicite missing_dependency (plus de message trompeur)
- dashboard /api/workflows + system/status: lecture DB VWB v3 canonique (total réel = 24, plus de 0)
- worker /processing/status: véridique (lit _worker_health.json) + statut "idle/armé (lazy)" distinct de "dégradé (échec)"
- VWB export: N steps -> N actions/edges (dernière action n'est plus perdue)
- tests: dashboard routes, worker status truthfulness, export VWB

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 17:50:12 +02:00
Dom
33c1e2e0d1 fix(grounding): confiance grounding dérivée sémantique (DETTE-019)
Some checks failed
tests / Lint (ruff + black) (push) Failing after 1m48s
tests / Tests unitaires (sans GPU) (push) Failing after 1m50s
tests / Tests sécurité (critique) (push) Has been skipped
Le score/confidence figés à 0.85 dans _resolve_by_grounding rendaient le
garde-seuil (_RESOLUTION_MIN_SCORES["grounding"]=0.60) inopérant (0.85>0.60
toujours accepté). Le grounding VLM n'a pas de confiance modèle native (prompt
{"x","y"}, pas de logprob de localisation — confirmé QG Qwen 2026-06-15). On
dérive une confiance SÉMANTIQUE : le texte cible est-il à la position trouvée ?
(_validate_text_at_position). Confirmé→0.90, absent→0.45 (<seuil→rejet),
non vérifiable→0.70. Confiance contextuelle documentée, PAS une proba modèle.

TDD : 5 tests (score varie / présent accepté / absent rejeté / score==confidence
/ sans by_text neutre), RED→GREEN. Non-régression : 24 tests resolve_engine +
câblage qwen3vl + legacy bbox verts. E2E panel inchangé (15/15). Pré-check OCR
non impacté. DETTE-018 (legacy non gardé) reste séparée.

refs DETTE-019

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 09:17:46 +02:00
Dom
5c5ce747b0 feat(grounding): câblage Qwen3-VL-4B/vLLM (RPA_GROUNDING_ENGINE, défaut off)
Active via RPA_GROUNDING_ENGINE=qwen3vl_vllm (défaut OFF = legacy Qwen2.5-VL
inchangé, byte-identique). Mode qwen3vl : port 8001/Qwen3-VL-4B, prompt point
0-1, think=false, parse /1000 (dissout DETTE-006), method "grounding" gardée
(seuil 0.60), pas de fallback Ollama (abstention si vLLM down). Grounder validé
au bench Easily réel (0.933, ~1s/cas). TDD : 4 tests (normalisation 0-1000,
think=false, prompt fractions 0-1, gating score bas).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 08:39:29 +02:00
Dom
b20d17882e feat(wp-c): méthode verify_token côté registre (patch 3, inerte)
Ajoute AgentRegistry.verify_token(token) -> machine_id|None : compare le
SHA-256 du token aux token_hash des agents 'active' via hmac.compare_digest
(temps constant). Agent désinstallé/révoqué refusé ; rotation à l'enroll
invalide l'ancien token.

Inerte au runtime : méthode non branchée sur l'auth HTTP (le branchement
derrière flag RPA_FLEET_PER_AGENT_TOKEN sera le Patch 4). api_stream.py
intouché. TDD : 6 tests + non-régression WP-C/WP-B (53 verts). Voir
PLAN-WPC-TDD-EXECUTABLE.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 14:21:04 +02:00
Dom
9fb2c7bfee feat(wp-c): génération token par poste à l'enroll (patch 2, inerte runtime)
Génère un token unique (secrets.token_hex(32)) à chaque (ré)enrôlement,
persiste uniquement son empreinte SHA-256 dans token_hash, renseigne
token_issued_at, retourne le clair une seule fois dans le résultat de
enroll. Le clair n'est jamais journalisé ni persisté.

Inerte au runtime : api_stream.py intouché, l'endpoint /agents/enroll ne
propage ni le clair ni le hash (api_token global inchangé). Auth runtime
non modifiée. Aucun branchement _verify_token. TDD : 8 tests + non-régression
WP-B/WP-C (47 verts). Voir PLAN-WPC-TDD-EXECUTABLE / DETTE-015.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 11:36:44 +02:00
Dom
f7f6926410 feat(wp-c): migration colonnes token par poste (patch 1, inerte)
Ajoute token_hash + token_issued_at à enrolled_agents via ALTER TABLE
idempotent (_init_db). Colonnes inertes : aucun branchement auth, runtime
inchangé (tests WP-B verts). Base du token par poste (WP-C, cf DETTE-015).

TDD: tests/unit/test_wpc_migration.py (présence, idempotence, préservation
des données d'une base existante). 3 tests + non-régression WP-B = 9 passed.

refs DETTE-015

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 21:04:18 +02:00
Dom
0ee54157e5 fix(p1g): garde-fou VRAM adapté à la mémoire unifiée (DGX GB10)
Some checks failed
tests / Lint (ruff + black) (push) Failing after 1m44s
tests / Tests unitaires (sans GPU) (push) Failing after 1m49s
tests / Tests sécurité (critique) (push) Has been skipped
resolve_device('auto') renvoyait 'cpu' sur le GB10 : le plafond max_total_gb=6
(pensé pour la RTX 12 Go dédiés) voyait used≈99 Go car la mémoire UNIFIÉE compte
la RAM système. Au-dessus de DEFAULT_LARGE_VRAM_GB=24 (grosse carte / mémoire
unifiée), le plafond n'est plus appliqué ; seul free >= min_free_gb décide.
RTX (<=24 Go) inchangée.

Détecté au bench GB10 2026-06-08 (auto->cpu, OCR 10x plus lent). +2 tests (17/17).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 17:43:12 +02:00
Dom
6d34b3cb68 chore(dgx): snapshot consolidation WIP pour transfert poc DGX
Some checks failed
tests / Lint (ruff + black) (push) Failing after 1m44s
tests / Tests unitaires (sans GPU) (push) Failing after 1m49s
tests / Tests sécurité (critique) (push) Has been skipped
Regroupe le WIP non committé requis pour le clone/runtime DGX (Option A) :
- api_stream.py : préflight replay + smoke santé modèles + handler 403 WP-B
- de-hardcode VLM : vlm_config, gpu/*, vram_orchestrator, ollama_manager
- stream_processor, semantic_matcher, agent_chat (app/planner/intent)
- workflows.db (acquis ; le transfert artifacts le mettra à jour + rewrite chemins)
- docs : plans DGX, benchmarks VLM/grounders, recherche SOTA, coordination 8 juin

Snapshot destiné à la branche poc-dgx poussée sur Gitea pour cloner le DGX.
Scan anti-secret : clean. graphify (repo embarqué) exclu.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 16:33:58 +02:00
Dom
f18de016d7 fix(wp-b): verrou d'enrôlement du parc (RPA_FLEET_ENROLL_LOCKED)
Ferme le contournement "poste révoqué + nouveau machine_id + token global" :
quand RPA_FLEET_ENROLL_LOCKED=true, l'enrôlement d'un machine_id INCONNU est refusé
(FleetEnrollLockedError). Les machines déjà connues conservent leur comportement :
active -> AlreadyEnrolled, désinstallé non-revoke -> réactivable, admin_revoke -> Revoked.

- agent_registry.py : _fleet_enroll_locked() + FleetEnrollLockedError + gate avant INSERT
- tests/unit/test_fleet_enroll_lock_wpb.py : 6 tests (verts)

NB : le handler HTTP 403 (api_stream.py /api/v1/agents/enroll) reste dans le WIP de la
branche (api_stream déjà modifié par le préflight non committé) — sera embarqué au commit
de consolidation api_stream. La logique de sécurité (gate) est dans agent_registry, committée.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 15:43:04 +02:00
Dom
549ea0631b fix(wp-a): dashboard fail-closed sans mot de passe par défaut
Le dashboard refuse de démarrer si DASHBOARD_PASSWORD absent ET auth non
explicitement désactivée (DASHBOARD_AUTH_DISABLED). Supprime le mot de passe
par défaut hardcodé exploitable.

- web_dashboard/app.py : _require_dashboard_password() fail-closed (lève en prod
  sans secret ; mode dev/test = DASHBOARD_AUTH_DISABLED=true)
- tests/unit/conftest.py : DASHBOARD_AUTH_DISABLED=true par défaut pour les tests
- tests/unit/test_dashboard_failclosed_wpa.py : 5 tests (fail-closed, anti-régression défaut)
- tests/unit/test_dashboard_auth_p0a.py : fixture _restore_module restaure un état neutre sûr

48 tests dashboard verts (WP-A + non-régression auth/routes).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 15:27:06 +02:00
Dom
0e215da842 feat(p1g): device policy GPU/CPU paramétrable pour la cascade vision
resolve_device(auto/cuda/cpu) avec garde-fou VRAM et fallback CPU propre.
Bascule EasyOCR/SoM/docTR sur GPU si VRAM libre, rollback env sans toucher au code.

- core/gpu/device_policy.py (nouveau) : resolve_device + garde-fou VRAM (max_total_gb)
- core/detection/som_engine.py, core/llm/ocr_extractor.py,
  agent_v0/server_v1/resolve_engine.py : câblage device auto (35 lignes)
- tests/unit/test_device_policy.py : 15 tests (verts venv réel)

Rollback sans toucher au code : RPA_VISION_DEVICE=cpu (force CPU global) / RPA_EASYOCR_GPU=0.
Bench GPU réel (latence) + activation large après verdict Qwen. QG Qwen deja valide sur le patch.
Mergé depuis worktree agent-a4f390f410e00ad7c (base 5b2afa362), 3 fichiers cibles non modifiés
dans le principal (zéro écrasement), dry-run apply propre.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 15:20:52 +02:00
Dom
d00fe7b00b feat(health): gate vision + détection des modèles aveugles
Détecte les modèles VLM/grounding « aveugles » (capabilities sans vision, ex.
UI-TARS réimporté sans mmproj) pour éviter le HTTP 500 silencieux masqué par
la cascade de grounding.

- core/detection/model_health.py : has_vision_capability() (cache, fail-open)
  + smoke_check_models()
- core/execution/input_handler.py : gate vision dans _grounding_ui_tars
  (skip propre vers niveau 3 si modèle aveugle, plus de 500 silencieux)
- tests/unit/test_model_health.py : 6 tests (vision/aveugle/fail-open/cache/smoke)

Incident 2026-06-08 : UI-TARS sans mmproj -> niveau 2 cascade en 500 silencieux,
non détecté (hors chemin runtime démo + échec avalé par fallback + zéro test).
NB : le smoke non bloquant au démarrage (api_stream.py startup) reste dans le WIP
de la branche, mélangé au préflight non committé.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 11:51:18 +02:00
Dom
5b2afa3629 fix(p1w): make default VLM model DGX-safe (qwen2.5vl:7b-rpa)
Sans env RPA_VLM_MODEL/VLM_MODEL, get_vlm_model() tombait sur le default
gemma4:latest, qui peut etre absent du tunnel DGX (depull) -> 404 Ollama et
echec de tout le pipeline VLM avant un test Lea humain.

- core/detection/vlm_config.py : DEFAULT_VLM_MODEL gemma4:latest -> qwen2.5vl:7b-rpa
  (confirme present DGX, deja default reasoning + fallback bbox grounding).
  + DGX_SAFE_VLM_MODELS allow-list documentee.
- tests/unit/test_vlm_default_dgx_safe.py : 5 tests (default != gemma4:latest,
  default in allow-list, no-env -> DGX-safe, env garde priorite).

Logique de resolution inchangee, pas d'appel reseau a l'import.
gemma4:latest reste accessible via env explicite.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 12:06:10 +02:00
Dom
0f122a512f feat(p1y-alpha): add OpenAI-compatible LeaBench adapter (benchmark only)
Adapter de benchmark isole (hors runtime Lea) ciblant un serveur
/v1/chat/completions a support vision (vLLM/SGLang/TGI), pour comparer
plus tard a Ollama via LeaBench. Ne controle jamais le desktop.

- core/evaluation/openai_compat_lea_bench_adapter.py : payload data-URL
  image_url, parsing choices[0].message.content. Reutilise par import la
  logique prompt/parse/normalisation de ollama_lea_bench_adapter (zero refactor).
- tools/lea_bench_openai_compat.py : wrapper CLI (--base-url defaut :8001).
- tests/unit/test_openai_compat_lea_bench_adapter.py : 6 tests mockes HTTP
  (data URL, pas de fuite expectation/click_region, prediction valide,
  abstain safe sur HTTP!=200 et reponse malformee, JSONL rechargeable).

Aucun runtime Lea modifie. Aucun service lance.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 16:49:53 +02:00
Dom
806cc04b82 feat(p1z): centralize V4 reasoning model resolution (DGX-safe)
Remplace le default runtime dangereux `qwen2.5vl:7b` (absent du tunnel DGX
-> 404) des chemins V4/reasoning par un helper central get_reasoning_model().

- core/detection/vlm_config.py : + get_reasoning_model() + DEFAULT_REASONING_MODEL
  (qwen2.5vl:7b-rpa). Ordre : RPA_REASONING_MODEL -> RPA_VLM_MODEL/VLM_MODEL ->
  default DGX-safe. Pas d'appel reseau (lazy, safe a l'import).
- core/execution/input_handler.py, observe_reason_act.py (x3),
  core/cognition/vram_orchestrator.py : migration des 5 call-sites.
- tests/unit/test_reasoning_model.py : 8 tests (default DGX-safe, ordre de
  resolution, non-regression wiring des 3 modules V4).

Hors scope (signale lot P1.w) : DEFAULT_VLM_MODEL=gemma4:latest reste fallback
de get_vlm_model(). Client gele non touche.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 16:23:10 +02:00
Dom
4dc7d840d6 feat(p1x): de-hardcode VLM models/endpoints to vlm_config (DGX-ready)
Migre les call-sites VLM serveur vers la configuration centrale pour
fonctionner sur DGX (tunnel Ollama 11434), où gemma4:* est absent et le
port Docker 11435 est mort.

- task_planner, replay_verifier, domain_context, ir_builder, resolve_engine
  (popup): modele -> vlm_config.get_vlm_model(), defaut 11435 -> 11434
  (override GEMMA4_PORT legacy conserve)
- resolve_engine (grounding bbox x2): nouvel helper
  vlm_config.get_bbox_grounding_model() (var dediee RPA_BBOX_GROUNDING_MODEL,
  fallback RPA_GROUNDING_MODEL puis qwen2.5vl:7b-rpa) -> desambiguise le
  conflit D5-v3b, bbox_2d + num_ctx 4096 preserves
- safety_checks_provider: defaut -> get_vlm_model(), override
  RPA_SAFETY_CHECKS_LLM_MODEL preserve
- ui_detector: default_factory + resolution lazy (corrige aussi un gel a
  l'import), pas d'appel reseau a l'import
- field_extractor: property lazy via vlm_config

TDD strict (RED->GREEN), 305 tests verts, tests mockes HTTP (zero dependance
DGX reel), aucun alias Ollama.

Hors perimetre (arbitrage Dom): client Lea agent_v1/executor.py (gele),
chemin V4 observe_reason_act (RPA_REASONING_MODEL), core/config.py defaults.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 14:06:03 +02:00
Dom
5289f3de48 feat(p11): learn from offline cross-session matches 2026-06-02 17:46:15 +02:00
Dom
18ed6cb751 feat(vwb): add dashboard competence testing and health tools 2026-06-02 16:27:19 +02:00
Dom
d38f0b0f2f feat(agent): add learn action flow and grounding guards 2026-06-02 16:24:10 +02:00
Dom
86b3c8f7e7 feat(p1): persist workflows and semantic learning artifacts 2026-06-02 16:20:38 +02:00
Dom
7a1a5cb6fd fix(p0): secure agent revocation and R6 worker queue 2026-06-02 15:52:35 +02:00
Dom
335d576830 feat(dashboard): launch supervised competence tests 2026-06-01 12:09:09 +02:00
Dom
34527b5cc5 feat(lea): add dashboard competence promotion dry run 2026-05-29 21:48:00 +02:00
Dom
47377226f2 feat(vwb): harden supervised verdict evidence 2026-05-29 18:54:54 +02:00
Dom
aba849324a feat(vwb): log supervised competence verdicts 2026-05-29 18:36:06 +02:00
Dom
794a248dae feat(vwb): preview lea competence workflows 2026-05-29 18:13:36 +02:00
Dom
e66bc6d452 feat(vwb): execute wait for state 2026-05-29 17:22:35 +02:00
Dom
45b6da5e3f feat(vwb): load palette from catalog 2026-05-29 17:09:47 +02:00
Dom
99f89317cb feat(lea): substitute save menu gesture 2026-05-29 13:45:44 +02:00
Dom
a49f59b4d6 feat(competences): plan supervised replay tests 2026-05-29 11:38:12 +02:00
Dom
c1a144c673 feat(vwb): expose competence yaml catalog 2026-05-29 11:28:25 +02:00
Dom
e8a0fb0e42 feat(competences): extract batch candidates 2026-05-29 11:25:00 +02:00
Dom
4ba426c205 fix(replay): guard single in-flight dispatch
Add a private in-flight helper for replay dispatch, block machine retargeting while an action is still pending on the previous session, and warn on duplicate in-flight entries for the same replay triplet.

Freeze the Notepad runtime dialog success path and add integration coverage for single in-flight dispatch, watchdog late-report documentation, and the known concurrent-poll race as an xfail.
2026-05-25 11:00:59 +02:00
Dom
7bb8d543ab feat(cognition): dataclasses Trace + SceneExpected + Precondition (Phase 2.1)
Crée les 3 dataclasses du modèle Mandat/Protocoles/Scènes v0.3 dans
core/cognition/, standalone (aucun branchement runtime), avec
sérialisation JSON explicite et tests offline.

Préparation des phases :
- Phase 2.1 plan : objet Trace (mandate_id, intention_id, scene_id,
  affordance_signature, expected_retour, level_of_delegation)
- Workpack A : SceneExpected (monitor_index, app_name, title_patterns,
  title_anti, window_rect_hint, scene_role, accepted_transitions,
  stability_ms) + helper matches_title()
- Workpack B : Precondition (kind, window_title_must_contain/anti,
  critic_question, verify_timeout_ms) + PreconditionRecovery
  (max_attempts, on_recovery_fail, actions)

Toutes les dataclasses sont frozen, immutables, avec to_dict/from_dict
tolérants (champs vides/None -> instance vide). Validation au __post_init__
pour Precondition.kind et PreconditionRecovery.on_recovery_fail.

Aucune dépendance runtime obligatoire : si l'objet n'est pas posé sur
une action, fallback comportement actuel. Aucune modif executor /
api_stream / replay_engine / grounding.

Tests : 22/22 passent (sérialisation JSON, contrats from_dict tolérants,
validation kinds, helpers matches_title/check_title, anti-intention).

Tag rollback : rollback/pre-cognition-dataclasses-2026-05-25_0610
2026-05-25 06:08:18 +02:00
Dom
debd7b423c feat(evaluation): add local Ollama LeaBench adapter 2026-05-24 21:58:06 +02:00
Dom
10136f0ee0 feat(agent): add standalone anchor-relative resolver 2026-05-24 21:54:39 +02:00
Dom
054279feb4 feat(evaluation): add LeaBench model prompt packs 2026-05-24 21:53:24 +02:00