349 lines
9.7 KiB
Markdown
349 lines
9.7 KiB
Markdown
<!-- file: deltas/0.1.3/pre.013.md -->
|
|
<!-- version: 1 -->
|
|
|
|
# Delta 0.1.3-pre.013
|
|
|
|
## Base requise
|
|
|
|
Livraison précédente validée :
|
|
|
|
```text
|
|
0.1.3-pre.012
|
|
```
|
|
|
|
Version technique de cette base :
|
|
|
|
```text
|
|
workspace.package.version = "0.1.3-pre.12"
|
|
Cargo.toml header version = 56
|
|
```
|
|
|
|
Validations utilisateur exécutées le 2026-08-16 :
|
|
|
|
```text
|
|
cargo fmt --all OK
|
|
cargo check --workspace OK
|
|
cargo clippy --workspace --all-targets OK
|
|
cargo test --workspace OK
|
|
cargo tree -p ksp-config-lib OK
|
|
cargo tree -p ksp-config-lib -d OK, doublon transitif syn 2/3 déjà connu
|
|
cargo tree -p ksp-config-lib -e features OK
|
|
cargo tree -p ksp-logging-lib -d OK, aucun doublon
|
|
```
|
|
|
|
`cargo test --workspace` confirme notamment 70 tests unitaires + 10 tests publics pour `ksp-config-lib` et 34 tests unitaires Logging avec toutes ses intégrations vertes.
|
|
|
|
## Objet de pre.013
|
|
|
|
Fermer la première surface de management/persistence Config sans introduire Tauri ni permettre aux applications de contourner `ksp-config-lib` :
|
|
|
|
```text
|
|
registered file_id
|
|
-> management source read
|
|
-> typed std.logging mutation
|
|
-> candidate validation
|
|
-> atomic persistence
|
|
|
|
process env (read-only) + .env (read/write)
|
|
-> desired/effective/shadow report
|
|
-> explicit reveal when UI management intentionally needs the real value
|
|
```
|
|
|
|
## `ConfigManagement`
|
|
|
|
Nouveau contrat public :
|
|
|
|
```text
|
|
ConfigManagement
|
|
```
|
|
|
|
Il possède un `ConfigDocumentEngine` et utilise par défaut le `.env` conventionnel :
|
|
|
|
```text
|
|
./.env
|
|
```
|
|
|
|
Il n'ajoute aucun path runtime Config supplémentaire et ne modifie jamais l'environnement hérité du processus.
|
|
|
|
L'authentification/autorisation de l'utilisateur final reste une responsabilité de la future application `ksp-app-config-desk`. Config fournit une frontière explicite qui évite l'exposition accidentelle mais ne prétend pas être un système d'authentification intra-processus.
|
|
|
|
## Lecture management
|
|
|
|
`ConfigManagement::read_source(file_id)` lit le texte brut d'un document **Config enregistré** par son `file_id`.
|
|
|
|
Cette lecture :
|
|
|
|
- ne prend jamais un path arbitraire fourni par le caller ;
|
|
- refuse un `file_id` de kind Schema ;
|
|
- reste possible lorsque le document est syntaxiquement/schema/sémantiquement invalide, afin qu'une UI de management puisse afficher et corriger sa source ;
|
|
- retourne `ConfigManagedSource`, dont `Debug` n'expose pas le contenu brut.
|
|
|
|
Aucune primitive publique générique « save raw JSON to path » n'est ajoutée.
|
|
|
|
## Mutation typée de `std.logging.json`
|
|
|
|
Nouveaux contrats source publics :
|
|
|
|
```text
|
|
LoggingConfigDocument
|
|
LoggingProfileConfig
|
|
LoggingConsoleConfig
|
|
LoggingFileConfig
|
|
LoggingOutputFilterConfig
|
|
LoggingTargetFilterConfig
|
|
```
|
|
|
|
Ils représentent la forme source de `cfg.std.logging` et permettent une mutation structurée en mémoire.
|
|
|
|
La persistance suit obligatoirement :
|
|
|
|
```text
|
|
LoggingConfigDocument
|
|
-> serde_json candidate
|
|
-> registered std.logging schema
|
|
-> KSP profile/logging semantic invariants
|
|
-> pretty JSON + newline final
|
|
-> atomic commit
|
|
```
|
|
|
|
Un candidate invalide retourne l'erreur de validation existante et ne touche pas au fichier destination.
|
|
|
|
`ConfigDocumentEngine` reçoit uniquement un helper interne `validate_candidate(...)`; la validation reste possédée par Config et n'est pas dupliquée dans la couche management.
|
|
|
|
## Persistence atomique
|
|
|
|
Nouveau module privé :
|
|
|
|
```text
|
|
src/persistence.rs
|
|
```
|
|
|
|
Stratégie :
|
|
|
|
1. créer un fichier temporaire avec `create_new` dans le même répertoire que la destination ;
|
|
2. appliquer les permissions requises ;
|
|
3. écrire tout le contenu ;
|
|
4. `sync_all` le fichier temporaire ;
|
|
5. fermer le handle ;
|
|
6. remplacer la destination par `rename` ;
|
|
7. nettoyer le temporaire si une étape pré-commit échoue.
|
|
|
|
La destination reste donc l'ancien fichier complet jusqu'au commit final.
|
|
|
|
Les permissions du fichier existant sont conservées. Sur Unix, un nouveau `.env` créé par Config reçoit explicitement :
|
|
|
|
```text
|
|
0600
|
|
```
|
|
|
|
Les documents JSON ne reçoivent pas artificiellement ce mode privé ; un fichier existant conserve son mode.
|
|
|
|
Nouveau code d'erreur :
|
|
|
|
```text
|
|
config.persistence_write_failed
|
|
```
|
|
|
|
## Management du `.env`
|
|
|
|
Nouvelles opérations :
|
|
|
|
```text
|
|
set_dotenv_value(name, value)
|
|
remove_dotenv_value(name)
|
|
reveal_dotenv_value(name)
|
|
reveal_effective_environment_value(name)
|
|
environment_report()
|
|
```
|
|
|
|
Mutation autorisée uniquement pour les namespaces déjà possédés par Config :
|
|
|
|
```text
|
|
KSP_*
|
|
KSPB_*
|
|
```
|
|
|
|
Une mutation ne touche jamais `std::env::set_var/remove_var` et ne prétend donc jamais modifier le shell parent, systemd, Docker/Kubernetes ou l'environnement déjà hérité du processus.
|
|
|
|
Avant mutation, le `.env` existant doit être interprétable par la grammaire Config actuelle. Un `.env` invalide est refusé sans altération.
|
|
|
|
L'éditeur ciblé :
|
|
|
|
- conserve les lignes/commentaires non concernés ;
|
|
- remplace uniquement l'assignment ciblé ;
|
|
- encode les valeurs nécessitant espaces, `#`, quotes, backslash ou contrôles avec la forme double-quoted déjà comprise par Config ;
|
|
- normalise un fichier modifié avec newline final ;
|
|
- ne réécrit pas un assignment si la valeur persistée est déjà identique ;
|
|
- ne crée pas le fichier lors d'un remove d'une clé absente.
|
|
|
|
## Desired / effective / shadow
|
|
|
|
`ConfigEnvironmentReport` n'embarque aucune valeur réelle secrète.
|
|
|
|
Il expose :
|
|
|
|
```text
|
|
variable_name
|
|
sensitivity
|
|
desired_safe_value # valeur .env persistée
|
|
effective_safe_value # process sinon .env
|
|
effective_source
|
|
shadowed_by_process_environment
|
|
```
|
|
|
|
Une entrée `.env` est `desired`; la valeur héritée du process reste prioritaire et peut donc la shadow.
|
|
|
|
`ConfigEnvironmentChangeReport` expose après create/update/remove :
|
|
|
|
```text
|
|
source_changed
|
|
effective_changed
|
|
shadowed_by_process_environment
|
|
reload_required
|
|
```
|
|
|
|
Si le process shadow une modification `.env`, `source_changed = true` mais `effective_changed = false` et `reload_required = false` pour le processus courant.
|
|
|
|
## Reveal explicite et secrets
|
|
|
|
Les rapports management ordinaires utilisent la représentation sûre :
|
|
|
|
```text
|
|
KSP_SECRET_* / KSPB_SECRET_* -> ********
|
|
```
|
|
|
|
La valeur réelle n'est accessible qu'en appelant explicitement :
|
|
|
|
```text
|
|
reveal_dotenv_value(...)
|
|
reveal_effective_environment_value(...)
|
|
```
|
|
|
|
Ces méthodes sont destinées à une surface UI management légitimement autorisée. Elles ne changent pas les règles suivantes :
|
|
|
|
- jamais de secret réel dans `Debug` ;
|
|
- jamais de secret réel dans les logs ;
|
|
- jamais de secret réel dans les diagnostics génériques ;
|
|
- l'application reste propriétaire de l'autorisation utilisateur.
|
|
|
|
## Règles durables
|
|
|
|
Ajout de :
|
|
|
|
```text
|
|
KSP-CONFIG-014
|
|
KSP-CONFIG-015
|
|
KSP-CONFIG-016
|
|
```
|
|
|
|
pour figer respectivement :
|
|
|
|
- la persistence validée/atomique bornée aux ressources Config connues ;
|
|
- la distinction process read-only / `.env` read-write et le reporting shadow ;
|
|
- la séparation report sûr / reveal explicite des valeurs sensibles.
|
|
|
|
`FILE_CONTRACTS.md` documente également la stratégie de persistence, le newline JSON, la preservation des permissions et le mode `0600` d'un nouveau `.env` sur Unix.
|
|
|
|
## `.env.example`
|
|
|
|
Aucune nouvelle variable runtime n'est introduite par cette tranche.
|
|
|
|
`.env.example` reste donc inchangé :
|
|
|
|
```text
|
|
KSP_LOGS_DIRECTORY=logs
|
|
```
|
|
|
|
Les variables utilisées uniquement comme canaries/tests ne font pas partie de l'inventaire runtime.
|
|
|
|
## Dépendances
|
|
|
|
Aucune nouvelle dépendance Cargo.
|
|
|
|
La direction reste :
|
|
|
|
```text
|
|
ksp-config-lib -> ksp-core-lib
|
|
ksp-config-lib -> ksp-logging-lib
|
|
ksp-logging-lib -X-> ksp-config-lib
|
|
```
|
|
|
|
## Tests ajoutés
|
|
|
|
Le nouveau module `unit_tests/management.rs` ajoute 10 tests couvrant notamment :
|
|
|
|
- lecture raw d'un source schema-invalide ;
|
|
- mutation typée + persistance + reload de `std.logging.json` ;
|
|
- candidate Logging invalide sans altération du fichier ;
|
|
- save identique sans reload ;
|
|
- create/update/remove `.env` ;
|
|
- quoting et preservation de commentaires/lignes externes ;
|
|
- `.env` invalide non modifié ;
|
|
- namespace externe refusé sans création de `.env` ;
|
|
- report secret redacted + reveal explicite du canary ;
|
|
- process shadowing desired `.env` sans faux changement effectif ;
|
|
- mode `0600` du nouveau `.env` sur Unix.
|
|
|
|
La surface publique ajoute un test d'adressabilité des contrats management.
|
|
|
|
Après ajout, `ksp-config-lib` doit compter :
|
|
|
|
```text
|
|
80 tests unitaires
|
|
11 tests publics
|
|
```
|
|
|
|
à exécuter chez l'utilisateur.
|
|
|
|
## Fichiers ajoutés
|
|
|
|
```text
|
|
crates/ksp-config-lib/src/management.rs
|
|
crates/ksp-config-lib/src/persistence.rs
|
|
crates/ksp-config-lib/unit_tests/management.rs
|
|
deltas/0.1.3/pre.013.md
|
|
```
|
|
|
|
## Fichiers modifiés
|
|
|
|
```text
|
|
Cargo.toml
|
|
crates/ksp-config-lib/src/document.rs
|
|
crates/ksp-config-lib/src/environment.rs
|
|
crates/ksp-config-lib/src/error.rs
|
|
crates/ksp-config-lib/src/lib.rs
|
|
crates/ksp-config-lib/tests/public_api.rs
|
|
docs/rules/RULES_KSP.md
|
|
docs/rules/FILE_CONTRACTS.md
|
|
docs/plans/000-README.md
|
|
docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md
|
|
docs/plans/005-V0_1_3_CONFIG_FOUNDATION_PLAN.md
|
|
```
|
|
|
|
## Hors scope
|
|
|
|
Toujours hors `pre.013` :
|
|
|
|
- application desktop Config/Tauri ;
|
|
- watcher automatique de fichiers ;
|
|
- rechargement automatique du runtime après save ;
|
|
- mutation générique de documents arbitraires ;
|
|
- management d'un environnement parent/systemd/container ;
|
|
- autres documents standard Store/Wallet/Transport ;
|
|
- audit global empêchant tous les futurs contournements Config hors crate, prévu en `pre.014`.
|
|
|
|
## Validation demandée
|
|
|
|
```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
|
|
cargo tree -p ksp-logging-lib -d
|
|
```
|
|
|
|
Aucune validation Cargo locale n'est revendiquée dans l'environnement de génération de ce delta.
|