v0.2.5-pre.010.fix.003
This commit is contained in:
@@ -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"
|
||||
|
||||
133
deltas/0.2.5/pre.010-fix.003.md
Normal file
133
deltas/0.2.5/pre.010-fix.003.md
Normal 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.
|
||||
@@ -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
|
||||
|
||||
@@ -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 :
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user