Files
khadhroony-solana-project/deltas/0.1.2/pre.003-fix.001.md

3.8 KiB

Delta 0.1.2-pre.003-fix.001

Base requise

Livraison précédente :

0.1.2-pre.003

La base porte :

workspace.package.version = "0.1.2-pre.3"
Cargo.toml header version = 29

Motif du correctif

Les validations remontées pour pre.003 sont :

cargo fmt --all                         OK
cargo check --workspace                OK
cargo clippy --workspace --all-targets OK
cargo test --workspace                 ECHEC

Le test d'intégration :

global_runtime_supports_takeover_hot_reload_and_single_initialization

panique pendant le premier reinitialize() activant la console :

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 :

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 :

reload::Layer<Vec<Box<dyn Layer<Registry>>>>

mais la composition devient :

Vec reloadable
├── Targets global takeover filter
└── fmt console layer

au lieu de :

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 :

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 :

workspace.package.version = "0.1.2-pre.3.fix.1"

et l'en-tête du Cargo.toml racine devient :

# version: 30

Fichiers du delta

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

cargo fmt --all
cargo check --workspace
cargo test --workspace
cargo clippy --workspace --all-targets

Si ces validations sont propres, la tranche suivante reste :

0.1.2-pre.004 — non-blocking console/file + guards + ANSI + reload sinks