Files
2026-08-16 10:40:23 +02:00

9.5 KiB

Delta 0.1.4-pre.003 — réparation validée d'un source Config

Base requise

0.1.4-pre.002
workspace.package.version = "0.1.4-pre.2"

pre.002 est considéré comme validé et commité après exécution locale de cargo fmt, cargo check, Clippy, des tests ciblés ksp-config-lib et de cargo tree -p ksp-config-lib.

Objectif

Fermer la seconde lacune ksp-config-lib identifiée pendant pre.001 avant la construction de ksp-app-config-desk : permettre à une application de management de corriger le texte brut d'un document Config invalide sans obtenir d'accès filesystem direct ni reproduire le parsing, la validation JSON Schema ou les invariants sémantiques de Config.

Cette tranche reste bornée à la persistence d'un document de kind Config déjà enregistré dans ConfigFileRegistry. Les schemas restent read-only depuis cette surface et aucun path arbitraire n'est accepté.

Version Cargo

Conformément à VER-ID-009, workspace.package.version passe de :

0.1.4-pre.2

à :

0.1.4-pre.3

L'identifiant de livraison est :

0.1.4-pre.003

1. API publique de réparation

ConfigManagement expose désormais :

pub fn save_source_candidate(
    &self,
    file_id: &ConfigFileId,
    source: &str,
) -> ksp_core_lib::Result<ConfigDocumentChangeReport>

Le workflow est :

file_id enregistré de kind Config
    -> résolution du path par ConfigFileRegistry
    -> parsing JSON du texte candidat
    -> validation du schema enregistré
    -> validation des invariants sémantiques KSP
    -> comparaison aux octets existants
    -> persistence atomique uniquement si le candidat est valide et différent

L'appelant ne fournit jamais de path physique.

Un file_id inconnu est rejeté par le registre. Un file_id de kind Schema est rejeté par la façade de management. Cette surface ne constitue donc pas une primitive de write générique.

2. Conservation du source brut

Contrairement à save_logging_document(), qui sérialise volontairement son contrat typé en JSON pretty-printé, save_source_candidate() persiste le texte brut validé exactement tel qu'il a été soumis.

Cette différence est intentionnelle : le workflow Documents de Config Desk doit pouvoir afficher un fichier invalide, laisser l'opérateur corriger son source, puis le sauvegarder sans reformattage implicite supplémentaire.

Le candidat reste néanmoins interprété et validé par ksp-config-lib; la conservation du formatting ne déplace aucune autorité de validation vers l'UI.

3. Validation du candidat dans le moteur documentaire

ConfigDocumentEngine possède maintenant une petite primitive interne validate_source_candidate() qui :

  • résout le path logique nécessaire aux diagnostics ;
  • parse le texte via serde_json ;
  • produit le même ERROR_CODE_JSON_SYNTAX_INVALID que la lecture documentaire normale ;
  • délègue ensuite à la validation candidate existante pour le schema et les invariants sémantiques.

Cette fonction reste pub(crate) : la surface publique de mutation est ConfigManagement, pas le moteur brut.

4. Persistence partagée

La comparaison du source existant et l'appel à persistence::atomic_write() sont regroupés dans un helper privé de management commun à :

  • save_source_candidate() ;
  • save_logging_document().

Le contrat existant de la sauvegarde Logging ne change pas : elle continue de pretty-printer et d'ajouter un newline final avant d'utiliser la même étape de persistence.

ConfigDocumentChangeReport conserve sa sémantique :

  • source identique -> source_changed = false, reload_required = false ;
  • source validé et remplacé -> source_changed = true, reload_required = true.

5. No-write-on-error

Les tests couvrent séparément les échecs avant persistence :

  • JSON syntaxiquement invalide -> ERROR_CODE_JSON_SYNTAX_INVALID ;
  • document ne satisfaisant pas le schema -> ERROR_CODE_SCHEMA_VALIDATION_FAILED ;
  • document schema-valid mais sémantiquement invalide -> ERROR_CODE_DOCUMENT_SEMANTIC_INVALID.

Dans les trois cas, les octets du fichier existant sont comparés avant/après et doivent rester strictement identiques.

Un test de réparation part d'un fichier physiquement corrompu puis soumet un candidat valide. La sauvegarde doit réussir, conserver exactement le texte candidat et rendre le document de nouveau chargeable via load_logging_document().

6. Bornage par registre

