gradatum-vault 0.4.3

Multi-vault registry + lifecycle (create/list/swap/delete) + forward-compat
Documentation
//! Détection de drift entre l'index SQLite et les fichiers `.md` sur disque.
//!
//! Délègue à `gradatum-index::drift::scan_phase_a`.
//!
//! ## Scan Phase A
//!
//! - Vérifie les entrées `file_checksums` : size + prefix-4KB, puis SHA-256 complet.
//! - Retourne un `DriftScanResult` avec compteurs et liste des fichiers manquants.
//!
//! ## Détection des fichiers non trackés (Phase B)
//!
//! Walk filesystem pour les `.md` absents de `file_checksums` + reconstruction
//! (re-parse + re-index + `AuditEvent::DriftFixed`) sont différés.

use gradatum_core::error::GradatumError;
use gradatum_index::drift::{scan_phase_a, DriftScanResult};

use crate::registry::Vault;

impl Vault {
    /// Déclenche un scan de drift Phase A sur l'ensemble du vault.
    ///
    /// ## Algorithme Phase A (3 niveaux)
    ///
    /// Pour chaque entrée dans la table `file_checksums` :
    /// 1. **Size + prefix-4KB** : si identiques → court-circuit (fichier probablement inchangé).
    /// 2. **Full SHA-256** : hash complet si size/prefix diffèrent.
    ///    - Match → `level3_full_hash_match` (modification cosmétique).
    ///    - Mismatch → `level3_full_hash_mismatch` (drift confirmé, reconstruction requise).
    ///
    /// Les fichiers absents sur disque sont collectés dans `DriftScanResult::missing`.
    ///
    /// ## OpenDAL data path
    ///
    /// `scan_phase_a` reçoit `&self.storage` (FileStorage OpenDAL) — les I/O drift
    /// passent par l'abstraction Storage.
    ///
    /// ## Phase B / Phase C
    ///
    /// La détection des fichiers "untracked" (présents sur disque, absents de `file_checksums`)
    /// et la reconstruction (re-parse + re-index) sont différées.
    ///
    /// ## Erreurs
    ///
    /// - `GradatumError::Storage` si la lecture des checksums depuis SQLite échoue.
    /// - `GradatumError::Storage` si la lecture d'un fichier existant échoue (permissions, etc.).
    pub async fn drift_check(&self) -> Result<DriftScanResult, GradatumError> {
        scan_phase_a(&self.storage, &self.index).await
    }
}