v0.2.5-pre.010.fix.003

This commit is contained in:
2026-08-20 12:15:36 +02:00
parent 08c8046262
commit cb142b1cb8
5 changed files with 156 additions and 25 deletions

View File

@@ -1,12 +1,12 @@
# file: Cargo.toml
# version: 161
# version: 162
[workspace]
resolver = "3"
members = ["crates/ksp-app-config-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-logging-lib", "crates/ksp-onchain-transport-lib", "crates/ksp-wallet-lib"]
[workspace.package]
version = "0.2.5-pre.10.fix.2"
version = "0.2.5-pre.10.fix.3"
edition = "2024"
license = "MIT"
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"

View File

@@ -0,0 +1,133 @@
<!-- file: deltas/0.2.5/pre.010-fix.003.md -->
<!-- version: 1 -->
# Delta `0.2.5-pre.010-fix.003` — alignement audit Rust sur rustfmt et TODO prix offchain
## 1. Base et version
Base :
```text
0.2.5-pre.010-fix.002
workspace.package.version = 0.2.5-pre.10.fix.2
```
Version technique cible :
```text
workspace.package.version = 0.2.5-pre.10.fix.3
```
Identifiant de livraison :
```text
0.2.5-pre.010-fix.003
```
Commit attendu après validation :
```text
v0.2.5-pre.010-fix.003
```
Aucun tag stable n'est créé par ce fix et `rel.001` reste bloqué jusqu'à validation complète.
## 2. Cause du fix
Après application de `fix.002`, l'opérateur a exécuté la séquence canonique :
```bash
cargo fmt --all
python3 scripts/audit_rust_workspace_rules.py
```
`cargo fmt` a produit un ordre valide et canonique dans les façades, mais l'audit Python a ensuite signalé 52 violations `RUST-FMT-107` parce qu'il imposait son propre tri alphabétique par **symbole exporté**.
Ce contrôle était incorrect : l'audit structurel ne doit pas réimplémenter un ordre de réexports différent de celui possédé par rustfmt.
Les contrôles Rust/Cargo du même checkpoint étaient par ailleurs verts : `cargo check --workspace`, Clippy, tests Wallet et tests workspace complets passent.
## 3. Correction de l'audit des réexports
`RUST-FMT-107` est retiré de `audit_rust_general_rules.py`.
Le script continue de vérifier les contraintes structurelles que rustfmt ne possède pas :
```text
pub use avant pub(crate) use
exactement une ligne vide entre les deux visibilités
aucune ligne vide à l'intérieur d'un bloc homogène
pas de grouped use/re-export
pas de glob
pas d'alias
réexports internes via self::
rustdoc adjacente
résolution crate-root via l'audit de complétude
```
En revanche, l'ordre intra-bloc des `use`/réexports est désormais explicitement délégué à :
```bash
cargo fmt --all
```
Le script ne tente plus de trier par symbole exporté ni de reproduire l'algorithme de rustfmt.
## 4. Règles Rust synchronisées
`RULES_RUST.md` précise désormais que :
- `rustfmt.toml` et `cargo fmt --all` sont canoniques pour l'ordre interne des `use`/réexports ;
- `RUST-FMT-005` n'impose pas son tri générique aux `use`/réexports ;
- `RUST-FMT-007` ne possède que la structure `pub` / `pub(crate)` et l'espacement ;
- `RUST-AUDIT-003` interdit explicitement au script de réimplémenter un ordre concurrent à rustfmt.
## 5. TODO `0.2.11` ajouté au prompt `0.2.6`
Le prompt `prompts/011-V0_2_6_START_PROMPT.md` contient maintenant un TODO durable :
```text
0.2.11
après réalisation et validation de l'application spécialisée de visualisation
de prix offchain, intégrer cette capacité dans ksp-app-wallet-desk
```
Le TODO précise que `0.2.6` ne doit pas anticiper cette logique et que `0.2.11` devra réauditer la frontière de partage afin de ne pas dupliquer récupération, normalisation, cache ou contrats de prix dans Wallet Desk.
## 6. Périmètre
Ce fix ne modifie :
```text
aucun fichier Rust
aucune API runtime
aucun wire .kspwallet
aucune dépendance
aucune primitive cryptographique
```
Le bump Cargo est requis parce que le script d'audit fait partie du toolchain de validation technique KSP.
## 7. Validation de préparation
Les scripts Python modifiés doivent passer :
```bash
python3 -m py_compile scripts/audit_rust_general_rules.py
python3 scripts/audit_rust_workspace_rules.py
```
La validation opérateur canonique doit impérativement conserver `cargo fmt --all` **avant** l'audit structurel afin de vérifier que le script accepte exactement l'état formaté par rustfmt.
## 8. Validation opérateur requise
```bash
cargo fmt --all
python3 scripts/audit_rust_workspace_rules.py
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-wallet-lib
cargo test --workspace
```
Les arbres de dépendances ne nécessitent pas d'être répétés pour ce fix : aucune dépendance n'est modifiée.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/rules/RULES_RUST.md -->
<!-- version: 7 -->
<!-- version: 8 -->
# Règles Rust générales
@@ -55,9 +55,9 @@ Les règles `RUST-*` s'appliquent à tous les fichiers Rust de KSP : crates, sou
- **RUST-FMT-002** — `cargo fmt --all` est exécuté après chaque modification Rust avant l'audit structurel et les validations Cargo.
- **RUST-FMT-003** — Aucune ligne vide n'est conservée à l'intérieur du corps d'une fonction ou méthode, ni à l'intérieur d'une définition `struct` ou `enum`.
- **RUST-FMT-004** — Deux fonctions ou méthodes distinctes, y compris deux `const fn`, sont séparées par exactement une ligne vide. La même séparation exacte s'applique entre `struct`, `enum`, `union`, `trait`, bloc `impl` et fonction/méthode lorsqu'ils constituent des items voisins d'un même scope.
- **RUST-FMT-005** — Les blocs homogènes sont ordonnés alphabétiquement par nom lorsque l'ordre n'a pas de signification sémantique.
- **RUST-FMT-005** — Les blocs homogènes sont ordonnés alphabétiquement par nom lorsque l'ordre n'a pas de signification sémantique. Cette règle ne redéfinit pas l'ordre interne des `use`/réexports : pour ceux-ci, la sortie de `cargo fmt --all` est canonique.
- **RUST-FMT-006** — Les constantes de module ou associées sont ordonnées par visibilité `pub`, puis `pub(crate)`, puis privée, et alphabétiquement dans chaque niveau. Deux constantes de même visibilité appartenant au même bloc ne sont séparées par aucune ligne vide ; exactement une ligne vide sépare deux niveaux de visibilité distincts.
- **RUST-FMT-007** — Dans une façade, le bloc `pub use` précède le bloc `pub(crate) use`; une seule ligne vide sépare les deux blocs, aucune ligne vide n'existe à l'intérieur d'un bloc, et les symboles sont ordonnés alphabétiquement.
- **RUST-FMT-007** — Dans une façade, le bloc `pub use` précède le bloc `pub(crate) use`; une seule ligne vide sépare les deux blocs et aucune ligne vide n'existe à l'intérieur d'un bloc. L'ordre intra-bloc des `use`/réexports est celui produit par `cargo fmt --all`; l'audit Python ne lui substitue aucun tri concurrent par symbole exporté ou chemin source.
- **RUST-FMT-008** — Les déclarations `mod` d'un même bloc sont ordonnées alphabétiquement ; les modules de tests conditionnels restent après les modules de production.
- **RUST-FMT-009** — Lorsqu'un `struct` et ses blocs `impl` forment une unité locale sans contrainte de séparation, l'implémentation suit la structure. Les éléments visibles précèdent les helpers privés lorsqu'aucun ordre métier ou protocolaire n'impose l'inverse.
- **RUST-FMT-010** — L'ordre alphabétique n'écrase jamais un ordre contractuel ou sémantique : wire fields, comptes Solana, étapes de protocole, priorités, transitions d'état, tableaux de dispatch et séquences explicitement normatives conservent leur ordre défini.
@@ -102,7 +102,7 @@ Les règles `RUST-*` s'appliquent à tous les fichiers Rust de KSP : crates, sou
- **RUST-AUDIT-001** — `scripts/audit_rust_workspace_rules.py` est le point d'entrée obligatoire de l'audit Rust KSP. Il exécute les audits généraux, la complétude des réexports/chemins et les frontières KSP sans fusionner leurs responsabilités.
- **RUST-AUDIT-002** — L'audit est dependency-free côté Python standard et échoue avec un code non nul dès qu'une violation mécanique est détectée.
- **RUST-AUDIT-003** — L'audit contrôle au minimum : headers/version/newline, lints de crate-root, visibilité interdite, `use`/aliases/groupes/globs/scope, rustdocs visibles, ordre des imports/réexports/constantes, lignes vides dans fonctions/structs/enums, complétude des réexports crate-root, chemins `crate::module::Item`, usage de `super::` dans les tests séparés et frontières KSP directement vérifiables.
- **RUST-AUDIT-003** — L'audit contrôle au minimum : headers/version/newline, lints de crate-root, visibilité interdite, `use`/aliases/groupes/globs/scope, rustdocs visibles, structure des blocs de réexports, ordre des imports de traits et constantes lorsque KSP le possède, lignes vides dans fonctions/structs/enums, complétude des réexports crate-root, chemins `crate::module::Item`, usage de `super::` dans les tests séparés et frontières KSP directement vérifiables. L'ordre intra-bloc des `use`/réexports reste la responsabilité canonique de `cargo fmt --all` et n'est pas réimplémenté par le script.
- **RUST-AUDIT-004** — Les règles contextuelles qui ne peuvent pas être prouvées sans interpréter la sémantique restent des critères de revue humaine ; le script ne doit pas produire de faux sentiment de complétude.
## Contrôle avant livraison

