# Delta 0.1.3-pre.007 ## Base requise Livraison précédente validée : ```text 0.1.3-pre.006 ``` Version technique de cette base : ```text workspace.package.version = "0.1.3-pre.6" Cargo.toml header version = 47 ``` Validations utilisateur exécutées le 2026-08-15 : ```text cargo fmt --all OK cargo check --workspace OK cargo clippy --workspace --all-targets OK cargo test --workspace OK cargo tree -p ksp-logging-lib OK cargo tree -p ksp-logging-lib -d OK — aucune duplication cargo tree -p ksp-logging-lib -e features OK ``` Les tranches Logging préalables au premier schema Config sont donc closes. ## Objet de pre.007 Introduire la première surface JSON/JSON Schema réelle de `ksp-config-lib` sans ouvrir encore la résolution de profils, les composites ou l'environnement : ```text registry file_id -> resolved Config path -> JSON parse -> registered schema file_id -> schema parse + meta-schema validation -> document validation -> bounded document semantics ``` Le premier document concret est : ```text cfg.std.logging -> config/std.logging.json ``` validé par : ```text schema.std.logging -> config/schemas/std.logging.schema.json ``` ## Dépendances Versions vérifiées au moment de l'ajout depuis les sources officielles `crates.io` / `docs.rs` : ```text serde 1.0.229 -> workspace constraint ^1.0 serde_json 1.0.151 -> workspace constraint ^1.0 jsonschema 0.49.9 -> workspace constraint ^0.49 ``` `jsonschema` est déclaré avec : ```text default-features = false ``` La première surface KSP utilise un schema autonome avec références JSON Pointer internes uniquement ; aucune récupération HTTP/file de schemas distants n'est nécessaire. Les trois dépendances sont déclarées uniquement sous `[workspace.dependencies]`, puis consommées par `ksp-config-lib` avec `.workspace = true`. ## Association document -> schema `ConfigFileDescriptor` possède maintenant : ```text schema_file_id: Option ``` Le mapping par défaut devient conceptuellement : ```text cfg.std.logging kind = Config filename = std.logging.json schema_file_id = schema.std.logging schema.std.logging kind = Schema filename = std.logging.schema.json schema_file_id = none ``` Le registre valide : - qu'un schema référencé utilise le namespace `schema.*` ; - que son descriptor existe réellement ; - qu'il possède `ConfigFileKind::Schema` ; - qu'un descriptor Schema ne référence pas lui-même un schema Config. Un `--filemap` change uniquement le filename physique et conserve cette association logique. Aucun `schema.composite` n'est encore créé : il sera ajouté avec la tranche composite qui en a réellement besoin. ## Moteur JSON générique Nouvelle façade : ```text ConfigDocumentEngine ConfigJsonDocument ``` `ConfigDocumentEngine::load_validated_document(file_id)` : 1. vérifie que le `file_id` désigne un document Config ; 2. résout son path via `ConfigBootstrapOptions` + `ConfigFileRegistry` ; 3. lit et parse le JSON ; 4. charge le schema associé par son propre `file_id` ; 5. valide le schema contre son meta-schema ; 6. valide le document contre le schema Draft 2020-12 ; 7. exécute les invariants sémantiques actuellement connus pour ce type de document ; 8. retourne le JSON validé sans transférer aux consumers la responsabilité de lecture/validation filesystem. `ConfigJsonDocument` expose uniquement : ```text file_id resolved path validated serde_json::Value ``` Les autres crates restent interdites de lecture directe des fichiers Config. ## Diagnostics Les nouveaux codes Config distinguent : ```text config.json_file_read_failed config.json_syntax_invalid config.schema_invalid config.schema_validation_failed config.document_semantic_invalid ``` Les erreurs enregistrent le `file_id` et le path concernés, mais jamais le contenu JSON complet. ## Premier schema Logging `config/schemas/std.logging.schema.json` utilise JSON Schema Draft 2020-12 et couvre la surface Logging stabilisée en `pre.004/.005/.006` : ```text format_version logs_directory default_profile profiles[] profile_id default_filter span_events console enabled output ansi format filter.level filter.targets[] filter.domains[] files[] output_id enabled path rotation format ansi = false filter.level filter.targets[] filter.domains[] target_filters[] ``` Le schema encode notamment : - niveaux `off/error/warn/info/debug/trace` ; - lifecycle `off/new_and_close/full` ; - formats `human/compact/pretty/json` ; - rotation `never/hourly/daily` ; - console `stdout/stderr` ; - targets KSP ou wildcard `*` ; - selectors uniques, wildcard utilisé seul ; - ANSI interdit pour les fichiers ; - ANSI + JSON console interdit. ## Document runtime et exemple Ajouts : ```text config/std.logging.json config/schemas/std.logging.schema.json config/examples/std.logging.example.json ``` Le runtime utilise déjà : ```text "logs_directory": "${KSP_LOGS_DIRECTORY:-logs}" ``` mais `pre.007` ne résout encore aucune variable. Le placeholder reste une valeur source string valide jusqu'au resolver de `pre.010`. Le runtime démontre : - console configurable ; - plusieurs fichiers ; - formats humain et JSON ; - filtres par level/target/domain ; - target overrides globaux ; - `output_id` distinct du `file_id` Config. ## Validation sémantique de base Après JSON Schema, Config vérifie déjà les invariants directement liés à la surface Logging : - `format_version = 1` ; - chaînes globales requises non vides ; - `output_id` fichier conforme ; - `output_id` uniques dans un même profil ; - path fichier relatif à `logs_directory`, sans traversal ; - ANSI fichier interdit ; - ANSI + JSON console interdit ; - selectors non vides/uniques ; - wildcard seul ; - target selector et global `target_prefix` limités aux targets `ksp-*`. Ne sont volontairement **pas encore** traités dans cette tranche : - unicité des `profile_id` ; - résolution de `default_profile` ; - sélection explicite d'un profil ; - construction d'une configuration effective globals + profil. Ces responsabilités appartiennent à `pre.008`. ## Tests ajoutés Les tests unitaires Config couvrent : - document Logging runtime commité valide ; - fichier Config absent ; - syntaxe JSON invalide ; - schema lui-même invalide ; - document ne satisfaisant pas son schema ; - document schema-valide mais sémantiquement invalide ; - association document -> schema présente dans le registre ; - association vers schema absent refusée. Le test d'API publique vérifie que `ConfigDocumentEngine` charge le vrai `std.logging.json` depuis les racines Config du workspace. ## Hors scope Cette tranche ne fait pas encore : - résolution globals/profils/`default_profile` ; - composite ; - `.env` ; - `std::env` ; - interpolation `${...}` ; - classification secret/public/internal ; - redaction ; - adaptation vers `ksp_logging_lib::LoggingSettings` ; - mutation/persistence. `ksp-config-lib` ne dépend donc toujours pas de `ksp-logging-lib` dans `pre.007`. ## Version technique La prerelease devient : ```text workspace.package.version = "0.1.3-pre.7" Cargo.toml header version = 48 ``` ## Fichiers ajoutés ```text config/std.logging.json config/schemas/std.logging.schema.json config/examples/std.logging.example.json crates/ksp-config-lib/src/document.rs crates/ksp-config-lib/unit_tests/document.rs deltas/0.1.3/pre.007.md ``` ## Fichiers modifiés ```text Cargo.toml crates/ksp-config-lib/Cargo.toml crates/ksp-config-lib/src/error.rs crates/ksp-config-lib/src/lib.rs crates/ksp-config-lib/src/registry.rs crates/ksp-config-lib/tests/public_api.rs crates/ksp-config-lib/unit_tests/registry.rs docs/plans/000-README.md docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md docs/plans/005-V0_1_3_CONFIG_FOUNDATION_PLAN.md docs/rules/FILE_CONTRACTS.md ``` ## Contrôles exécutés dans l'environnement de génération Les fichiers JSON ont été parsés avec `python -m json.tool`. Le schema Draft 2020-12 et le document runtime ont également été validés avec l'implémentation Python `jsonschema` disponible dans l'environnement de génération. Aucune commande Cargo n'est disponible dans cet environnement ; aucune validation Rust n'est donc déclarée réussie ici. ## Validations utilisateur à exécuter ```bash cargo fmt --all cargo check --workspace cargo clippy --workspace --all-targets cargo test --workspace cargo tree -p ksp-config-lib cargo tree -p ksp-config-lib -d cargo tree -p ksp-config-lib -e features ``` Une attention particulière doit être portée au graphe `jsonschema` avec `default-features = false` afin de confirmer qu'aucun stack HTTP/TLS de résolution distante n'est introduit inutilement. Après validation de `pre.007`, la prochaine tranche est : ```text 0.1.3-pre.008 — globals + profils + default_profile ```