# Delta 0.1.3-pre.004 ## Base requise Livraison précédente validée : ```text 0.1.3-pre.003 ``` Version technique de cette base : ```text workspace.package.version = "0.1.3-pre.3" Cargo.toml header version = 43 ``` Validations utilisateur de `pre.003` : ```text cargo fmt --all OK cargo check --workspace OK cargo clippy --workspace --all-targets OK cargo test --workspace OK ``` Les tests Config livrés en `pre.003` réussissent : 21 tests unitaires et 4 tests d'API publique. ## Objet de pre.004 Cette tranche complète uniquement les **contrats/settings publics** de `ksp-logging-lib` nécessaires au futur `config/std.logging.json`. Elle ne livre pas encore le runtime multi-sink complet. Le but est de stabiliser ce que Logging sait représenter avant de figer le schema JSON Config. ## Modèle public ajouté ### `LogFormat` Formats publics représentables : ```text Human Compact Pretty Json ``` L'activation backend de tous ces formats appartient à la tranche runtime suivante. ### `OutputFilter` Chaque sink peut maintenant déclarer un filtre propre contenant : ```text level targets[] domains[] ``` Les selectors `targets` sont des préfixes de targets KSP ou le wildcard `*`. Les selectors `domains` sont des préfixes de domain ou le wildcard `*`. Le wildcard doit être utilisé seul dans sa dimension. Les listes vides, selectors vides, doublons et targets externes à KSP sont refusés par la validation publique. `OutputFilter::unrestricted()` représente l'absence de restriction supplémentaire par rapport au takeover global : ```text level = Trace targets = ["*"] domains = ["*"] ``` ## Console explicite `ConsoleSettings` représente désormais explicitement : ```text enabled output = stdout | stderr ansi format filter ``` Les helpers : ```text ConsoleSettings::stdout() ConsoleSettings::stderr() ``` restent disponibles et produisent un contrat compatible avec le runtime `0.1.2` : console activée, format `Human`, ANSI désactivé et `OutputFilter::unrestricted()`. ## Plusieurs outputs fichier `LoggingSettings` ne contient plus un unique : ```text Option ``` mais : ```text Vec ``` Chaque `FileSettings` porte : ```text output_id enabled directory file_name_prefix rotation format ansi filter ``` `output_id` est une identité Logging stable, unique parmi les fichiers d'un même `LoggingSettings`. Il ne doit pas être confondu avec le `file_id` de `ksp-config-lib` : ```text file_id -> identité d'un document/schema Config output_id -> identité d'une sortie Logging ``` La syntaxe initiale d'un `output_id` accepte l'ASCII minuscule, chiffres, `_`, `-` et des segments séparés par `.` sans segment vide. Exemples : ```text file.debug file.config.error file.ksp-config-lib.error ``` ## ANSI fichier Une sortie persistante avec : ```text ansi = true ``` est refusée par `LoggingSettings::validate()`. Le contrat KSP conserve donc l'invariant qu'un fichier de logs ne persiste pas de séquences ANSI. ## Deux niveaux de filtrage conservés Le nouveau filtre par sink ne remplace pas la politique existante. `LoggingSettings` conserve : ```text default_filter target_filters[] ``` qui définissent le takeover global KSP. Puis chaque console/fichier possède son `OutputFilter`, appliqué conceptuellement **en plus** du takeover global. Cette séparation permet de conserver les overrides généraux tout en préparant un routing indépendant par sink, target, domain et niveau. ## Compatibilité runtime transitoire Cette tranche ne doit jamais accepter silencieusement un contrat que le runtime `0.1.2` ne sait pas encore appliquer. Après la validation structurelle, `initialize/reinitialize` refusent donc temporairement : - plusieurs fichiers **actifs** simultanément ; - ANSI console ; - format console différent de `Human` ; - format fichier différent de `Human` ; - filtre propre à un output différent de `OutputFilter::unrestricted()`. Les outputs désactivés peuvent déjà porter leur future configuration sans influencer le runtime actif. Le refus utilise actuellement `logging.invalid_settings` avec un contexte `runtime_contract = single-output-compatibility`. Ce garde-fou transitoire sera supprimé/remplacé lorsque `pre.005` implémentera réellement les capacités représentées. ## Lifecycle Logging préservé Cette tranche ne modifie pas les responsabilités suivantes : ```text initialize(...) reinitialize(...) LoggingGuard subscriber global unique takeover KSP hot reload transactionnel writers non bloquants DroppedLines agrégé console/fichier ``` `DroppedLines` reste temporairement agrégé par type de sink ; sa généralisation éventuelle par `output_id` appartient à `pre.005`. ## Frontière Config préservée Aucune dépendance inverse n'est introduite : ```text ksp-logging-lib -X-> ksp-config-lib ``` `ksp-logging-lib` ne lit toujours aucun fichier JSON, aucun profil, aucun `.env` et aucune variable applicative. Le futur `ksp-config-lib` construira ces contrats publics après résolution de `std.logging.json`. ## Dépendances Aucune dépendance externe ou KSP supplémentaire n'est ajoutée. Le graphe direct de `ksp-config-lib` reste inchangé dans cette tranche. ## Tests modifiés/ajoutés Les tests settings couvrent notamment : - les quatre formats ; - niveau/targets/domains de `OutputFilter` ; - wildcard unrestricted ; - console enabled/output/ANSI/format/filter ; - plusieurs `FileSettings` ; - unicité et syntaxe des `output_id` ; - fichiers sans ANSI ; - selectors invalides, doublons et targets externes ; - outputs déclarés mais désactivés. Les tests runtime couvrent également le garde-fou transitoire : - une console utilisant ANSI/format/routing enrichi est structurellement valide mais refusée par le backend courant ; - plusieurs fichiers actifs sont structurellement valides mais refusés par le backend courant ; - les contrats historiques compatibles continuent d'être préparés normalement. Le test d'intégration d'API publique construit un contrat avec console enrichie et fichier JSON filtré afin de vérifier que la nouvelle surface est bien accessible depuis le crate-root. ## Documentation Logging `README.md`, `USAGE.md` et `TODO.md` sont alignés sur la séparation : ```text pre.004 = contrat public multi-output pre.005 = activation runtime multi-sink/routing ``` ## Version technique La prerelease devient : ```text workspace.package.version = "0.1.3-pre.4" ``` Le manifest racine devient : ```text # version: 44 ``` Le plan Config devient : ```text ``` ## Fichiers ajoutés ```text deltas/0.1.3/pre.004.md ``` ## Fichiers modifiés ```text Cargo.toml crates/ksp-logging-lib/README.md crates/ksp-logging-lib/TODO.md crates/ksp-logging-lib/USAGE.md crates/ksp-logging-lib/src/lib.rs crates/ksp-logging-lib/src/runtime.rs crates/ksp-logging-lib/src/settings.rs crates/ksp-logging-lib/tests/public_api.rs crates/ksp-logging-lib/tests/runtime.rs crates/ksp-logging-lib/unit_tests/runtime.rs crates/ksp-logging-lib/unit_tests/settings.rs docs/plans/005-V0_1_3_CONFIG_FOUNDATION_PLAN.md ``` ## Hors scope confirmé Cette tranche n'implémente pas : - le runtime multi-sink complet ; - le routing réel par target/domain de chaque sink ; - les formatters Compact/Pretty/JSON runtime ; - l'ANSI console runtime ; - la généralisation complète des guards/drop counters par `output_id` ; - `serde`, `serde_json` ou `jsonschema` ; - `std.logging.json` ou son schema ; - profils Config ; - `.env` ou interpolation ; - modification de `ksp-config-lib`. ## Validations à exécuter par l'utilisateur ```bash cargo fmt --all cargo check --workspace cargo clippy --workspace --all-targets cargo test --workspace cargo tree -p ksp-logging-lib cargo tree -p ksp-logging-lib -d cargo tree -p ksp-logging-lib -e features ``` Les commandes Cargo ne sont pas déclarées réussies dans le delta tant qu'elles n'ont pas été exécutées sur l'environnement utilisateur. ## Suite Après validation de cette tranche : ```text 0.1.3-pre.005 — ksp-logging-lib : runtime multi-sink + routing ``` Cette tranche suivante devra activer réellement les contrats stabilisés ici sans réintroduire Config dans Logging.