Files
rpa_vision_v3/docs/CARTO_APPRENTISSAGE_FONDS_COMMUN_2026-06-16.md
Dom 6907ecc82f docs: track design docs, plans, audits, coordination infrastructure, handoffs
- 21 docs/*.md: audits, design notes, deployment plans, checklists, memos
- Coordination: ROLES, runbooks (DGX reboot, Lea live), patches, registre, syntheses, systemd, QG template
- Handoffs: 6 Codex handoff documents + README + template
2026-07-02 13:29:58 +02:00

13 KiB

Cartographie — Chaîne d'apprentissage & mise en commun des connaissances (2026-06-16)

Question Dom : « Comment le savoir appris sur chaque poste est-il mutualisé dans un fonds commun unique partagé par tous les postes, et exploité vers l'autonomie ? » Méthode : graphify (graphe code 58k nodes) + 3 agents Explore + vérif code directe. Cross-checks Codex (pipeline server_v1) & Qwen (fédération/FAISS) en cours — ce doc sera enrichi. ⚠️ Verdicts = état runtime constaté ce jour (poc-dgx @ 2b1743c20), pas la doc d'intention.

TL;DR (réponse directe)

Le « fonds commun → autonomie » est partiellement construit, mais les maillons clés sont soit silotés par machine, soit dormants :

  1. Ce qui EST déjà commun : les compétences YAML (core/competences/) et les embeddings (CLIP→FAISS) — partagés serveur, tous postes.
  2. Ce qui est SILOTÉ par machine (codé en dur) : le stockage workflows/sessions ({machine_id}/) et surtout le cross-session learning qui refuse de matcher entre machines (if workflow_machine != machine_id: continue). C'est l'anti-pattern direct vs la vision.
  3. 🌙 Ce qui est DORMANT : la fédération (core/federation : LearningPack, GlobalFAISSIndex) — le vrai mécanisme de fonds commun — est bien conçue, globale et anonymisée (Qwen confirmé : zéro machine_id, clé pack_source_hash), mais doublement inerte au runtime : (a) alimentée seulement par l'endpoint import manuel (jamais auto-déclenché) ; (b) son search() n'est JAMAIS appelé (faiss_global.py:199 défini, zéro consommateur actif) → index write-only, jamais consulté → contribue zéro au comportement/à l'autonomie aujourd'hui.
  4. 🚧 Ce qui manque pour l'autonomie : la couche graphe (WorkflowGraph) EST construite en live (finalize_sessionGraphBuilder, import lazy stream_processor.py:3017-3022, DBSCAN) — correction d'un faux "orphelin"mais le graphe est siloté par machine (persisté sous workflows/{machine_id}/) et le merge cross-session est machine-filtré. La progression Shadow→Copilot→Autonomous reste du design, pas du runtime (Shadow observe+log).

⚠️ Caveat méthodo : ce code utilise massivement des imports lazy dans les handlers/méthodes. Les verdicts "orphelin" basés sur grep d'imports top-level sont non fiables (federation ET GraphBuilder étaient ainsi faussement classés orphelins, puis confirmés WIRED). Tout "orphelin" ci-dessous non vérifié par lazy-import est à recontrôler.

→ Aujourd'hui, par défaut, chaque poste est un silo cognitif : il n'apprend pas des autres, sauf pour les compétences YAML et les embeddings centralisés.

Tableau de synthèse (WIRED ? · COMMUN/SILOTÉ)

A. Capture → construction → stockage (agent Explore #1)

Composant fichier:ligne WIRED COMMUN/SILOTÉ
TraceStreamer (tag machine_id) agent_v1/network/streamer.py:91 (main.py:227) tague machine_id sur chaque POST
register/stream/finalize server_v1/api_stream.py:1748/1801/2336 endpoints session taguée machine_id
_persist_workflow server_v1/stream_processor.py:4417 (appelé 3066) SILOTÉ : écrit data/training/workflows/{machine_id}/ + tag _machine_id
Store disque sessions data/training/live_sessions/{machine_id}/ SILOTÉ (arbo 1:1 par machine)
_run_cross_session_learning / _find_best_cross_session_match stream_processor.py:3149 / 3273 (via finalize) SILOTÉ CODÉ : if workflow_machine != machine_id: continue (L3284-3286) → un poste n'apprend jamais d'un autre
Listing list_workflows api_stream.py:2799 + stream_processor.py:4518 BIMODAL : machine_id=None → tous ; sinon filtré
Client list_workflows() lea_ui/server_client.py:228 (smart_tray:802) COMMUN : n'envoie PAS machine_id → reçoit tous
Dashboard list_sessions web_dashboard/app.py:2289 filtre disque par machine_id (optionnel)
Replay ciblage api_stream.py:3064 + replay_engine.py:1559 machine_id = ROUTE l'exécution vers le bon poste (légitime)

B. Apprentissage / cognition / compétences (agent Explore #2)

Module fichier:ligne WIRED COMMUN/SILOTÉ
target_memory_store (mémoire cibles, phase 1) core/learning/target_memory_store.py:77 hot-path resolve_engine.py:1869 SILOTÉ par machine (data/learning/target_memory.db local, sauf RPA_LEARNING_DIR partagé)
continuous_learner core/learning/continuous_learner.py (stream_processor.py:3145) SILOTÉ par session
replay_learner server_v1/replay_learner.py:90 (api_stream.py:2436) SILOTÉ par session
learning_manager (états workflow VWB) core/learning/learning_manager.py:37 singleton VWB COMMUN
Compétences YAML (catalog/replay/persist/verdicts/promotions) core/competences/* endpoints api_stream + dashboard COMMUN (tous lisent data/competences/) — c'est le vrai fonds commun qui marche
observe_reason_act (ORALoop) core/execution/observe_reason_act.py:145 (VWB api_v3/execute.py) siloté par exécution
feedback_processor, versioned_store, core/cognition/*, core/knowledge, core/coaching, core/healing, core/supervision ⚠️ ORPHELINS (tests seuls)

C. Graphe / embeddings / autonomie (agent Explore #3)

Composant fichier:ligne WIRED COMMUN/SILOTÉ
ScreenState (perception) core/pipeline/workflow_pipeline.py serveur COMMUN
StateEmbedding + Builder (fusion 512d) core/models/state_embedding.py:44 / core/embedding/state_embedding_builder.py:25 stream_processor startup COMMUN (vecteurs data/training/embeddings/*.npy centralisés)
CLIP (OpenCLIP ViT-B-32) core/embedding/clip_embedder.py COMMUN
FAISSManager (similarité) core/embedding/faiss_manager.py:40 stream_processor COMMUN serveur mais index per-session en mémoire (pas un index global persistant)
WorkflowGraph builder (couche 4) core/graph/graph_builder.py:148 WIRED (import lazy stream_processor.py:3017, instancié :3022 dans finalize_session, DBSCAN) — corrigé : Agent #3 l'avait dit orphelin à tort SILOTÉ : graphe construit par session, persisté workflows/{machine_id}/ ; merge cross-session machine-filtré
WorkflowNode/Edge (modèles couche 4) core/models/workflow_graph.py:384 utilisés par GraphBuilder siloté (idem)
Shadow observer core/workflow/shadow_observer.py:25 ⚠️ partiel (api_stream:2700 observe + LOG seulement) pas d'apprentissage collectif
Copilot / Autonomous core/learning/learning_engine.py design papier, pas runtime
audit_trail.execution_mode (shadow/assisted/autonomous) server_v1/audit_trail.py:50 enregistré mais pas exploité pour décider

D. Fédération = LE fonds commun par design (vérif directe + Qwen en cours)

Composant fichier:ligne WIRED COMMUN/SILOTÉ
LearningPackExporter core/federation/learning_pack.py 🌙 endpoint manuel GET /api/v1/traces/stream/learning-pack/export (api_stream.py:6278, import lazy L6292) conçu commun
LearningPack + GlobalFAISSIndex core/federation/learning_pack.py:294 / faiss_global.py:51 🌙 endpoint manuel POST .../learning-pack/import (api_stream.py:6323, L6334-6353 GlobalFAISSIndex() ré-instancié) conçu commun
Déclenchement automatique AUCUN : rien dans le flux capture→learn n'appelle export/import → fonds commun dormant

Verdict fédération (Claude + Qwen) :

  • Bien architecturé (Qwen) : LearningPack anonymise (machine_id blacklisté _SENSITIVE_METADATA_KEYS:64, source_hash SHA-256), GlobalFAISSIndex est global (clé pack_source_hash+workflow_skeleton_id+node_name+app_name, aucun machine_id), persistant (.faiss+.meta.json, save/load L245/277). Export prend tous les workflows (processor._workflows.values() L6305) sans filtre machine.
  • Mais doublement inerte : (a) pas d'auto-déclenchement (rien dans capture→learn n'appelle export/import) ; (b) search() jamais appelé_global_faiss_index n'est référencé QU'aux lignes api_stream.py:6351-6372 (instanciation + add_pack à l'import). Aucun chemin de résolution/apprentissage/replay ne lit l'index global. → write-only, jamais consulté : contribue 0 au runtime.

Conclusion : le fonds commun fédéré est codé correctement mais débranché du runtime — c'est exactement le maillon à activer pour la vision.

machine_id cloisonne vs route

  • ROUTE (légitime) : ciblage d'un replay/d'une session vers le bon poste (replay_engine.py:1559, start_replay).
  • CLOISONNE (à corriger vs vision) : (1) dossiers de stockage {machine_id}/ ; (2) filtre dur du cross-session learning (stream_processor.py:3284) ; (3) target_memory.db local par machine. + machine_id instable (nouvel ID à chaque relance) qui fragmente même au sein d'un poste.

Gap vs vision « fonds commun → autonomie » (constats, pas décisions)

Pour réaliser la vision, il manque le câblage de :

  1. Dé-siloter le savoir workflows/sessions : retirer le filtre machine_id du cross-session learning + stockage commun (ou index commun), en gardant machine_id pour le seul routing.
  2. Activer la fédération en continu (auto-export/import ou store partagé) au lieu du manuel dormant — c'est l'endroit conçu pour ça.
  3. Câbler la couche graphe (4) en live (aujourd'hui orpheline) pour un knowledge graph commun.
  4. Implémenter Shadow→Copilot→Autonomous (aujourd'hui observe+log / design) consommant ce fonds commun.
  5. Stabiliser machine_id (persisté) pour ne pas fragmenter.

Ce qui marche DÉJÀ comme fonds commun (à capitaliser)

  • Compétences YAML (core/competences/) : micro-workflows réutilisables, états supervisés, lus par tous les postes. C'est le modèle commun qui fonctionne → piste à étendre.
  • Embeddings centralisés (data/training/embeddings/) : matière première commune déjà là.

E. Pipeline server_v1 (cross-check Codex — intégré)

  • Pipeline WIRED : capture → _worker_queue.txtrun_worker.pyStreamProcessor.reprocess_session() → workflow JSON → replay → apprentissage. api_stream.py importe+instancie ReplayLearner/StreamProcessor/StreamWorker (:32/40/41, :562-563, startup :1626-1629).
  • ReplayLearner = commun mais faiblement effectif : ActionOutcome sans machine_id, stockage global data/learning/replay_results/ ; MAIS query_similar() ne lit que le cache mémoire _recent (:273-304) et build_replay_from_raw_events() crée une nouvelle instance (stream_processor.py:2379-2382) → l'historique JSONL global n'est pas exploité après restart/hors instance globale.
  • Risque ambiguïté : la queue worker ne porte que session_id, pas machine_id (api_stream.py:734-760) → résolution disque ambiguë si 2 machines ont le même session_id.
  • machine_id route légitimement : /replay, /replay/next refusent les actions d'une autre machine (:3978-3982, :4033-4054), _find_active_agent_session filtre machine_id/bg_<machine_id> (replay_engine.py:1559-1588).

Pistes de correction CONVERGENTES (constats Codex+Claude — NON décidées, mapping seulement)

  1. Cantonner machine_id au routing/fleet/replay-target/audit — pas au stockage ni au matching du savoir.
  2. Dé-siloter les workflows appris : sortir du stockage logique workflows/{machine_id}/ (ou neutraliser ce marqueur en lecture/matching).
  3. Retirer/rendre optionnel le filtre machine dans _run_cross_session_learning() / _find_best_cross_session_match() (stream_processor.py:3193-3203, 3283-3286) → apprendre sur tous les workflows compatibles.
  4. Brancher le fonds commun fédéré : (a) alimenter le GlobalFAISSIndex en continu (auto export/import ou store partagé) ; (b) appeler son search() dans le hot-path résolution/apprentissage (aujourd'hui jamais lu).
  5. Rendre ReplayLearner durable : charger/interroger l'historique JSONL global, réutiliser l'instance globale (pas une neuve par session).
  6. Stabiliser machine_id (persisté) pour ne pas fragmenter intra-poste.
  7. Étendre le modèle "compétences communes" (core/competences/, déjà commun + supervisé) comme colonne vertébrale du fonds commun.

Sources : graphify-out (58k nodes) ; agents Explore #1/#2/#3 (⚠ verdicts "orphelin" sur imports top-level corrigés par lazy-import) ; cross-checks Codex (server_v1, msg 16:43) & Qwen (federation/FAISS, msg 16:50) intégrés ; vérifs directes api_stream.py:6271-6372, faiss_global.py:199, stream_processor.py:3017-3022.