feat: replay E2E fonctionnel — 25/25 actions, 0 retries, SomEngine via serveur

Validé sur PC Windows (DESKTOP-58D5CAC, 2560x1600) :
- 8 clics résolus visuellement (1 anchor_template, 1 som_text_match, 6 som_vlm)
- Score moyen 0.75, temps moyen 1.6s
- Texte tapé correctement (bonjour, test word, date, email)
- 0 retries, 2 actions non vérifiées (OK)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dom
2026-03-31 14:04:41 +02:00
parent 5e0b53cfd1
commit a7de6a488b
79542 changed files with 6091757 additions and 1 deletions

View File

@@ -0,0 +1,410 @@
# Design Document - FAISS Rebuild Propre
**Auteur :** Dom, Alice Kiro - 22 décembre 2025
## Overview
Le système FAISS Rebuild Propre résout le problème de pollution d'index causé par l'accumulation de vecteurs obsolètes lors des mises à jour de prototypes. La stratégie adoptée est simple et sûre : **clear + reindex complet** depuis les derniers prototypes validés.
## Architecture
### Composants Principaux
```
┌─────────────────────────────────────────────────────────────┐
│ FAISS Rebuild Propre │
├─────────────────────────────────────────────────────────────┤
│ │
│ FAISSManager Enhanced ←→ WorkflowPipeline Enhanced │
│ ✅ clear() amélioré ✅ _extract_node_vector() │
│ ✅ reindex() nouveau ✅ _index_workflow_embeddings │
│ │
│ Test Suite ←→ Trigger Logic │
│ ✅ test_faiss_reindex.py ✅ Post-validation trigger │
│ ✅ Batch session trigger │
│ │
└─────────────────────────────────────────────────────────────┘
```
## Components and Interfaces
### 1. FAISSManager Enhanced
#### Interface Améliorée
```python
class FAISSManager:
def clear(self) -> None:
"""Vider complètement l'index + reset état d'entraînement."""
def reindex(self, items: Iterable[Tuple[str, np.ndarray, dict]],
force_train_ivf: bool = True) -> int:
"""Reconstruit l'index à partir d'une source canonique."""
def _create_index(self) -> faiss.Index:
"""Créer un nouvel index selon la configuration."""
```
#### Méthode clear() Améliorée
```python
def clear(self) -> None:
"""Vider complètement l'index + reset état d'entraînement."""
self.index = self._create_index()
self.metadata_store.clear()
self.next_id = 0
# IMPORTANT: reset IVF training state
self.training_vectors.clear()
self.is_trained = (self.index_type == "Flat")
```
**Améliorations :**
- Reset complet de l'état IVF training
- Réinitialisation des training_vectors
- Gestion correcte du flag is_trained selon le type d'index
#### Méthode reindex() Nouvelle
```python
def reindex(self, items: Iterable[Tuple[str, np.ndarray, dict]],
force_train_ivf: bool = True) -> int:
"""
Reconstruit l'index à partir d'une source canonique (vecteurs).
items: Iterable[(embedding_id: str, vector: np.ndarray, metadata: dict)]
"""
self.clear()
count = 0
for embedding_id, vector, metadata in items:
if vector is None:
continue
self.add_embedding(embedding_id, vector, metadata or {})
count += 1
# Si IVF + petit volume, add_embedding ne déclenche pas forcément l'entraînement
if (self.index_type == "IVF" and force_train_ivf and
(not self.is_trained) and self.training_vectors):
self._train_ivf_index()
return count
```
**Fonctionnalités :**
- Clear complet avant reconstruction
- Ajout sécurisé avec validation des vecteurs
- Force training IVF même pour petits volumes
- Retour du nombre d'éléments indexés
### 2. WorkflowPipeline Enhanced
#### Extraction de Vecteurs Multi-Version
```python
def _extract_node_vector(self, node) -> Optional[np.ndarray]:
"""
Récupérer le prototype vecteur d'un node, compatible avec plusieurs versions de modèle.
Retourne np.ndarray ou None.
"""
import numpy as np
# v1: prototype stocké en liste directement
tpl = getattr(node, "template", None)
if tpl is not None:
proto_list = getattr(tpl, "embedding_prototype", None)
if isinstance(proto_list, list):
v = np.array(proto_list, dtype=np.float32)
return v
# v2: prototype stocké sur disque via EmbeddingPrototype.vector_id
emb = getattr(tpl, "embedding", None)
if emb is not None:
vector_id = getattr(emb, "vector_id", None)
if vector_id:
try:
return np.load(vector_id).astype(np.float32)
except Exception:
return None
# fallback (ancienne nomenclature)
st = getattr(node, "screen_template", None)
if st is not None:
p = getattr(st, "embedding_prototype_path", None)
if p:
try:
return np.load(p).astype(np.float32)
except Exception:
return None
return None
```
**Support Multi-Version :**
- v1: embedding_prototype en liste directe
- v2: embedding.vector_id avec fichier sur disque
- Fallback: screen_template legacy
- Gestion robuste des erreurs
#### Indexation Workflow Améliorée
```python
def _index_workflow_embeddings(self, workflow: Workflow) -> None:
"""
Indexer les embeddings des nodes dans FAISS (rebuild propre).
"""
if not self.faiss_manager:
return
items = []
for node in workflow.nodes:
vec = self._extract_node_vector(node)
if vec is None:
continue
items.append((
node.node_id,
vec,
{
"workflow_id": workflow.workflow_id,
"node_id": node.node_id,
"node_name": getattr(node, "name", "")
}
))
n = self.faiss_manager.reindex(items, force_train_ivf=True)
logger.info(f"FAISS reindexed: {n} node prototypes (workflow={workflow.workflow_id})")
```
**Avantages :**
- Construction de liste canonique avant reindex
- Métadonnées enrichies (workflow_id, node_id, node_name)
- Force training IVF pour cohérence
- Logging informatif
## Data Models
### Item de Reindex
```python
@dataclass
class ReindexItem:
embedding_id: str
vector: np.ndarray
metadata: Dict[str, Any]
def __post_init__(self):
if self.vector is not None:
self.vector = self.vector.astype(np.float32)
```
### Résultat de Reindex
```python
@dataclass
class ReindexResult:
success: bool
items_processed: int
items_skipped: int
training_performed: bool
duration_ms: float
error_message: Optional[str] = None
```
## Correctness Properties
*Une propriété est une caractéristique ou un comportement qui doit être vrai pour toutes les exécutions valides d'un système - essentiellement, une déclaration formelle sur ce que le système devrait faire.*
### Property 1: Clear Operation Completeness
*Pour tout* FAISSManager, après un appel à clear(), l'index doit être vide (ntotal=0), les métadonnées vides, next_id remis à 0, training_vectors vidé, et is_trained défini selon le type d'index
**Validates: Requirements 1.2, 1.3, 1.4, 1.5**
### Property 2: Embedding Removal Completeness
*Pour tout* embedding ajouté puis supprimé via remove_embedding(), ni les métadonnées ni le vecteur ne doivent être présents dans l'index
**Validates: Requirements 1.1**
### Property 3: Reindex Consistency
*Pour tout* ensemble d'items valides, reindex() doit produire un index contenant exactement ces items, sans doublons ni éléments manquants, et retourner le bon nombre d'items traités
**Validates: Requirements 2.1, 2.2, 2.4**
### Property 4: Invalid Vector Handling
*Pour tout* ensemble d'items contenant des vecteurs invalides (None), reindex() doit les ignorer et continuer le traitement des vecteurs valides
**Validates: Requirements 2.5**
### Property 5: IVF Training Consistency
*Pour tout* reindex avec force_train_ivf=True sur un index IVF contenant des vecteurs, l'index résultant doit être dans l'état is_trained=True
**Validates: Requirements 2.3**
### Property 6: Vector Extraction Multi-Format
*Pour tout* node contenant un vecteur prototype dans n'importe quel format supporté (template.embedding_prototype, embedding.vector_id, ou screen_template legacy), _extract_node_vector() doit retourner un np.ndarray de type float32
**Validates: Requirements 3.1, 3.2, 3.3, 3.4**
### Property 7: Vector Extraction Graceful Failure
*Pour tout* node sans vecteur prototype valide, _extract_node_vector() doit retourner None sans lever d'exception
**Validates: Requirements 3.5**
### Property 8: Workflow Indexing Completeness
*Pour tout* workflow contenant des nodes avec vecteurs valides, _index_workflow_embeddings() doit extraire tous les vecteurs valides et les indexer avec les métadonnées appropriées (workflow_id, node_id)
**Validates: Requirements 4.1, 4.2**
### Property 9: IVF Training Force in Pipeline
*Pour tout* workflow indexé avec un FAISSManager IVF, le système doit forcer l'entraînement IVF pour assurer la cohérence
**Validates: Requirements 4.3**
### Property 10: Trigger Logic Validation
*Pour tout* prototype mis à jour avec post-conditions OK, le système doit déclencher un rebuild FAISS
**Validates: Requirements 5.1**
### Property 11: Batch Session Trigger
*Pour toute* session d'apprentissage par batch qui se termine, le système doit déclencher un rebuild FAISS
**Validates: Requirements 5.2**
### Property 12: Frame Update Restraint
*Pour toute* série de mises à jour de frames, le système ne doit pas déclencher de rebuild à chaque frame
**Validates: Requirements 5.3**
### Property 13: Rebuild Failure Resilience
*Pour tout* échec de rebuild, le système doit maintenir l'index existant dans un état valide sans corruption
**Validates: Requirements 5.5**
### Property 14: Flat Index Reindex Cleanup
*Pour tout* index Flat, après reindex avec de nouveaux items, les anciens items doivent être complètement supprimés
**Validates: Requirements 6.1**
### Property 15: IVF Small Dataset Training
*Pour tout* index IVF, même avec un petit dataset, reindex() avec force_train_ivf=True doit déclencher l'entraînement
**Validates: Requirements 6.2**
### Property 16: Metadata Consistency After Reindex
*Pour tout* reindex, les métadonnées de chaque item doivent être préservées et cohérentes après l'opération
**Validates: Requirements 6.3**
### Property 17: Search Accuracy After Reindex
*Pour tout* reindex suivi d'une recherche, les résultats doivent être corrects et correspondre aux vecteurs indexés
**Validates: Requirements 6.4**
### Property 18: Index State Validation
*Pour tout* reindex, l'état de l'index (ntotal, is_trained) doit être cohérent avec le contenu effectivement indexé
**Validates: Requirements 6.5**
## Error Handling
### Stratégies de Gestion d'Erreurs
1. **Vector Loading Errors**
- Try/catch sur np.load() avec fallback gracieux
- Log warning pour vecteurs non chargeables
- Continue processing avec autres vecteurs
2. **FAISS Training Errors**
- Validation du nombre minimum de vecteurs pour IVF
- Retry avec paramètres ajustés si échec
- Fallback vers index Flat si IVF impossible
3. **Memory Errors**
- Monitoring de l'utilisation mémoire pendant reindex
- Batch processing pour gros volumes
- Cleanup automatique en cas d'échec
### Logging Strategy
```python
# Niveaux de logging
logger.info(f"FAISS reindex started: {len(items)} items")
logger.debug(f"Processing item {embedding_id}: vector shape {vector.shape}")
logger.warning(f"Skipped invalid vector for {embedding_id}")
logger.error(f"FAISS reindex failed: {error}")
logger.info(f"FAISS reindex completed: {count} items in {duration}ms")
```
## Testing Strategy
### Tests Unitaires
1. **test_faiss_clear_resets_state**
- Valide reset complet après clear()
- Vérifie état IVF training
2. **test_faiss_reindex_flat_removes_old_entries**
- Valide suppression des anciens vecteurs
- Vérifie cohérence métadonnées
3. **test_faiss_reindex_ivf_trains_even_small**
- Valide training forcé sur petits datasets
- Vérifie état is_trained
4. **test_extract_node_vector_multi_version**
- Teste support des différents formats
- Valide fallback gracieux
### Tests d'Intégration
1. **test_workflow_pipeline_reindex_integration**
- Test complet pipeline → FAISS
- Validation end-to-end
2. **test_reindex_performance_large_dataset**
- Test performance sur gros volumes
- Validation mémoire
### Tests de Propriétés
Chaque propriété de correctness sera implémentée comme un test property-based avec minimum 100 itérations.
## Trigger Logic
### Moments de Déclenchement
1. **Post-Validation Trigger**
```python
# Après mise à jour de prototype validée
if post_conditions_ok and prototype_updated:
self.trigger_faiss_rebuild()
```
2. **Batch Session Trigger**
```python
# À la fin d'une session d'apprentissage
def end_learning_session(self):
self.trigger_faiss_rebuild()
self.save_session_metrics()
```
3. **Manual Trigger**
```python
# Commande administrative
def admin_rebuild_faiss(self):
return self.faiss_manager.reindex(self.get_all_prototypes())
```
### Éviter les Triggers Excessifs
- **PAS** de rebuild à chaque frame
- **PAS** de rebuild sur échecs temporaires
- **OUI** rebuild après validation réussie
- **OUI** rebuild en fin de batch
## Performance Considerations
### Optimisations
1. **Batch Processing**
- Grouper les updates avant rebuild
- Éviter les rebuilds fréquents
2. **Memory Management**
- Clear explicite des anciens vecteurs
- Monitoring utilisation mémoire
3. **IVF Training**
- Force training même petits volumes
- Paramètres optimisés par défaut
### Métriques
- Temps de rebuild par nombre de vecteurs
- Utilisation mémoire pendant rebuild
- Taux de réussite des training IVF
- Fréquence des rebuilds déclenchés
## Conclusion
Le système FAISS Rebuild Propre garantit la cohérence et la propreté de l'index FAISS en éliminant la pollution par vecteurs obsolètes. L'approche "clear + reindex complet" est simple, sûre et efficace pour maintenir la qualité de l'apprentissage du système RPA Vision V3.

