v0.1.3-pre.005

This commit is contained in:
2026-08-15 20:22:02 +02:00
parent 29660fd9f0
commit 063b24ee1c
17 changed files with 957 additions and 244 deletions

View File

@@ -1,11 +1,11 @@
<!-- file: docs/plans/005-V0_1_3_CONFIG_FOUNDATION_PLAN.md -->
<!-- version: 7 -->
<!-- version: 8 -->
# Plan `0.1.3` — Configuration foundation
## 1. Statut et objectif
Ce plan a été établi par `0.1.3-pre.001`, corrigé par `0.1.3-pre.001-fix.001/.002/.003`, puis exécuté par petites tranches. `pre.002` a livré le bootstrap Config, `pre.003` le registre `file_id`, et `pre.004` étend maintenant les contrats publics de `ksp-logging-lib` nécessaires au futur `std.logging.json` sans ouvrir encore le runtime multi-sink complet.
Ce plan a été établi par `0.1.3-pre.001`, corrigé par `0.1.3-pre.001-fix.001/.002/.003`, puis exécuté par petites tranches. `pre.002` a livré le bootstrap Config, `pre.003` le registre `file_id`, `pre.004` les contrats publics multi-output de Logging, et `pre.005` active le runtime multi-sink sur niveau/target/formats. Le routing structuré `domain` est scindé en `pre.006` avant le gel du premier schema Logging.
La base auditée reste la release stable `v0.1.2`.
@@ -230,25 +230,25 @@ La complétion Logging n'ouvre ni une nouvelle façade ni une dépendance invers
## 5. Matrice de responsabilités
| Responsabilité | Propriétaire | Consommateurs | Interdit |
|---|---|---|---|
| Définir les `file_id` connus et leur mapping par défaut | `ksp-config-lib` | bootstrap Config | noms physiques codés dans les consumers |
| Résoudre `file_id -> filename` | `ksp-config-lib` | session Config | référence inter-document par filename |
| Interpréter `--cfgpath`, `--schemapath` et overrides de mapping KSP | `ksp-config-lib` | applications qui transmettent argv/options | parser ces options différemment dans chaque binaire |
| Lire un document Config JSON | `ksp-config-lib` | crates/apps via API Config | lecture directe par consumer |
| Valider JSON Schema | `ksp-config-lib` | orchestration/management | validation divergente dans chaque crate |
| Résoudre globals/profils/compositions | `ksp-config-lib` | orchestration | résolution locale dans un binaire |
| Lire `KSP_*` / `KSPB_*` du processus | `ksp-config-lib` | crates/apps via API Config | `std::env::var*` applicatif hors Config |
| Lire `.env` | `ksp-config-lib` | crates/apps via API Config | loader dotenv direct hors Config |
| Résoudre `${...}` et fallback | `ksp-config-lib` | tous les consumers | interpolation locale dans les consumers |
| Classer sensibilité et construire une valeur sûre | `ksp-config-lib` | runtime/logging/diagnostics | redaction ad hoc dans chaque crate |
| Modifier/sauvegarder JSON Config | `ksp-config-lib` | management explicite | écriture directe par application |
| Créer/modifier/supprimer une entrée `.env` | `ksp-config-lib` | management explicite | édition directe par application |
| Modifier l'environnement externe du shell/systemd/parent | propriétaire externe de ce processus | Config le lit seulement | prétendre qu'un child process peut administrer son parent |
| Posséder les settings/sinks/routing Logging | `ksp-logging-lib` | Config construit les contrats publics | logique de routing dupliquée dans Config |
| Posséder `LoggingGuard` | orchestration/application | lifecycle Logging | singleton Config global |
| Initialiser/recharger Logging | orchestration | Config fournit settings/changement | Logging lisant Config |
| DTO/bindings Tauri | application Tauri | frontend | TS-RS automatique dans Config |
| Responsabilité | Propriétaire | Consommateurs | Interdit |
|---------------------------------------------------------------------|--------------------------------------|--------------------------------------------|-----------------------------------------------------------|
| Définir les `file_id` connus et leur mapping par défaut | `ksp-config-lib` | bootstrap Config | noms physiques codés dans les consumers |
| Résoudre `file_id -> filename` | `ksp-config-lib` | session Config | référence inter-document par filename |
| Interpréter `--cfgpath`, `--schemapath` et overrides de mapping KSP | `ksp-config-lib` | applications qui transmettent argv/options | parser ces options différemment dans chaque binaire |
| Lire un document Config JSON | `ksp-config-lib` | crates/apps via API Config | lecture directe par consumer |
| Valider JSON Schema | `ksp-config-lib` | orchestration/management | validation divergente dans chaque crate |
| Résoudre globals/profils/compositions | `ksp-config-lib` | orchestration | résolution locale dans un binaire |
| Lire `KSP_*` / `KSPB_*` du processus | `ksp-config-lib` | crates/apps via API Config | `std::env::var*` applicatif hors Config |
| Lire `.env` | `ksp-config-lib` | crates/apps via API Config | loader dotenv direct hors Config |
| Résoudre `${...}` et fallback | `ksp-config-lib` | tous les consumers | interpolation locale dans les consumers |
| Classer sensibilité et construire une valeur sûre | `ksp-config-lib` | runtime/logging/diagnostics | redaction ad hoc dans chaque crate |
| Modifier/sauvegarder JSON Config | `ksp-config-lib` | management explicite | écriture directe par application |
| Créer/modifier/supprimer une entrée `.env` | `ksp-config-lib` | management explicite | édition directe par application |
| Modifier l'environnement externe du shell/systemd/parent | propriétaire externe de ce processus | Config le lit seulement | prétendre qu'un child process peut administrer son parent |
| Posséder les settings/sinks/routing Logging | `ksp-logging-lib` | Config construit les contrats publics | logique de routing dupliquée dans Config |
| Posséder `LoggingGuard` | orchestration/application | lifecycle Logging | singleton Config global |
| Initialiser/recharger Logging | orchestration | Config fournit settings/changement | Logging lisant Config |
| DTO/bindings Tauri | application Tauri | frontend | TS-RS automatique dans Config |
## 6. Registre de fichiers, bootstrap, arborescence et nomenclature
@@ -580,23 +580,23 @@ Décisions :
### 8.1 Écart `ksp-logging-lib 0.1.2` à fermer
| Capacité | `0.1.2` | Requise par `std.logging.json` |
|---|---:|---:|
| filtre global | oui | oui |
| overrides par target | oui | oui |
| lifecycle spans | oui | oui |
| console stdout/stderr | oui | oui |
| console enabled | via `Option` | oui explicite |
| console ANSI configurable | non | oui |
| format console configurable | non | oui |
| plusieurs fichiers | non | oui |
| rotation par fichier | un seul fichier | oui par sink |
| format par fichier | non | oui |
| filtre par sink/target | non | oui |
| filtre par sink/domain | non | oui |
| filtre par sink/niveau | non indépendant | oui |
| hot reload transactionnel | oui | à conserver |
| non-blocking/guards/drop counters | oui | à conserver et généraliser par sinks |
| Capacité | `0.1.2` | Requise par `std.logging.json` |
|-----------------------------------|----------------:|-------------------------------------:|
| filtre global | oui | oui |
| overrides par target | oui | oui |
| lifecycle spans | oui | oui |
| console stdout/stderr | oui | oui |
| console enabled | via `Option` | oui explicite |
| console ANSI configurable | non | oui |
| format console configurable | non | oui |
| plusieurs fichiers | non | oui |
| rotation par fichier | un seul fichier | oui par sink |
| format par fichier | non | oui |
| filtre par sink/target | non | oui |
| filtre par sink/domain | non | oui |
| filtre par sink/niveau | non indépendant | oui |
| hot reload transactionnel | oui | à conserver |
| non-blocking/guards/drop counters | oui | à conserver et généraliser par sinks |
Ce tableau est un **gap identifié**, pas une invitation à déplacer Logging dans Config. La tranche qui le ferme modifie `ksp-logging-lib` uniquement dans son domaine propriétaire.
@@ -1646,37 +1646,68 @@ Implémentation candidate livrée par `pre.004` :
- jusqu'à `pre.005`, `initialize/reinitialize` refusent explicitement les nouvelles capacités qu'ils ne savent pas encore appliquer (plusieurs fichiers actifs, formats enrichis, ANSI console ou routing par output) plutôt que de les ignorer silencieusement ;
- aucune dépendance Config n'entre dans Logging et aucune dépendance externe supplémentaire n'est ajoutée.
La validation utilisateur de `pre.004` reste requise avant l'ouverture de `pre.005`.
`pre.004` a été validée par l'utilisateur le 2026-08-15 avec `cargo fmt --all`, `cargo check --workspace`, `cargo clippy --workspace --all-targets`, `cargo test --workspace` et les trois vues `cargo tree -p ksp-logging-lib` demandées, sans warning ni échec.
### `0.1.3-pre.005` — `ksp-logging-lib` : runtime multi-sink + routing
### `0.1.3-pre.005` — `ksp-logging-lib` : runtime multi-sink + routing metadata
Objectif unique : implémenter derrière les contrats de `pre.004` le comportement runtime manquant.
Objectif unique : activer derrière les contrats de `pre.004` les capacités runtime bornées aux métadonnées directement disponibles par output.
- 0..N fichiers simultanés ;
- console indépendante ;
- routing/filter par output, level, target et domain ;
- rotation/format/ANSI selon settings ;
- writers non bloquants et guards ;
- conserver subscriber unique et takeover ;
- routing/filter par output sur level + target ;
- rotation/format `Human/Compact/Pretty/Json` ;
- ANSI console configurable, jamais persisté dans les fichiers ;
- writers non bloquants et guards indépendants ;
- compteurs agrégés conservés + compteur cumulatif fichier par `output_id` ;
- conserver subscriber unique et takeover global KSP ;
- conserver `initialize/reinitialize` transactionnel ;
- conserver drop counters et comportement de saturation ;
- tests de non-régression et hot reload.
- conserver le comportement de saturation ;
- tests multi-sink, formats, routing metadata et hot reload.
Si l'audit de `pre.004` montre que multi-sink et routing/hot-reload ne tiennent pas proprement ensemble dans le budget, `pre.005` est scindée avant implémentation ; le numéro de clôture est alors décalé explicitement.
Décision de scission prise pendant l'implémentation : `domain` est un champ structuré et ne doit être ni assimilé au target ni filtré approximativement au niveau du writer. `pre.005` refuse donc explicitement tout output actif avec `domains != ["*"]`.
### `0.1.3-pre.006` — JSON/JSON Schema + premier document Logging
Implémentation candidate de `pre.005` :
- chaque formatter possède son writer routé par `OutputFilter.level` + `OutputFilter.targets` ;
- la politique globale `default_filter` + `TargetFilter` reste composée devant tout le groupe de sinks ;
- les layers reloadables ne deviennent pas des `Filtered`, afin de préserver la composition/hot reload stabilisée en `0.1.2` ;
- `tracing-subscriber` active ses features `json` et `ansi` pour les formats publics déjà décidés en `pre.004` ;
- `LoggingGuard::dropped_file_lines(output_id)` expose le compteur cumulatif d'un fichier à travers les reloads ;
- `DroppedLines` conserve la vue agrégée console/fichier ;
- JSON + ANSI console est refusé comme combinaison incohérente ;
- aucune dépendance Config n'entre dans Logging.
La validation utilisateur de `pre.005` est requise avant l'ouverture de `pre.006`.
### `0.1.3-pre.006` — `ksp-logging-lib` : routing structuré `domain`
Objectif unique : fermer proprement la dimension `OutputFilter.domains[]` avant que Config ne fige le schema Logging.
- extraire le champ structuré `domain` des events/spans ;
- définir la sémantique d'un event portant son propre `domain` ;
- définir l'héritage depuis le span courant lorsqu'un event ne porte pas de `domain` ;
- définir le comportement des spans sans domain et des spans imbriqués ;
- appliquer les selectors domain par output sans casser level/target ;
- conserver les événements lifecycle `SpanEvents` cohérents avec le domain du span ;
- préserver les champs formatés requis par les différents formatters ;
- conserver hot reload, takeover et non-blocking ;
- tests unitaires/intégration sur events, spans, héritage et plusieurs sinks.
Une solution qui réduirait `domain` à une convention de target est interdite : il s'agit d'une dimension structurée distincte.
### `0.1.3-pre.007` — JSON/JSON Schema + premier document Logging
- `serde`/`serde_json`/`jsonschema` au workspace avec versions revérifiées ;
- infrastructure générique de lecture JSON ;
- association descriptor -> schema par `file_id` ;
- validation JSON Schema ;
- `config/`, `config/schemas/`, `config/examples/` ;
- `std.logging.schema.json` aligné sur les contrats Logging réellement stabilisés en `pre.004/.005` ;
- `std.logging.schema.json` aligné sur les contrats Logging réellement stabilisés en `pre.004/.005/.006` ;
- runtime `config/std.logging.json` ;
- exemple Logging ;
- parse/schema/validation sémantique de base.
### `0.1.3-pre.007` — globals + profils + `default_profile`
### `0.1.3-pre.008` — globals + profils + `default_profile`
- paramètres globaux hors profils ;
- `profile_id` unique ;
@@ -1686,7 +1717,7 @@ Si l'audit de `pre.004` montre que multi-sink et routing/hot-reload ne tiennent
- provenance document/global/profile ;
- tests sur `std.logging.json`.
### `0.1.3-pre.008` — compositions génériques par `file_id`
### `0.1.3-pre.009` — compositions génériques par `file_id`
- contrat composite générique ;
- schema/example composite ;
@@ -1695,7 +1726,7 @@ Si l'audit de `pre.004` montre que multi-sink et routing/hot-reload ne tiennent
- résolution composition -> document -> profil/global ;
- aucun composite runtime fictif obligatoire.
### `0.1.3-pre.009` — `.env` + process env + resolver `${...}`
### `0.1.3-pre.010` — `.env` + process env + resolver `${...}`
- lecture process env ;
- lecture `.env` sans écrasement process ;
@@ -1706,7 +1737,7 @@ Si l'audit de `pre.004` montre que multi-sink et routing/hot-reload ne tiennent
- namespaces KSP/KSPB ;
- tests d'isolation process env.
### `0.1.3-pre.010` — sensibilité + valeurs real/safe/provenance
### `0.1.3-pre.011` — sensibilité + valeurs real/safe/provenance
- `Public/Internal/Secret` ;
- propagation de sensibilité par chaîne composée ;
@@ -1716,7 +1747,7 @@ Si l'audit de `pre.004` montre que multi-sink et routing/hot-reload ne tiennent
- interdiction des secrets dans logs/diagnostics ordinaires ;
- tests canary de non-divulgation.
### `0.1.3-pre.011` — adapter Config -> Logging
### `0.1.3-pre.012` — adapter Config -> Logging
- `ResolvedLoggingConfig` ;
- conversion explicite vers les contrats publics `ksp_logging_lib::*` ;
@@ -1726,7 +1757,7 @@ Si l'audit de `pre.004` montre que multi-sink et routing/hot-reload ne tiennent
- tests de mapping multi-output/filter/domain ;
- vérification qu'aucune valeur secrète n'est utilisée dans les diagnostics Logging.
### `0.1.3-pre.012` — management + persistence JSON/.env
### `0.1.3-pre.013` — management + persistence JSON/.env
- lecture management ;
- reveal secret explicite ;
@@ -1736,7 +1767,7 @@ Si l'audit de `pre.004` montre que multi-sink et routing/hot-reload ne tiennent
- desired/effective/shadow report ;
- refus des mutations non autorisées.
### `0.1.3-pre.013` — ownership audits + robustesse
### `0.1.3-pre.014` — ownership audits + robustesse
- audits interdisant les accès Config/env directs ailleurs ;
- invalid documents/env/placeholders/file mappings ;
@@ -1745,7 +1776,7 @@ Si l'audit de `pre.004` montre que multi-sink et routing/hot-reload ne tiennent
- robustesse des diagnostics sans fuite ;
- vérification de la granularité réelle des responsabilités publiques.
### `0.1.3-pre.014` — clôture
### `0.1.3-pre.015` — clôture
- validations finales ;
- documentation durable ;
@@ -1832,9 +1863,9 @@ Le `pre.001-fix.003` est validable lorsque les décisions suivantes sont accept
- l'écart de capacités de `ksp-logging-lib 0.1.2` est reconnu et sera fermé dans Logging, pas contourné par Config ;
- le lifecycle/ownership Logging `initialize/reinitialize/LoggingGuard` reste inchangé ;
- persistence JSON et `.env` atomique ;
- `0.1.3` reste une release unique bornée avec clôture prévisionnelle en `pre.014`, sous réserve de nouvelles scissions explicites si une tranche dépasse le budget 1520 minutes ;
- `0.1.3` reste une release unique bornée avec clôture prévisionnelle désormais en `pre.015`, sous réserve de nouvelles scissions explicites si une tranche dépasse le budget 1520 minutes ;
- `pre.002` est limitée à la création de la crate et au bootstrap `cfgpath`/`schemapath`; le registre `file_id` commence en `pre.003` ;
- les évolutions `ksp-logging-lib` sont explicites en `pre.004` (contrats/settings multi-output) puis `pre.005` (runtime multi-sink/routing), avant gel du schema Logging ;
- les évolutions `ksp-logging-lib` sont explicites en `pre.004` (contrats/settings), `pre.005` (runtime multi-sink + level/target/formats) puis `pre.006` (routing structuré domain), avant gel du schema Logging ;
- chaque prerelease vise environ 1520 minutes de travail effectif et doit être scindée si ce budget devient manifestement irréaliste ;
- aucune implémentation `pre.002` ne commence avant validation utilisateur de ce plan corrigé.