Files
khadhroony-solana-project/deltas/0.1.3/pre.011.md
2026-08-16 04:35:23 +02:00

330 lines
8.1 KiB
Markdown

<!-- file: deltas/0.1.3/pre.011.md -->
<!-- version: 1 -->
# Delta 0.1.3-pre.011
## Base requise
Livraison précédente validée :
```text
0.1.3-pre.010-fix.001
```
Version technique de cette base :
```text
workspace.package.version = "0.1.3-pre.10.fix.1"
Cargo.toml header version = 53
```
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-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 test --workspace` confirme notamment 53 tests unitaires + 8 tests publics pour `ksp-config-lib`.
## Objet de pre.011
Ajouter la couche de sécurité/provenance qui manquait au resolver environnemental :
```text
Config source string / JSON
+
process > .env > fallback
->
real runtime value
safe diagnostic value
Public | Internal | Secret
ordered / JSON-Pointer provenance
```
Cette tranche ne modifie pas encore les documents Config, ne construit pas `LoggingSettings` et ne persiste rien.
## Classification de sensibilité
`ConfigSensitivity` expose :
```text
Public
Internal
Secret
```
Classification nominale :
```text
KSP_SECRET_* / KSPB_SECRET_* -> Secret
KSP_PUBLIC_* / KSPB_PUBLIC_* -> Public
autre KSP_* / KSPB_* -> Internal
```
Ordre :
```text
Secret > Internal > Public
```
La sensibilité d'une chaîne contenant des placeholders est la sensibilité la plus forte des placeholders effectivement référencés. Une chaîne littérale sans placeholder est `Internal`.
Un fallback hérite toujours de la sensibilité du nom de variable référencé. Ainsi :
```text
${KSP_SECRET_TOKEN:-false-secret}
```
reste `Secret` même si la valeur réelle vient du fallback.
## Valeur réelle et représentation sûre
`ConfigEnvironmentValue` conserve désormais :
```text
variable_name
value réel runtime
safe_value diagnostic sûr
sensitivity
source Process | DotEnv | Fallback
provenance
```
Pour `Secret` :
```text
value = valeur réelle
safe_value = ********
```
Pour `Public` et `Internal`, la représentation sûre conserve la valeur réelle dans cette tranche.
`ConfigEnvironmentValue` possède un `Debug` manuel qui n'affiche jamais `value`; il affiche `safe_value`, sensibilité, source et nom de variable.
## Chaînes composées
Nouveau contrat :
```text
ResolvedConfigText
```
Il conserve :
```text
value
safe_value
sensitivity
provenance[]
```
Exemple :
```text
source:
https://${KSP_PUBLIC_HOST}/?token=${KSP_SECRET_TOKEN}
real:
https://rpc.example.test/?token=secret-canary
safe:
https://rpc.example.test/?token=********
```
La redaction est réalisée par segment de substitution. Les fragments littéraux et non secrets restent visibles dans la représentation sûre.
`ConfigEnvironment::resolve_text_detailed()` expose ce contrat.
L'API existante :
```text
resolve_text(...)
```
reste compatible et retourne uniquement la valeur réelle.
## Provenance
`ConfigValueProvenance` distingue :
```text
DocumentLiteral
EnvironmentProcess { variable_name }
EnvironmentDotEnv { variable_name }
EnvironmentFallback { variable_name }
```
La provenance n'embarque jamais la valeur d'environnement elle-même.
Une chaîne composée conserve l'ordre des segments/références ayant participé à sa construction.
## JSON détaillé
Nouveau contrat :
```text
ResolvedConfigJson
```
Il conserve :
```text
value arbre JSON réel
safe_value arbre JSON redacted
sensitivity plus forte sensibilité contenue
provenance map JSON Pointer -> provenance[]
```
`ConfigEnvironment::resolve_json_detailed()` parcourt récursivement objets et tableaux sans modifier les clés.
Les JSON Pointer suivent RFC 6901 pour les clés contenant `~` ou `/`.
L'API existante :
```text
resolve_json(...)
resolve_map(...)
```
reste compatible et retourne uniquement la valeur réelle.
## Profil effectif
`ResolvedConfigProfile` ajoute :
```text
resolve_effective_environment_detailed(...)
```
La provenance top-level déjà existante :
```text
Global
Profile
```
reste attachée au profil source via `origin(key)`.
La résolution détaillée ajoute séparément la provenance de la couche environnement :
```text
DocumentLiteral
Process
DotEnv
Fallback
```
L'ancienne méthode `resolve_effective_environment()` reste disponible et retourne seulement la map réelle.
## Non-divulgation
Les tests canary vérifient notamment :
- secret venant du process : réel disponible, safe redacted, `Debug` sans canary ;
- secret venant d'un fallback : fallback réel disponible mais safe redacted ;
- URL composée public + secret : seul le segment secret est masqué ;
- JSON imbriqué : arbre réel complet, arbre safe redacted, `Debug` sans canary ;
- provenance de la variable sans transport de la valeur elle-même.
`ksp-logging-lib` ne reçoit aucune logique générique de redaction de messages arbitraires. La valeur sûre est construite par Config avant qu'un diagnostic ne l'utilise.
## Clarification `KSP_LOGS_DIRECTORY`
La décision préparatoire de l'adapter `pre.012` est enregistrée dans le plan :
- après interpolation, `logs_directory` pourra être absolu ou relatif ;
- un chemin relatif sera interprété relativement au current working directory du processus qui initialise Logging, pas automatiquement au répertoire du binaire ;
- le fallback `logs` s'applique seulement si `KSP_LOGS_DIRECTORY` est absent ;
- une valeur explicitement présente mais invalide ne déclenche pas le fallback et devra produire un diagnostic de configuration effective invalide ;
- les paths de sinks restent relatifs sous `logs_directory` sans traversal.
Aucun code de validation/conversion Logging correspondant n'est ajouté dans `pre.011`; cette responsabilité appartient à `pre.012`.
## `.env.example`
Aucune nouvelle variable runtime n'est introduite.
`.env.example` reste donc inchangé et contient toujours la seule variable actuellement utilisée :
```text
KSP_LOGS_DIRECTORY=logs
```
## Dépendances
Aucune dépendance ou feature Cargo n'est ajoutée/modifiée.
La direction reste :
```text
ksp-config-lib -> ksp-logging-lib -> ksp-core-lib
ksp-config-lib -> ksp-core-lib
```
Logging ne dépend toujours pas de Config.
## Version technique
La prerelease devient :
```text
workspace.package.version = "0.1.3-pre.11"
Cargo.toml header version = 54
```
## Fichiers ajoutés
```text
crates/ksp-config-lib/src/sensitivity.rs
crates/ksp-config-lib/unit_tests/sensitivity.rs
deltas/0.1.3/pre.011.md
```
## Fichiers modifiés
```text
Cargo.toml
crates/ksp-config-lib/src/environment.rs
crates/ksp-config-lib/src/lib.rs
crates/ksp-config-lib/src/profile.rs
crates/ksp-config-lib/tests/public_api.rs
crates/ksp-config-lib/unit_tests/environment.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/RULES_KSP.md
```
## Fichiers supprimés
Aucun.
## Contrôles exécutés dans l'environnement de génération
- comparaison statique avec la base validée `pre.010-fix.001` ;
- absence de nouvelle dépendance/feature Cargo ;
- absence de nouvelle variable runtime nécessitant une modification de `.env.example` ;
- audit statique du nouveau code Config contre `unsafe`, `unwrap`, `expect`, `panic!` et opérateur `?` de production ;
- contrôle des headers/version ;
- contrôle des lignes Rust à 160 colonnes maximum ;
- contrôle canary dans les tests : les représentations safe/Debug attendues ne contiennent pas le secret ;
- reproduction du delta sur la base précédente avant packaging.
Le toolchain Rust n'est pas disponible dans l'environnement de génération. `cargo fmt/check/clippy/test` doivent donc être exécutés par l'utilisateur.
## Étape suivante
Après validation utilisateur :
```text
0.1.3-pre.012 — adapter Config -> Logging
```
Cette tranche devra notamment valider/résoudre `logs_directory`, convertir le profil Logging effectif vers les contrats publics `ksp_logging_lib::*` et démontrer `initialize/reinitialize` sans créer de dépendance Logging -> Config.