Commit Graph

473 Commits

Author SHA1 Message Date
Dom
105ade959d chore(agent_v1): AGENT_VERSION configurable via RPA_AGENT_VERSION (amorce DETTE-022)
Permet d'identifier la version déployée par poste (préparation MAJ auto).
Inoffensif pour DETTE-021 ; nettoie le working tree avant déploiement Émilie.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 09:50:58 +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
de73cbd404 docs(dette): DETTE-021 (logs client Léa non effectifs) + DETTE-022 (MAJ auto Léa)
DETTE-021: LOG_FILE défini mais jamais branché (basicConfig->stderr perdu sous
pythonw, dossier logs vide) -> diagnostic terrain aveugle + non-conformité
Règlement IA Art.12 (180j). Pendant client du DETTE-020.
DETTE-022: modif client = redéploiement manuel poste par poste -> dérange les
TIM, ne scale pas. Besoin MAJ auto/tâche de fond. Décision Dom 2026-06-25.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 14:32:32 +02:00
Dom
1b491326be docs(dette): DETTE-020 (P1) — incidents silencieux, pas d'alerte composant critique HS
Grounder vLLM (rpa-vllm-grounder) trouvé en crash-loop (×3960) → bascule
silencieuse sur fallback Qwen2.5-VL, sans remontée dashboard/log/alerte.
Découvert par vérif manuelle runtime (DGX clinique, 2026-06-25). Dette = absence
de supervision/alerte des composants critiques (vLLM/Ollama/services rpa-*) ;
la cause SSL/offline du crash se corrige à part.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 11:37:18 +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
2cabc6cb7e fix(vwb): propage l'image d'ancre aux substeps compound à l'import (SP-1/U-B)
Some checks failed
tests / Lint (ruff + black) (push) Failing after 1m43s
tests / Tests unitaires (sans GPU) (push) Failing after 1m48s
tests / Tests sécurité (critique) (push) Has been skipped
Les actions compound passaient par _convert_compound_substep qui ne lisait
jamais l'image d'ancre du parent -> substeps anchor_id NULL, "Ancre requise"
sans image dans le VWB. On pose desormais l'ancre du parent (meme fallback que
la branche action simple) sur le 1er substep cliquable uniquement.

Test: test_learned_workflow_bridge.py (TDD, RED->GREEN).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 15:11:32 +02:00
Dom
d686c3ac22 feat(deploy): installation 1-clic non-IT — raccourci Bureau + Demarrage auto
Some checks failed
tests / Lint (ruff + black) (push) Failing after 1m45s
tests / Tests unitaires (sans GPU) (push) Failing after 1m47s
tests / Tests sécurité (critique) (push) Has been skipped
Ajoute Installer-Lea.bat (CRLF/ASCII, chcp 65001) au paquet Lea complet :
- copie le paquet (python-embed inclus) vers %LOCALAPPDATA%\Lea (per-user,
  emplacement stable via robocopy, fallback xcopy) ;
