v0.1.2-pre.003-fix.001

This commit is contained in:
2026-08-14 18:29:56 +02:00
parent 6e06802e38
commit 488d8ae0a8
5 changed files with 174 additions and 12 deletions

View File

@@ -0,0 +1,144 @@
<!-- file: deltas/0.1.2/pre.003-fix.001.md -->
<!-- version: 1 -->
# 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<fmt, Targets, Registry>
```
Ce `Filtered` était ensuite boxed dans le `Vec<Box<dyn Layer<Registry>>>` 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<Vec<Box<dyn Layer<Registry>>>>
```
mais la composition devient :
```text
Vec reloadable
├── Targets global takeover filter
└── fmt console layer
```
au lieu de :
```text
Vec reloadable
└── Filtered<fmt console layer, Targets>
```
`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
```