View File

@@ -0,0 +1,89 @@
# Requirements Document - FAISS Rebuild Propre
**Auteur :** Dom, Alice Kiro - 22 décembre 2025
## Introduction
Le système FAISS Rebuild Propre permet de maintenir un index FAISS propre et cohérent en éliminant la pollution causée par l'accumulation de vecteurs obsolètes lors des mises à jour de prototypes d'apprentissage.
## Glossary
- **FAISS_Manager** : Gestionnaire d'index FAISS pour la recherche de similarité
- **Prototype** : Vecteur représentatif d'un état d'écran ou d'un node de workflow
- **Index_Pollution** : Accumulation de vecteurs obsolètes dans l'index FAISS
- **Reindex** : Reconstruction complète de l'index depuis une source canonique
- **IVF_Training** : Entraînement des index FAISS de type Inverted File
## Requirements
### Requirement 1
**User Story:** En tant que système d'apprentissage, je veux nettoyer l'index FAISS, afin d'éliminer les vecteurs obsolètes et maintenir la cohérence.
#### Acceptance Criteria
1. WHEN remove_embedding() is called THEN THE FAISS_Manager SHALL remove both metadata and vector from index
2. WHEN clear() is called THEN THE FAISS_Manager SHALL reset IVF training state completely
3. THE FAISS_Manager SHALL maintain next_id counter consistency after clear operations
4. WHEN clearing IVF index THEN THE FAISS_Manager SHALL reset training_vectors collection
5. THE FAISS_Manager SHALL set is_trained flag appropriately based on index type after clear
### Requirement 2
**User Story:** En tant que système d'apprentissage, je veux reconstruire l'index FAISS depuis une source canonique, afin de garantir que l'index reflète exactement les prototypes actuels.
#### Acceptance Criteria
1. WHEN reindex() is called with prototype items THEN THE FAISS_Manager SHALL clear existing index completely
2. WHEN reindex() processes items THEN THE FAISS_Manager SHALL add each valid vector with metadata
3. WHEN reindex() completes with IVF index THEN THE FAISS_Manager SHALL force training if requested
4. THE FAISS_Manager SHALL return count of successfully indexed items
5. WHEN reindex() encounters invalid vectors THEN THE FAISS_Manager SHALL skip them and continue processing
### Requirement 3
**User Story:** En tant que pipeline de workflow, je veux extraire les vecteurs prototypes des nodes, afin de supporter différentes versions de modèles de données.
#### Acceptance Criteria
1. WHEN extracting node vector THEN THE System SHALL check template.embedding_prototype list format
2. WHEN template.embedding_prototype is unavailable THEN THE System SHALL check embedding.vector_id path
3. WHEN vector_id path exists THEN THE System SHALL load numpy array from disk
4. WHEN legacy screen_template exists THEN THE System SHALL check embedding_prototype_path
5. WHEN no valid vector found THEN THE System SHALL return None gracefully
### Requirement 4
**User Story:** En tant que pipeline de workflow, je veux reconstruire l'index FAISS avec les prototypes actuels, afin d'éliminer les doublons et maintenir la cohérence.
#### Acceptance Criteria
1. WHEN indexing workflow embeddings THEN THE System SHALL extract all valid node vectors
2. WHEN building items list THEN THE System SHALL include workflow_id and node_id in metadata
3. WHEN calling reindex THEN THE System SHALL force IVF training for consistency
4. THE System SHALL log count of reindexed prototypes with workflow information
5. WHEN no valid vectors found THEN THE System SHALL handle empty reindex gracefully
### Requirement 5
**User Story:** En tant qu'administrateur système, je veux déclencher le rebuild FAISS au bon moment, afin d'optimiser les performances sans impact négatif.
#### Acceptance Criteria
1. WHEN prototype update is validated with post-conditions OK THEN THE System SHALL trigger FAISS rebuild
2. WHEN batch learning session completes THEN THE System SHALL trigger FAISS rebuild
3. THE System SHALL NOT trigger rebuild on every frame update
4. WHEN rebuild is triggered THEN THE System SHALL log rebuild operation with timing
5. THE System SHALL handle rebuild failures gracefully without corrupting existing index
### Requirement 6
**User Story:** En tant que développeur, je veux tester le système de rebuild FAISS, afin de valider le comportement avec différents types d'index.
#### Acceptance Criteria
1. WHEN testing Flat index reindex THEN THE System SHALL remove old entries completely
2. WHEN testing IVF index reindex THEN THE System SHALL force training even with small datasets
3. THE System SHALL validate metadata consistency after reindex operations
4. WHEN querying after reindex THEN THE System SHALL return correct top results
5. THE System SHALL validate index state (ntotal, is_trained) after reindex operations