- cree un raccourci Bureau + un raccourci dans le dossier Demarrage
  (lancement auto a l'ouverture de session) via WScript.Shell, cibles
  python-embed\pythonw.exe run_agent_v1.py (pas de console) ;
- icone optionnelle si un .ico est present dans le paquet (best-effort,
  sinon icone par defaut) ;
- lance Lea une premiere fois, message de fin clair.

Application SYSTRAY -> pas de service Windows (session 0 sans UI) :
dossier Demarrage + raccourci, per-user, sans admin/UAC.

LISEZMOI.txt du paquet remplacee par LISEZMOI-autonome.txt (le flux
install.bat + Python systeme n'existe plus dans ce paquet). build_package_full.sh
integre ces deux assets et les valide dans le ZIP.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 17:04:20 +02:00
Dom
e212f4141c fix(dashboard): servir le ZIP Lea complet autoportant à l'enrôlement Fleet
L'endpoint /api/fleet/download/<machine_id> servait deploy/Lea_v1.0.0.zip
(sources seules, suppose Python système) → installation impossible chez un
utilisateur non-IT sans Python. Désormais il sert en priorité le ZIP complet
deploy/build/Lea_full_v1.0.1.zip (python-embed inclus), avec fallback sur
l'ancien ZIP léger s'il est seul. Résolution du template à la volée (le ZIP
complet peut être buildé après le démarrage du dashboard) + message d'erreur
explicite. L'injection de Lea/config.txt est inchangée.

Le title du bouton de téléchargement ne ment plus : 'installation autonome,
sans Python — dézipper puis double-cliquer Lea.bat'.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 15:58:51 +02:00
Dom
33ddb51c3c feat(deploy): script build ZIP Lea complet autoportant (python-embed + source à jour)
Construit deploy/build/Lea_full_v<version>.zip servi par le dashboard Fleet :
runtime Python 3.12 embedded inclus, source Lea du working tree COURANT
(force --clean pour ne pas réutiliser un deploy/build/Lea/ périmé en cache),
Lea.bat embedded extrait de configure_embed.ps1, _pth patché, config.txt
placeholder CONFIGURE_ME. Pas de install.bat : plus aucun Python système requis.

Garde-fous intégrés : refus de builder si config.py embarqué diffère du repo,
si install.bat présent, ou si python-embed incomplet. Extraction de version
robuste (gère AGENT_VERSION littéral OU os.environ.get).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 15:58:51 +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
cf81ce4c7b feat(vwb): Basic auth LAN sur backend 5002 — creds dashboard, loopback exempté
Some checks failed
tests / Lint (ruff + black) (push) Failing after 1m52s
tests / Tests unitaires (sans GPU) (push) Failing after 1m52s
tests / Tests sécurité (critique) (push) Has been skipped
VWB backend exposé au LAN sans auth (point pré-clinique). Ajoute HTTP Basic auth
(mêmes identifiants que le dashboard: DASHBOARD_USER/DASHBOARD_PASSWORD) via
@app.before_request ; exempte loopback (intégration dashboard/agent_chat intacte),
/health et OPTIONS. Frontend = Create React App (pas Vite) → auth backend suffit
(navigateur LAN challengé au 1er XHR vers 5002) ; build statique = cible clinique.

Déployé + vérifié DGX: loopback 200, LAN no-creds 401, LAN+creds 200. 10 tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 16:27:15 +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
6d5ef51c60 fix(server): api_upload load_env_file en setdefault (env systemd prime sur .env.local)
Some checks failed
tests / Lint (ruff + black) (push) Failing after 1m47s
tests / Tests unitaires (sans GPU) (push) Failing after 1m49s
tests / Tests sécurité (critique) (push) Has been skipped
.env.local etait charge avec override systematique, ecrasant RPA_BIND_HOST
defini par le service systemd -> upload API bindait 0.0.0.0 malgre le drop-in.
setdefault aligne sur la convention dotenv (override=False) : l'env explicite
du service prime, .env.local ne fournit que des defauts. Complete d0c794d92.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 20:34:43 +02:00
Dom
d0c794d923 fix(systemd): bind upload api to loopback
Some checks failed
tests / Lint (ruff + black) (push) Failing after 1m47s
tests / Tests unitaires (sans GPU) (push) Failing after 1m56s
tests / Tests sécurité (critique) (push) Has been skipped
2026-06-17 20:01:27 +02:00
Dom
9605cc9d95 fix(vwb): resolve frontend services from runtime host
Some checks failed
tests / Lint (ruff + black) (push) Failing after 1m46s
tests / Tests unitaires (sans GPU) (push) Failing after 1m50s
tests / Tests sécurité (critique) (push) Has been skipped
2026-06-17 17:53:57 +02:00
Dom
667575c3ad feat(installer): make Lea autonomous for POC 2026-06-17 17:53:46 +02:00
Dom
787dbfb0eb fix(installer): configure_embed saute pip si deps deja embarquees (install offline)
Some checks failed
tests / Lint (ruff + black) (push) Failing after 1m45s
tests / Tests unitaires (sans GPU) (push) Failing after 1m50s
tests / Tests sécurité (critique) (push) Has been skipped
Quand l'embed est livre complet (socketio + tkinter pre-embarques),
le bootstrap get-pip.py + pip install echouait hors-ligne. Ajout d'un
guard : si 'import socketio, tkinter' OK -> on saute pip (offline).
Mode online legacy conserve si embed nu.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 18:16:04 +02:00
Dom
86b5ec18c6 chore(installer): prep Lea-Setup-v1.0.1 — socketio dans requirements + exclusion fichiers test du staging
Some checks failed
tests / Lint (ruff + black) (push) Failing after 1m43s
tests / Tests unitaires (sans GPU) (push) Failing after 1m47s
tests / Tests sécurité (critique) (push) Has been skipped
- requirements_agent.txt : ajout python-socketio/engineio/websocket-client/simple-websocket
  (FeedbackBus/bulles ; jeu valide en runtime sur la VM)
- build_installer.sh : exclusion test_lea_*, _test_paused_toast.py, tools/test_* du staging
Reste (phase build sur .11) : pre-bundler tkinter+zlib1 dans l'embed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 17:52:49 +02:00
Dom
b8b963059e fix(vwb): import lit anchor_image_base64 dans target.context_hints
Some checks failed
tests / Lint (ruff + black) (push) Failing after 1m44s
tests / Tests unitaires (sans GPU) (push) Failing after 1m47s
tests / Tests sécurité (critique) (push) Has been skipped
Le converter convert_learned_to_vwb_steps ne lisait l'ancre que dans
target/screenshot/action.parameters, jamais dans target.context_hints
où le recorder la range réellement -> anchor_id NULL a l'import.
Ajout de la source context_hints (fallback or, additif, non regressif).
Preuve: import reel 'Explorateur — session' -> 4/5 steps anchor_id non NULL
+ 4 PNG, x_pct/y_pct preserves.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 17:42:03 +02:00
Dom
2b1743c206 fix(poc-agent): ouvrir le chat Lea DGX si Tk est indisponible
Some checks failed
tests / Lint (ruff + black) (push) Failing after 1m43s
tests / Tests unitaires (sans GPU) (push) Failing after 1m46s
tests / Tests sécurité (critique) (push) Has been skipped
2026-06-15 21:32:54 +02:00
Dom
48879fb849 fix(vwb): conservation des données de position des anchors Lea lors de l'import
- Supprime le 'pop' de '_anchor_bbox' qui jetait les coordonnées de position (x_pct, y_pct).
- Conserve ces données dans les paramètres du step pour que le frontend puisse les utiliser pour afficher la zone ciblée.
- Évite la création d'une bounding box factice (écran entier) qui rendait le crop de l'ancre inutile.
- Impact isolé à la route d'import, aucun impact sur le runtime d'exécution de Léa ni sur DETTE-015.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-06-15 18:13:29 +02:00
Dom
c12fd8e1c1 fix(dashboard): VWB import URL dynamique pour éviter hardcoded localhost
- Remplace l'URL hardcodée 'http://localhost:5002' par une construction dynamique basée sur l'origine actuelle.
- Permet les tests d'import depuis la VM ou le poste de test via l'IP du banc (ex: 192.168.1.45) sans échec CORS/routage.
- Respecte la règle POC DGX : pas de localhost comme preuve produit.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-06-15 18:13:22 +02:00
Dom
cbd3d40e39 fix(poc-installer): rendre l'installateur Lea embedded fonctionnel
Some checks failed
tests / Lint (ruff + black) (push) Failing after 1m47s
tests / Tests unitaires (sans GPU) (push) Failing after 1m50s
tests / Tests sécurité (critique) (push) Has been skipped
Lea.iss (Inno Setup) n'avait jamais compile. Corrections :
- StringChange utilise en in-place (procedure modifiant la variable, retour
  Integer) au lieu d'imbrique/assigne (l.246, 407-408)
- GetTickCount (absent du Pascal Script Inno) -> GetDateTimeString pour le
  fallback machine_id
- skipifsilent retire du [Run] configure_embed : le runtime python-embed est
  desormais configure aussi en installation silencieuse (cas POC)

.gitignore : artefacts de build installateur non versionnes
(python-3.12-embed/, releases/*.exe, build/).

Valide sur VM Win11 : install per-user sans Python systeme, config DGX
(RPA_SERVER_URL=http://192.168.1.45:5005/api/v1), python-embed 3.12.8 + deps OK.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 17:14:08 +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
c0e4c382be docs(dette): acte DETTE-018/019 (garde-seuil grounding) + inscrit DETTE-015..017
Some checks failed
tests / Lint (ruff + black) (push) Failing after 1m45s
tests / Tests unitaires (sans GPU) (push) Failing after 1m51s
tests / Tests sécurité (critique) (push) Has been skipped
DETTE-018: method="grounding_vlm" legacy non gardé par _RESOLUTION_MIN_SCORES
(seul prefixe memory_ traité ; reste = match exact) → Check-1 seuil jamais appliqué
au chemin legacy. Mode qwen3vl ("grounding", seuil 0.60) correctement gardé.
DETTE-019: confiance figée 0.85 en dur dans _resolve_by_grounding (return) pour les
deux modes → garde-seuil (0.60) reçoit toujours 0.85, filtre inopérant.
Découvertes au câblage qwen3vl (5c5ce747b) + validation E2E 2026-06-13 (15/15, 0 dangereux).
Inscrit aussi DETTE-015/016/017 restées non commitées.

refs DETTE-018 DETTE-019

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 09:33:58 +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
09f65cecbe fix(security): bind 127.0.0.1 par défaut via RPA_BIND_HOST (plus de host=0.0.0.0 en dur)
Some checks failed
tests / Lint (ruff + black) (push) Failing after 1m44s
tests / Tests unitaires (sans GPU) (push) Failing after 1m48s
tests / Tests sécurité (critique) (push) Has been skipped
Les 4 entrypoints HTTP (api_stream 5005, api_upload 8000, VWB backend 5002,
dashboard 5001) bindaient host=0.0.0.0 en dur -> exposés sur tout le réseau.
Désormais host=os.environ.get('RPA_BIND_HOST','127.0.0.1') : local-only par
défaut, configurable. Découvert à la mise en service DGX local-only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 17:49:58 +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
4e7c2a7628 docs(coordination): dispatch dgx vlm model cleanup 2026-06-02 18:16:55 +02:00
Dom
3697e3ba0e docs(coordination): record p11 option a decision 2026-06-02 17:46:22 +02:00
Dom
5289f3de48 feat(p11): learn from offline cross-session matches 2026-06-02 17:46:15 +02:00
Dom
4b3d5ce0d7 chore(gitignore): ignore local agent and runtime artifacts 2026-06-02 16:31:09 +02:00
Dom
9b8bdfdbbe docs(coordination): sync agent inboxes and active decisions 2026-06-02 16:30:14 +02:00
Dom
f2e9aac6b7 docs: add POC specs, handoffs, and research notes 2026-06-02 16:28:34 +02:00
Dom
18ed6cb751 feat(vwb): add dashboard competence testing and health tools 2026-06-02 16:27:19 +02:00