# Delta 0.1.2-pre.003-fix.001 ## Base requise Livraison précédente : ```text 0.1.2-pre.003 ``` La base porte : ```text workspace.package.version = "0.1.2-pre.3" Cargo.toml header version = 29 ``` ## Motif du correctif Les validations remontées pour `pre.003` sont : ```text cargo fmt --all OK cargo check --workspace OK cargo clippy --workspace --all-targets OK cargo test --workspace ECHEC ``` Le test d'intégration : ```text global_runtime_supports_takeover_hot_reload_and_single_initialization ``` panique pendant le premier `reinitialize()` activant la console : ```text a `Filtered` layer was used, but it had no `FilterId`; was it registered with the subscriber? ``` ## Cause `pre.003` construisait le sink console sous cette forme conceptuelle : ```text fmt layer .with_filter(Targets) -> Filtered ``` Ce `Filtered` était ensuite boxed dans le `Vec>>` placé derrière `tracing_subscriber::reload::Layer`. Au démarrage sans sink, le `Vec` initial était vide. Le premier hot reload construisait donc un nouveau `Filtered` après l'installation du subscriber global puis remplaçait le `Vec` via `Handle::reload`. Or un per-layer `Filtered` a besoin que son `FilterId` soit enregistré lors de son attachement au subscriber. La documentation de `tracing-subscriber 0.3.23` indique explicitement que `Handle::reload` ne doit pas être utilisé pour remplacer directement un `Filtered`. Le panic n'indique donc pas un défaut du contrat public KSP de hot reload, mais une composition interne incorrecte des layers de `pre.003`. ## Correction Le runtime conserve : ```text reload::Layer>>> ``` mais la composition devient : ```text Vec reloadable ├── Targets global takeover filter └── fmt console layer ``` au lieu de : ```text Vec reloadable └── Filtered ``` `Targets` est utilisé comme layer de filtrage global. Le layer `fmt` n'appelle plus `with_filter`. Conséquences : - aucun nouveau `Filtered` n'est injecté par `Handle::reload` ; - aucun `FilterId` tardif n'est nécessaire ; - le takeover reste global : les targets externes restent `OFF` ; - les niveaux KSP et overrides par préfixe restent inchangés ; - le `Vec` complet peut toujours être remplacé pour activer/désactiver des sinks à chaud ; - l'API publique `initialize` / `reinitialize` / `LoggingGuard` ne change pas ; - `pre.004` peut toujours ajouter le backend fichier au même runtime reloadable. Une configuration sans sink conserve un `Vec` vide, donc le logging reste effectivement désactivé jusqu'à un `reinitialize()` qui ajoute une sortie. ## Tests Le test d'intégration déjà présent qui a révélé la régression reste le test de non-régression principal : ```text global_runtime_supports_takeover_hot_reload_and_single_initialization ``` Un test unitaire supplémentaire vérifie que la console prépare deux layers distincts : le takeover filter global et le formatter. ## Version technique Ce correctif modifie du Rust. Conformément à la règle KSP de signal technique, la version workspace devient : ```text workspace.package.version = "0.1.2-pre.3.fix.1" ``` et l'en-tête du `Cargo.toml` racine devient : ```text # version: 30 ``` ## Fichiers du delta ```text Cargo.toml crates/ksp-logging-lib/src/runtime.rs crates/ksp-logging-lib/unit_tests/runtime.rs docs/plans/004-V0_1_2_LOGGING_FOUNDATION_PLAN.md deltas/0.1.2/pre.003-fix.001.md ``` ## Validations à exécuter ```bash cargo fmt --all cargo check --workspace cargo test --workspace cargo clippy --workspace --all-targets ``` Si ces validations sont propres, la tranche suivante reste : ```text 0.1.2-pre.004 — non-blocking console/file + guards + ANSI + reload sinks ```