v0.1.4-pre.002
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
# file: Cargo.toml
|
||||
# version: 62
|
||||
# version: 63
|
||||
|
||||
[workspace]
|
||||
resolver = "3"
|
||||
members = ["crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-logging-lib"]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.1.4-pre.1"
|
||||
version = "0.1.4-pre.2"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: crates/ksp-config-lib/README.md -->
|
||||
<!-- version: 1 -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# ksp-config-lib
|
||||
|
||||
@@ -12,7 +12,7 @@ La crate centralise les documents JSON, leurs schemas, les profils et compositio
|
||||
`ksp-config-lib` possède :
|
||||
|
||||
- le bootstrap non récursif `config/` / `config/schemas/` et les overrides `--cfgpath` / `--schemapath` ;
|
||||
- le registre logique `file_id -> filename` et les overrides `--filemap=<file_id>=<filename>` ;
|
||||
- le registre logique `file_id -> filename`, son inventaire public read-only ordonné par `file_id` et les overrides `--filemap=<file_id>=<filename>` ;
|
||||
- la lecture JSON et la validation JSON Schema Draft 2020-12 ;
|
||||
- les invariants sémantiques KSP des documents connus ;
|
||||
- les globals, `default_profile`, profils nommés et leur provenance ;
|
||||
@@ -27,7 +27,7 @@ La crate centralise les documents JSON, leurs schemas, les profils et compositio
|
||||
- les écritures atomiques JSON/`.env` et la protection des permissions `.env` ;
|
||||
- les audits workspace empêchant les bypass d'ownership Config et les oublis dans `.env.example`.
|
||||
|
||||
## Ressources gérées dans `0.1.3`
|
||||
## Ressources gérées
|
||||
|
||||
Le registre par défaut connaît :
|
||||
|
||||
@@ -37,6 +37,8 @@ schema.std.logging -> config/schemas/std.logging.schema.json
|
||||
schema.composite -> config/schemas/composite.schema.json
|
||||
```
|
||||
|
||||
`ConfigFileRegistry::descriptors()` expose ces descripteurs en lecture seule et dans un ordre déterministe par `file_id`. Une application de management peut ainsi découvrir les fichiers connus sans maintenir une liste parallèle ni dépendre de leurs filenames physiques.
|
||||
|
||||
`config/examples/composite.example.json` démontre le format composite sans créer de composite runtime fictif.
|
||||
|
||||
Le fichier local d'environnement est :
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: crates/ksp-config-lib/TODO.md -->
|
||||
<!-- version: 1 -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# TODO ksp-config-lib
|
||||
|
||||
@@ -9,7 +9,13 @@ Aucun TODO fonctionnel bloquant n'est ouvert pour la fondation Config `0.1.3`.
|
||||
|
||||
Les responsabilités prévues pour cette release sont implémentées et couvertes par les tests : bootstrap, registre `file_id`, JSON/JSON Schema, profils, composites, environnement process/`.env`, placeholders, sensibilité/provenance, adapter Logging, management/persistence et audits d'ownership.
|
||||
|
||||
## Reporté explicitement à `0.1.4`
|
||||
## Extensions bornées révélées par `0.1.4`
|
||||
|
||||
`0.1.4-pre.002` ajoute l'inventaire public read-only de `ConfigFileRegistry`, nécessaire au shell Documents de `ksp-app-config-desk`. Le registre reste propriétaire des descripteurs ; l'application n'entretient pas de liste parallèle de `file_id`.
|
||||
|
||||
La seconde lacune révélée pendant `pre.001` reste à traiter dans la tranche suivante : une API Config bornée permettant de soumettre le source corrigé d'un `file_id` connu, le valider puis le persister atomiquement sans accès filesystem direct de l'application.
|
||||
|
||||
## Validation desktop de `0.1.4`
|
||||
|
||||
La validation applicative desktop appartient à `ksp-app-config-desk` :
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: crates/ksp-config-lib/USAGE.md -->
|
||||
<!-- version: 2 -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Utilisation de ksp-config-lib
|
||||
|
||||
@@ -33,6 +33,22 @@ Les arguments compris par Config sont :
|
||||
|
||||
`cfgpath` et `schemapath` ne sont jamais lus depuis JSON, `.env` ou une variable KSP : cette règle évite un bootstrap récursif.
|
||||
|
||||
### 1.1 Inventorier les fichiers enregistrés
|
||||
|
||||
Le registre expose une vue read-only déterministe des descripteurs connus :
|
||||
|
||||
```rust
|
||||
for descriptor in registry.descriptors() {
|
||||
let file_id = descriptor.file_id().as_str();
|
||||
let kind = descriptor.kind();
|
||||
let filename = descriptor.filename();
|
||||
let schema_file_id = descriptor.schema_file_id();
|
||||
let _ = (file_id, kind, filename, schema_file_id);
|
||||
}
|
||||
```
|
||||
|
||||
L'ordre est celui des `file_id`. La vue reflète les éventuels overrides `--filemap` déjà appliqués tout en conservant le kind et l'association de schema. Elle permet notamment à une application de management de construire sa liste de documents/schemas sans dupliquer le registre dans sa propre couche.
|
||||
|
||||
## 2. Charger et valider un document connu
|
||||
|
||||
Les consumers utilisent un `file_id` logique :
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-config-lib/src/registry.rs
|
||||
// version: 3
|
||||
// version: 4
|
||||
|
||||
/// Bootstrap argument used to replace a known Config filename mapping.
|
||||
pub const ARG_FILE_MAP: &str = "--filemap";
|
||||
@@ -165,6 +165,13 @@ impl ConfigFileRegistry {
|
||||
return std::result::Result::Ok(registry);
|
||||
}
|
||||
|
||||
/// Iterates over all registered descriptors in deterministic logical `file_id` order.
|
||||
///
|
||||
/// The returned view is read-only and reflects filename overrides already applied to this registry.
|
||||
pub fn descriptors(&self) -> impl std::iter::Iterator<Item = &ConfigFileDescriptor> + '_ {
|
||||
return self.descriptors.values();
|
||||
}
|
||||
|
||||
/// Returns the descriptor associated with a known logical file identifier.
|
||||
pub fn descriptor(&self, file_id: &ConfigFileId) -> ksp_core_lib::Result<&ConfigFileDescriptor> {
|
||||
return match self.descriptors.get(file_id) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-config-lib/tests/public_api.rs
|
||||
// version: 10
|
||||
// version: 11
|
||||
|
||||
//! Integration tests for the public `ksp-config-lib` bootstrap, registry, JSON/profile/composite, environment-resolution, sensitivity, Logging-adapter and
|
||||
//! management contracts.
|
||||
@@ -74,6 +74,25 @@ fn logical_file_registry_is_available_from_crate_root() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn registry_descriptor_inventory_is_available_from_crate_root() {
|
||||
let registry = ksp_config_lib::ConfigFileRegistry::defaults();
|
||||
assert!(registry.is_ok(), "public registry should remain constructible: {registry:?}");
|
||||
if let std::result::Result::Ok(registry) = registry {
|
||||
let descriptors: std::vec::Vec<&ksp_config_lib::ConfigFileDescriptor> = registry.descriptors().collect();
|
||||
assert_eq!(descriptors.len(), 3);
|
||||
assert_eq!(descriptors[0].file_id().as_str(), ksp_config_lib::FILE_ID_STD_LOGGING);
|
||||
assert_eq!(descriptors[0].kind(), ksp_config_lib::ConfigFileKind::Config);
|
||||
assert_eq!(descriptors[1].file_id().as_str(), ksp_config_lib::FILE_ID_SCHEMA_COMPOSITE);
|
||||
assert_eq!(descriptors[2].file_id().as_str(), ksp_config_lib::FILE_ID_SCHEMA_STD_LOGGING);
|
||||
let schema_file_id = descriptors[0].schema_file_id();
|
||||
assert!(schema_file_id.is_some(), "public descriptor inventory should preserve schema association");
|
||||
if let std::option::Option::Some(schema_file_id) = schema_file_id {
|
||||
assert_eq!(schema_file_id.as_str(), ksp_config_lib::FILE_ID_SCHEMA_STD_LOGGING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validated_json_document_engine_is_available_from_crate_root() {
|
||||
let workspace = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../..");
|
||||
|
||||
@@ -1,5 +1,58 @@
|
||||
// file: crates/ksp-config-lib/unit_tests/registry.rs
|
||||
// version: 3
|
||||
// version: 4
|
||||
|
||||
#[test]
|
||||
fn descriptors_expose_complete_registry_in_deterministic_file_id_order() {
|
||||
let registry = super::ConfigFileRegistry::defaults();
|
||||
assert!(registry.is_ok(), "default registry should be valid: {registry:?}");
|
||||
if let std::result::Result::Ok(registry) = registry {
|
||||
let descriptors: std::vec::Vec<&super::ConfigFileDescriptor> = registry.descriptors().collect();
|
||||
assert_eq!(descriptors.len(), 3);
|
||||
assert_eq!(descriptors[0].file_id().as_str(), super::FILE_ID_STD_LOGGING);
|
||||
assert_eq!(descriptors[0].kind(), super::ConfigFileKind::Config);
|
||||
assert_eq!(descriptors[0].filename(), std::path::Path::new(super::DEFAULT_STD_LOGGING_FILENAME));
|
||||
let schema_file_id = descriptors[0].schema_file_id();
|
||||
assert!(schema_file_id.is_some(), "logging descriptor should expose its validation schema");
|
||||
if let std::option::Option::Some(schema_file_id) = schema_file_id {
|
||||
assert_eq!(schema_file_id.as_str(), super::FILE_ID_SCHEMA_STD_LOGGING);
|
||||
}
|
||||
assert_eq!(descriptors[1].file_id().as_str(), super::FILE_ID_SCHEMA_COMPOSITE);
|
||||
assert_eq!(descriptors[1].kind(), super::ConfigFileKind::Schema);
|
||||
assert_eq!(descriptors[2].file_id().as_str(), super::FILE_ID_SCHEMA_STD_LOGGING);
|
||||
assert_eq!(descriptors[2].kind(), super::ConfigFileKind::Schema);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn descriptors_reflect_filename_overrides_without_changing_logical_metadata() {
|
||||
let registry = super::ConfigFileRegistry::defaults();
|
||||
let file_id = super::ConfigFileId::new(super::FILE_ID_STD_LOGGING);
|
||||
assert!(registry.is_ok(), "default registry should be valid: {registry:?}");
|
||||
assert!(file_id.is_ok(), "logging file_id should be valid: {file_id:?}");
|
||||
if let (std::result::Result::Ok(registry), std::result::Result::Ok(file_id)) = (registry, file_id) {
|
||||
let overridden = registry.with_filename_override(&file_id, "profiles/desktop.logging.json");
|
||||
assert!(overridden.is_ok(), "filename override should remain valid: {overridden:?}");
|
||||
if let std::result::Result::Ok(overridden) = overridden {
|
||||
let mut found: std::option::Option<&super::ConfigFileDescriptor> = std::option::Option::None;
|
||||
for descriptor in overridden.descriptors() {
|
||||
if descriptor.file_id() == &file_id {
|
||||
found = std::option::Option::Some(descriptor);
|
||||
}
|
||||
}
|
||||
assert!(found.is_some(), "public descriptor inventory should retain the overridden logging descriptor");
|
||||
if let std::option::Option::Some(descriptor) = found {
|
||||
assert_eq!(descriptor.file_id(), &file_id);
|
||||
assert_eq!(descriptor.kind(), super::ConfigFileKind::Config);
|
||||
assert_eq!(descriptor.filename(), std::path::Path::new("profiles/desktop.logging.json"));
|
||||
let schema_file_id = descriptor.schema_file_id();
|
||||
assert!(schema_file_id.is_some(), "filename override should preserve schema association");
|
||||
if let std::option::Option::Some(schema_file_id) = schema_file_id {
|
||||
assert_eq!(schema_file_id.as_str(), super::FILE_ID_SCHEMA_STD_LOGGING);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn defaults_register_logging_document_and_schema_with_distinct_roots() {
|
||||
|
||||
194
deltas/0.1.4/pre.002.md
Normal file
194
deltas/0.1.4/pre.002.md
Normal file
@@ -0,0 +1,194 @@
|
||||
<!-- file: deltas/0.1.4/pre.002.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.1.4-pre.002 — inventaire public du registre Config
|
||||
|
||||
## Base requise
|
||||
|
||||
```text
|
||||
0.1.4-pre.001-fix.003
|
||||
workspace.package.version = "0.1.4-pre.1"
|
||||
```
|
||||
|
||||
Le plan `docs/plans/006-V0_1_4_CONFIG_DESKTOP_PLAN.md` est considéré comme validé dans sa révision issue de `pre.001-fix.003`.
|
||||
|
||||
## Objectif
|
||||
|
||||
Traiter la première lacune `ksp-config-lib` identifiée par `pre.001` avant la construction du shell desktop : permettre à un consumer de management d'inventorier les fichiers enregistrés dans `ConfigFileRegistry` sans maintenir une liste parallèle de `file_id` et sans obtenir de capacité de mutation supplémentaire.
|
||||
|
||||
Cette tranche reste volontairement limitée à l'inventaire public du registre. La soumission/réparation d'un source candidat invalide reste réservée à `pre.003`.
|
||||
|
||||
## Version Cargo
|
||||
|
||||
Conformément à `VER-ID-009`, `workspace.package.version` passe de :
|
||||
|
||||
```text
|
||||
0.1.4-pre.1
|
||||
```
|
||||
|
||||
à :
|
||||
|
||||
```text
|
||||
0.1.4-pre.2
|
||||
```
|
||||
|
||||
L'identifiant de livraison est :
|
||||
|
||||
```text
|
||||
0.1.4-pre.002
|
||||
```
|
||||
|
||||
## 1. API publique du registre
|
||||
|
||||
`ConfigFileRegistry` expose désormais :
|
||||
|
||||
```rust
|
||||
pub fn descriptors(&self) -> impl std::iter::Iterator<Item = &ConfigFileDescriptor> + '_
|
||||
```
|
||||
|
||||
Le contrat est volontairement read-only :
|
||||
|
||||
- aucun descripteur n'est copié dans une seconde structure propriétaire ;
|
||||
- aucune mutation du registre n'est exposée ;
|
||||
- l'itération reflète les éventuels overrides de filename déjà appliqués ;
|
||||
- `file_id`, `kind` et association de schema restent ceux du descripteur enregistré ;
|
||||
- l'ordre est déterministe et correspond à l'ordre logique des `ConfigFileId` porté par le `BTreeMap` interne.
|
||||
|
||||
Avec le registre par défaut actuel, l'ordre est :
|
||||
|
||||
```text
|
||||
cfg.std.logging
|
||||
schema.composite
|
||||
schema.std.logging
|
||||
```
|
||||
|
||||
L'API ne crée pas de DTO applicatif. `ksp-app-config-desk` pourra convertir ces descripteurs vers ses propres DTO Tauri dans sa frontière applicative.
|
||||
|
||||
## 2. Tests unitaires
|
||||
|
||||
`unit_tests/registry.rs` couvre maintenant explicitement :
|
||||
|
||||
- l'inventaire complet du registre par défaut ;
|
||||
- l'ordre déterministe par `file_id` ;
|
||||
- le `ConfigFileKind` de chaque famille ;
|
||||
- l'association `cfg.std.logging -> schema.std.logging` ;
|
||||
- la conservation de ces métadonnées après un override de filename ;
|
||||
- la visibilité du filename effectivement overridé depuis l'inventaire.
|
||||
|
||||
Les tests existants de lookup, résolution de path, validation des mappings, doublons et associations de schema restent inchangés dans leur responsabilité.
|
||||
|
||||
## 3. Test de surface publique
|
||||
|
||||
`tests/public_api.rs` vérifie que le consumer externe peut appeler `ConfigFileRegistry::descriptors()` depuis la racine de crate et exploiter les `ConfigFileDescriptor` publics sans accès à une API interne.
|
||||
|
||||
Le test couvre l'ordre et les métadonnées nécessaires au futur panneau Documents de Config Desk.
|
||||
|
||||
## 4. Documentation Config
|
||||
|
||||
`README.md` précise maintenant que le registre possède un inventaire public read-only ordonné par `file_id`.
|
||||
|
||||
`USAGE.md` ajoute un exemple version-neutral montrant comment parcourir :
|
||||
|
||||
- `file_id` ;
|
||||
- `kind` ;
|
||||
- filename courant ;
|
||||
- schema associé éventuel.
|
||||
|
||||
`TODO.md` distingue désormais les deux lacunes révélées par `0.1.4` :
|
||||
|
||||
- inventaire public du registre : **traité par `pre.002`** ;
|
||||
- réparation/persistence d'un source candidat par `file_id` connu : **reste à traiter dans `pre.003`**.
|
||||
|
||||
## 5. Ownership et extensibilité
|
||||
|
||||
Cette tranche conserve les frontières décidées :
|
||||
|
||||
```text
|
||||
ConfigFileRegistry
|
||||
-> possède les descripteurs connus
|
||||
-> expose leur inventaire read-only
|
||||
|
||||
ksp-app-config-desk
|
||||
-> consommera l'inventaire
|
||||
-> construira ses DTO applicatifs
|
||||
-> ne maintiendra pas de liste parallèle de file_id
|
||||
```
|
||||
|
||||
L'ajout futur d'un nouveau descripteur au registre le rendra donc automatiquement découvrable par le shell de management, indépendamment de la présence ou non d'un éditeur spécialisé pour ce `file_id`.
|
||||
|
||||
## Hors scope confirmé
|
||||
|
||||
Cette tranche n'ajoute pas :
|
||||
|
||||
- `ksp-app-config-desk` ;
|
||||
- Tauri ou dépendance frontend ;
|
||||
- DTO TS-RS ;
|
||||
- API de modification arbitraire du registre ;
|
||||
- API de réparation/persistence de source candidat ;
|
||||
- nouveau document Config ou nouveau schema ;
|
||||
- variable `.env` ;
|
||||
- modification du runtime Logging.
|
||||
|
||||
## Fichiers ajoutés
|
||||
|
||||
```text
|
||||
deltas/0.1.4/pre.002.md
|
||||
```
|
||||
|
||||
## Fichiers modifiés
|
||||
|
||||
| Fichier | Version précédente | Nouvelle version |
|
||||
|------------------------------------------------|-------------------:|-----------------:|
|
||||
| `Cargo.toml` | 62 | 63 |
|
||||
| `crates/ksp-config-lib/src/registry.rs` | 3 | 4 |
|
||||
| `crates/ksp-config-lib/unit_tests/registry.rs` | 3 | 4 |
|
||||
| `crates/ksp-config-lib/tests/public_api.rs` | 10 | 11 |
|
||||
| `crates/ksp-config-lib/README.md` | 1 | 2 |
|
||||
| `crates/ksp-config-lib/USAGE.md` | 2 | 3 |
|
||||
| `crates/ksp-config-lib/TODO.md` | 1 | 2 |
|
||||
|
||||
## Fichiers supprimés
|
||||
|
||||
Aucun.
|
||||
|
||||
## Validations exécutées
|
||||
|
||||
Dans l'environnement de préparation disponible :
|
||||
|
||||
- contrôle statique du diff borné à l'inventaire du registre ;
|
||||
- vérification de `workspace.package.version = "0.1.4-pre.2"` ;
|
||||
- vérification des headers `file:` / `version:` des fichiers modifiés ;
|
||||
- vérification de l'absence de `?`, `unwrap`, `expect`, `panic` et `unsafe` dans le nouveau code Rust ;
|
||||
- vérification des lignes Rust modifiées vis-à-vis de la limite KSP de 160 colonnes ;
|
||||
- vérification de la documentation publique de `ConfigFileRegistry::descriptors()` ;
|
||||
- vérification que les tests couvrent ordre, kind, schema et override ;
|
||||
- vérification syntaxique TOML du `Cargo.toml` avec le parseur disponible ;
|
||||
- contrôle des fences Markdown et des espaces de fin de ligne dans les fichiers livrés.
|
||||
|
||||
## Validations non exécutées
|
||||
|
||||
Le sandbox de préparation ne fournit pas les binaires Rust/Cargo. Les validations obligatoires suivantes ne peuvent donc pas être exécutées ici :
|
||||
|
||||
```text
|
||||
cargo fmt --all
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets
|
||||
cargo test -p ksp-config-lib
|
||||
cargo tree -p ksp-config-lib
|
||||
```
|
||||
|
||||
Elles doivent être exécutées sur le workspace de développement après application du delta et avant validation/commit de `pre.002`.
|
||||
|
||||
`cargo test --workspace` n'est pas requis pour cette tranche ciblée selon le plan de `0.1.4`; il reste réservé aux frontières globales justifiées et à la clôture de la release.
|
||||
|
||||
## Décisions prises
|
||||
|
||||
- l'inventaire reste une vue du registre existant, pas une collection dupliquée ;
|
||||
- l'ordre public est déterministe par `file_id` ;
|
||||
- les overrides restent visibles sans altérer l'identité logique et les associations de schema ;
|
||||
- aucun DTO Config spécifique au desktop n'entre dans `ksp-config-lib` ;
|
||||
- `pre.003` reste la tranche dédiée à la réparation validée/persistée d'un source candidat.
|
||||
|
||||
## Questions ouvertes
|
||||
|
||||
Aucune question bloquante pour `pre.002`.
|
||||
Reference in New Issue
Block a user