Les tests vérifient également :

  • refus d'un schema.std.logging par ERROR_CODE_MANAGEMENT_OPERATION_INVALID ;
  • refus d'un cfg.not.registered par ERROR_CODE_FILE_ID_UNKNOWN ;
  • absence de création d'un fichier dérivé du texte du file_id inconnu.

La signature publique ne contient aucun Path/PathBuf, ce qui maintient l'ownership du mapping physique dans ConfigFileRegistry.

7. Surface publique

tests/public_api.rs compile la signature de ConfigManagement::save_source_candidate() depuis la racine de crate avec :

  • ConfigManagement ;
  • ConfigFileId ;
  • ConfigDocumentChangeReport.

Aucun nouveau DTO ou type public n'est nécessaire.

8. Documentation Config

README.md documente maintenant la paire :

read_source()
    -> inspection brute même si invalide

save_source_candidate()
    -> parse + schema + sémantique + persistence atomique

USAGE.md ajoute le workflow version-neutral de réparation et précise la différence entre source brut et sauvegarde Logging typée.

TODO.md marque les deux extensions Config préalables au desktop comme traitées :

  • inventaire du registre par pre.002 ;
  • réparation validée du source par pre.003.

Hors scope confirmé

Cette tranche n'ajoute pas :

  • ksp-app-config-desk ;
  • Tauri ou dépendance frontend ;
  • DTO TS-RS ;
  • édition de schemas ;
  • JSON Patch générique ;
  • path physique fourni par l'appelant ;
  • nouveau document Config/schema ;
  • variable .env ;
  • watcher filesystem ;
  • reload runtime Logging.

Fichiers ajoutés

deltas/0.1.4/pre.003.md

Fichiers modifiés

Fichier Version précédente Nouvelle version
Cargo.toml 63 64
crates/ksp-config-lib/src/document.rs 4 5
crates/ksp-config-lib/src/management.rs 1 2
crates/ksp-config-lib/unit_tests/management.rs 1 2
crates/ksp-config-lib/tests/public_api.rs 11 12
crates/ksp-config-lib/README.md 2 3
crates/ksp-config-lib/USAGE.md 3 4
crates/ksp-config-lib/TODO.md 2 3

Fichiers supprimés

Aucun.

Validations exécutées dans l'environnement de préparation

  • contrôle statique du diff et du périmètre pre.003 ;
  • vérification de workspace.package.version = "0.1.4-pre.3" ;
  • vérification des headers file: / version: des fichiers modifiés ;
  • vérification de la limite KSP de 160 colonnes sur les fichiers Rust modifiés ;
  • vérification de l'absence d'ajout de dépendance ;
  • vérification que l'API publique n'accepte aucun path physique ;
  • vérification des cas de tests JSON/schema/sémantique/no-write, réparation valide et bornage file_id ;
  • vérification syntaxique TOML avec le parseur disponible ;
  • contrôle des fences Markdown et des espaces de fin de ligne des fichiers livrés.

Validations à exécuter localement

Le sandbox de préparation ne fournit pas les binaires Rust/Cargo. Avant validation/commit de pre.003, exécuter :

cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-config-lib
cargo tree -p ksp-config-lib

cargo test --workspace n'est pas requis pour cette tranche ciblée ; il reste réservé aux frontières globales prévues par le plan de 0.1.4.

Résultat attendu des nouveaux tests

Par rapport à pre.002, cette tranche ajoute cinq tests unitaires de management :

  1. réparation/persistence exacte d'un candidat valide ;
  2. rejet syntaxique sans write ;
  3. rejet schema sans write ;
  4. rejet sémantique sans write ;
  5. refus des file_id schema/inconnus comme cible de persistence Config.

Le nombre exact affiché par cargo test doit être relevé lors de la validation locale plutôt que codé comme invariant documentaire.

Décisions prises

  • le nom public retenu est ConfigManagement::save_source_candidate() ;
  • la mutation est générique par file_id, mais uniquement pour les documents de kind Config déjà enregistrés ;
  • le source brut validé est conservé tel quel ;
  • les sauvegardes typées spécialisées, comme Logging, peuvent conserver leur propre normalisation ;
  • schema et invariants sémantiques restent entièrement propriétaires de ksp-config-lib ;
  • aucune surface de write de schema ou de filesystem arbitraire n'est introduite.

Suite

Après validation et commit de pre.003, les deux prérequis Config révélés par pre.001 sont fermés. La tranche suivante prévue par le plan est 0.1.4-pre.004 : squelette Rust Tauri de ksp-app-config-desk, package mixte lib + bin, frontière tauri.rs, single-instance et builder construit par étapes courtes.