View File

@@ -0,0 +1,179 @@
# Implementation Plan: FAISS Rebuild Propre
**Auteur :** Dom, Alice Kiro - 22 décembre 2025
## Overview
Implémentation du système FAISS Rebuild Propre pour éliminer la pollution d'index et maintenir la cohérence des prototypes d'apprentissage. L'approche est "clear + reindex complet" depuis une source canonique.
## Tasks
- [x] 1. Améliorer FAISSManager.clear() pour reset complet de l'état IVF ✅
- Modifier `core/embedding/faiss_manager.py`
- Ajouter reset de `training_vectors.clear()`
- Définir `is_trained` selon le type d'index (Flat=True, IVF=False)
- Reset `next_id` à 0
- _Requirements: 1.2, 1.3, 1.4, 1.5_
- **FAIT:** Méthode clear() améliorée avec reset complet IVF training state
- [ ]* 1.1 Écrire test property pour clear() reset complet
- **Property 1: Clear Operation Completeness**
- **Validates: Requirements 1.2, 1.3, 1.4, 1.5**
- [x] 2. Implémenter FAISSManager.reindex() pour reconstruction propre ✅
- [x] 2.1 Créer méthode `reindex(items, force_train_ivf=True)`
- Appeler `self.clear()` au début
- Itérer sur items et appeler `add_embedding()` pour chaque vecteur valide
- Compter les items traités
- _Requirements: 2.1, 2.2, 2.4, 2.5_
- **FAIT:** Méthode reindex() implémentée avec clear + add_embedding
- [x] 2.2 Ajouter force training IVF pour petits volumes ✅
- Vérifier si `index_type == "IVF"` et `force_train_ivf == True`
- Appeler `_train_ivf_index()` si `not is_trained` et `training_vectors` non vide
- _Requirements: 2.3_
- **FAIT:** Force training IVF implémenté
- [x] 2.3 Retourner le nombre d'items indexés ✅
- Return `count` à la fin de la méthode
- _Requirements: 2.4_
- **FAIT:** Retour du count d'items indexés
- [ ]* 2.4 Écrire tests property pour reindex()
- **Property 3: Reindex Consistency**
- **Property 4: Invalid Vector Handling**
- **Property 5: IVF Training Consistency**
- **Validates: Requirements 2.1, 2.2, 2.3, 2.4, 2.5**
- [x] 3. Implémenter extraction de vecteurs multi-version dans WorkflowPipeline ✅
- [x] 3.1 Créer méthode `_extract_node_vector(node)`
- Vérifier `template.embedding_prototype` (liste)
- Fallback vers `embedding.vector_id` (fichier)
- Fallback vers `screen_template.embedding_prototype_path` (legacy)
- Retourner None si aucun vecteur trouvé
- Gérer exceptions avec try/catch
- _Requirements: 3.1, 3.2, 3.3, 3.4, 3.5_
- **FAIT:** Méthode _extract_node_vector() avec support multi-version
- [ ]* 3.2 Écrire tests property pour extraction multi-version
- **Property 6: Vector Extraction Multi-Format**
- **Property 7: Vector Extraction Graceful Failure**
- **Validates: Requirements 3.1, 3.2, 3.3, 3.4, 3.5**
- [x] 4. Refactoriser WorkflowPipeline._index_workflow_embeddings() ✅
- [x] 4.1 Construire liste canonique d'items ✅
- Itérer sur `workflow.nodes`
- Appeler `_extract_node_vector()` pour chaque node
- Construire tuple `(node_id, vector, metadata)` avec workflow_id et node_id
- _Requirements: 4.1, 4.2_
- **FAIT:** Construction liste canonique avec métadonnées enrichies
- [x] 4.2 Appeler reindex() avec force_train_ivf=True ✅
- `n = self.faiss_manager.reindex(items, force_train_ivf=True)`
- Logger le nombre d'items indexés avec workflow_id
- _Requirements: 4.3, 4.4_
- **FAIT:** Appel reindex() avec force training IVF
- [x] 4.3 Gérer cas où aucun vecteur valide trouvé ✅
- Vérifier si `items` est vide
- Logger warning approprié
- _Requirements: 4.5_
- **FAIT:** Gestion gracieuse des cas sans vecteurs
- [ ]* 4.4 Écrire tests property pour indexation workflow
- **Property 8: Workflow Indexing Completeness**
- **Property 9: IVF Training Force in Pipeline**
- **Validates: Requirements 4.1, 4.2, 4.3**
- [ ] 5. Checkpoint - Valider fonctionnalités de base
- Exécuter tous les tests unitaires et property
- Vérifier que clear() et reindex() fonctionnent correctement
- Valider extraction multi-version
- Demander feedback utilisateur si questions
- [ ] 6. Implémenter logique de déclenchement de rebuild
- [ ] 6.1 Ajouter trigger après validation de prototype
- Dans le code de validation post-conditions
- Appeler `trigger_faiss_rebuild()` si `post_conditions_ok and prototype_updated`
- _Requirements: 5.1_
- [ ] 6.2 Ajouter trigger en fin de session batch
- Dans `end_learning_session()`
- Appeler `trigger_faiss_rebuild()`
- _Requirements: 5.2_
- [ ] 6.3 Implémenter protection contre triggers excessifs
- Ajouter flag `_rebuild_pending` pour éviter rebuilds multiples
- Ne pas trigger sur chaque frame update
- _Requirements: 5.3_
- [ ] 6.4 Ajouter logging des opérations de rebuild
- Logger début de rebuild avec timestamp
- Logger fin de rebuild avec durée et nombre d'items
- _Requirements: 5.4_
- [ ] 6.5 Gérer échecs de rebuild gracieusement
- Try/catch autour de reindex()
- Maintenir index existant en cas d'échec
- Logger erreur avec détails
- _Requirements: 5.5_
- [ ]* 6.6 Écrire tests property pour trigger logic
- **Property 10: Trigger Logic Validation**
- **Property 11: Batch Session Trigger**
- **Property 12: Frame Update Restraint**
- **Property 13: Rebuild Failure Resilience**
- **Validates: Requirements 5.1, 5.2, 5.3, 5.5**
- [x] 7. Créer suite de tests complète ✅
- [x] 7.1 Créer `tests/unit/test_faiss_reindex.py`
- Test `test_faiss_clear_resets_state()`
- Test `test_faiss_reindex_flat_removes_old_entries()`
- Test `test_faiss_reindex_ivf_trains_even_small()`
- Test `test_extract_node_vector_multi_version()`
- _Requirements: 6.1, 6.2, 6.3, 6.4, 6.5_
- **FAIT:** Suite de tests unitaires complète créée
- [ ]* 7.2 Écrire tests property pour validation complète
- **Property 14: Flat Index Reindex Cleanup**
- **Property 15: IVF Small Dataset Training**
- **Property 16: Metadata Consistency After Reindex**
- **Property 17: Search Accuracy After Reindex**
- **Property 18: Index State Validation**
- **Validates: Requirements 6.1, 6.2, 6.3, 6.4, 6.5**
- [ ]* 7.3 Créer tests d'intégration
- Test `test_workflow_pipeline_reindex_integration()`
- Test `test_reindex_performance_large_dataset()`
- Valider end-to-end avec workflow réel
- [x] 8. Créer script utilitaire rebuild_faiss_simple.py ✅
- Créer script à la racine du projet
- Charger tous les prototypes depuis storage
- Appeler reindex() avec tous les prototypes
- Logger résultats et statistiques
- Ajouter options CLI (--dry-run, --verbose, --index-type)
- **FAIT:** Script utilitaire complet avec options CLI
- [x] 9. Créer documentation utilisateur ✅
- Créer `docs/guides/FAISS_REBUILD_GUIDE.md`
- Documenter quand déclencher un rebuild
- Documenter comment utiliser rebuild_faiss_simple.py
- Ajouter exemples d'utilisation
- Documenter troubleshooting
- **FAIT:** Documentation complète créée
- [ ] 10. Checkpoint Final - Validation complète
- Exécuter tous les tests (unitaires, property, intégration)
- Valider performance sur gros datasets
- Tester script rebuild_faiss_simple.py
- Valider documentation
- Demander validation utilisateur finale
## Notes
- Les tâches marquées avec `*` sont optionnelles et peuvent être sautées pour un MVP plus rapide
- Chaque tâche référence les requirements spécifiques pour la traçabilité
- Les checkpoints assurent une validation incrémentale
- Les tests property valident les propriétés de correctness universelles
- Les tests unitaires valident des exemples spécifiques et cas limites