View File

@@ -1,5 +1,5 @@
<!-- file: prompts/011-V0_2_6_START_PROMPT.md -->
<!-- version: 2 -->
<!-- version: 3 -->
# Prompt de démarrage `0.2.6` — Wallet Desk
@@ -668,6 +668,12 @@ trading
Le Wallet Desk valide et administre Wallet ; il ne devient pas l'application globale KSP.
### TODO futur `0.2.11` — prix offchain dans Wallet Desk
La visualisation de prix offchain n'appartient pas au scope de `0.2.6`. Une application spécialisée de visualisation de prix offchain doit d'abord être réalisée et valider durablement ses sources, contrats, rafraîchissement, cache et UX.
Pour `0.2.11`, prévoir explicitement un chantier d'intégration de cette capacité dans `ksp-app-wallet-desk` afin qu'un wallet puisse afficher les informations de prix offchain pertinentes sans dupliquer la logique de récupération/normalisation possédée par le composant spécialisé. Le futur travail devra réauditer la frontière entre application, bibliothèque/service partagé et Transport avant implémentation ; le TODO n'autorise pas l'ajout anticipé de logique de prix dans Wallet Desk pendant `0.2.6`.
## 25. Résultat attendu de `0.2.6`
À la clôture stable :

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env python3
# file: scripts/audit_rust_general_rules.py
# version: 4
# version: 5
"""Audit mechanically verifiable Rust normalization rules used by KSP."""
@@ -186,13 +186,6 @@ def preceding_doc_line(lines: list[str], index: int) -> bool:
return cursor >= 0 and lines[cursor].lstrip().startswith("///")
def export_symbol(line: str) -> str:
"""Return the re-exported symbol name from one ungrouped re-export."""
path = line.split(" use ", 1)[1].split(";", 1)[0].strip()
return path.rsplit("::", 1)[-1]
def natural_key(value: str) -> tuple[tuple[int, object], ...]:
"""Return a natural case-sensitive ordering key."""
@@ -523,12 +516,12 @@ def audit_file(root: pathlib.Path, path: pathlib.Path) -> list[Violation]:
for attribute in ("#![warn(missing_docs)]", "#![deny(unreachable_pub)]", "#![forbid(unsafe_code)]"):
if attribute not in lines[:24]:
violations.append(Violation("RUST-BASE-103", relative, 1, f"missing `{attribute}`"))
exports: list[tuple[int, str, str]] = []
exports: list[tuple[int, str]] = []
for idx, line in enumerate(lines, 1):
stripped = line.strip()
if stripped.startswith("pub use ") or stripped.startswith("pub(crate) use "):
visibility = "pub(crate)" if stripped.startswith("pub(crate) use ") else "pub"
exports.append((idx, visibility, export_symbol(stripped)))
exports.append((idx, visibility))
if not preceding_doc_line(lines, idx):
violations.append(Violation("RUST-DOC-102", relative, idx, "crate-root re-export requires adjacent rustdoc"))
source_match = re.match(r"^pub(?:\(crate\))?\s+use\s+(?:self::)?([A-Za-z_][A-Za-z0-9_]*)::", stripped)
@@ -544,22 +537,21 @@ def audit_file(root: pathlib.Path, path: pathlib.Path) -> list[Violation]:
if blank_count != 1:
violations.append(Violation("RUST-FMT-113", relative, crate_start, f"pub use and pub(crate) use blocks require exactly one blank line; found {blank_count}"))
crate_seen = False
previous_by_visibility: dict[str, tuple[int, str]] = {}
for idx, visibility, symbol in exports:
previous_by_visibility: dict[str, int] = {}
for idx, visibility in exports:
if visibility == "pub(crate)":
crate_seen = True
elif crate_seen:
violations.append(Violation("RUST-FMT-105", relative, idx, "pub use block must precede pub(crate) use block"))
previous = previous_by_visibility.get(visibility)
if previous is not None:
previous_idx, previous_symbol = previous
previous_idx = previous_by_visibility.get(visibility)
if previous_idx is not None:
# One homogeneous block may contain rustdocs but no blank line.
# rustfmt is authoritative for intra-block re-export ordering;
# this audit must not impose a competing exported-symbol sort.
between = lines[previous_idx:idx - 1]
if any(not candidate.strip() for candidate in between):
violations.append(Violation("RUST-FMT-106", relative, idx, f"{visibility} use block contains an empty line"))
if natural_key(symbol) < natural_key(previous_symbol):
violations.append(Violation("RUST-FMT-107", relative, idx, f"{visibility} use block is not alphabetically ordered by exported symbol"))
previous_by_visibility[visibility] = (idx, symbol)
previous_by_visibility[visibility] = idx
violations.extend(audit_blank_lines_in_bodies(relative, lines, masked_lines, depths))
violations.extend(audit_item_spacing_and_nesting(relative, lines, masked_lines, depths))
violations.extend(audit_module_order(relative, lines, depths))