v0.2.13-pre.002

This commit is contained in:
2026-08-28 04:31:32 +02:00
parent 9148920f42
commit 99477d0d2b
10 changed files with 434 additions and 23 deletions

View File

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

View File

@@ -0,0 +1,14 @@
# file: crates/ksp-interface-lib/Cargo.toml
# version: 1
[package]
name = "ksp-interface-lib"
version.workspace = true
edition.workspace = true
repository.workspace = true
[dependencies]
ksp-core-lib = { path = "../ksp-core-lib" }
[lints]
workspace = true

View File

@@ -0,0 +1,32 @@
<!-- file: crates/ksp-interface-lib/README.md -->
<!-- version: 1 -->
# ksp-interface-lib
`ksp-interface-lib` est la façade KSP destinée aux contrats wire passifs des programmes Solana. Elle est conçue pour être consommée par les implémentations Program officielles ou externes sans absorber Transport, Wallet, Store, Config ni le comportement métier Program.
## Ownership
La crate réutilise les primitives fondamentales déjà possédées par `ksp-core-lib`, notamment `Pubkey`. Les Program IDs fondamentaux restent également dans Core. Interface possédera progressivement les layouts, discriminants, codecs et constructeurs wire uniquement lorsqu'un protocole réel les exige.
La foundation ne dépend pas de runtime réseau ou applicatif. Elle n'ajoute donc pas de logging runtime, de scheduler, de persistence ou de configuration.
## Surface initiale
La façade crate-root expose actuellement le `Pubkey` canonique de Core. Les contrats passifs d'instruction et d'account meta sont introduits séparément afin de fermer leurs bornes et leur surface publique avant les premières APIs Program.
## Frontières
`ksp-interface-lib` ne possède pas :
```text
RPC / WebSocket / gRPC
wallet / signature
persistence / Store
Config / environnement
interprétation métier Program
execution policy
lifecycle réseau
```
La conception détaillée de la foundation est suivie dans [`../../docs/plans/020-V0_2_13_INTERFACE_PLAN.md`](../../docs/plans/020-V0_2_13_INTERFACE_PLAN.md) et sa validation dans [`../../docs/validation/016-V0_2_13_INTERFACE.md`](../../docs/validation/016-V0_2_13_INTERFACE.md).

View File

@@ -0,0 +1,24 @@
<!-- file: crates/ksp-interface-lib/USAGE.md -->
<!-- version: 1 -->
# Usage de ksp-interface-lib
Cette page décrit la surface publique actuellement matérialisée par la foundation Interface. Les APIs d'instruction sont ajoutées progressivement sans exposer les modules internes.
## Utiliser le Pubkey canonique
Interface réexporte le `Pubkey` possédé par Core afin que les futurs contrats wire puissent partager la même primitive sans wrapper parallèle :
```rust
let program_id = ksp_interface_lib::Pubkey::default();
let bytes = program_id.to_bytes();
assert_eq!(bytes.len(), 32);
```
Un consumer ne doit pas reconstruire une identité Program textuelle propre à Interface. Les Program IDs fondamentaux restent possédés et répertoriés par `ksp-core-lib`.
## Surface volontairement absente
La foundation initiale n'expose encore aucun constructeur d'instruction fonctionnel. Elle ne fournit pas non plus de codec générique Borsh/Wincode, de sérialisation Serde, de transport ou de comportement Program. Ces surfaces sont ajoutées uniquement lorsque leur contrat réel est matérialisé et borné.
Aucun runtime logging n'est nécessaire pour les contrats passifs actuels ; une future instrumentation comportementale devrait passer par `ksp-logging-lib` selon les règles KSP au lieu d'introduire `tracing` directement.

View File

@@ -0,0 +1,16 @@
// file: crates/ksp-interface-lib/src/lib.rs
// version: 1
#![warn(missing_docs)]
#![deny(unreachable_pub)]
#![forbid(unsafe_code)]
//! Passive wire contracts shared by KSP Program implementations.
//!
//! The foundation deliberately starts with the canonical Solana [`Pubkey`]
//! owned by `ksp-core-lib`. Program-facing instruction contracts are added in
//! later slices without introducing runtime, transport, persistence or Program
//! behavior into Interface.
/// Canonical Solana account address primitive owned by `ksp-core-lib`.
pub use ksp_core_lib::Pubkey;

View File

@@ -0,0 +1,79 @@
// file: crates/ksp-interface-lib/tests/dependency_boundary.rs
// version: 1
//! Dependency and passive-surface canaries for the Interface scaffold.
#[test]
fn pre_002_manifest_has_exact_core_only_runtime_dependency() {
let manifest = include_str!("../Cargo.toml");
let dependencies_tail = manifest.split("[dependencies]").nth(1);
assert!(dependencies_tail.is_some(), "Interface dependencies section must exist");
let dependencies_tail = match dependencies_tail {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
let dependencies = match dependencies_tail.split("[lints]").next() {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
assert_eq!(manifest_dependency_names(dependencies), std::vec!["ksp-core-lib"]);
for forbidden in [
"ksp-config-lib",
"ksp-logging-lib",
"ksp-offchain-transport-lib",
"ksp-onchain-transport-lib",
"ksp-program-api",
"ksp-program-lib",
"ksp-store-api",
"ksp-store-lib",
"ksp-wallet-lib",
"borsh",
"bincode",
"reqwest",
"serde",
"serde_json",
"solana-instruction",
"tauri",
"tokio",
"tonic",
"tracing",
"wincode",
] {
assert!(!dependencies.contains(forbidden), "forbidden Interface dependency detected: {forbidden}");
}
return;
}
#[test]
fn pre_002_scaffold_remains_passive_without_runtime_logging_surface() {
let crate_root = include_str!("../src/lib.rs");
assert!(crate_root.contains("pub use ksp_core_lib::Pubkey;"));
assert!(!crate_root.contains("ProgramAccountMeta"));
assert!(!crate_root.contains("ProgramInstruction"));
assert!(!crate_root.contains("TRACING_TARGET"));
assert!(!crate_root.contains("ksp_logging_lib"));
assert!(!std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("src/constants.rs").exists());
return;
}
fn manifest_dependency_names(section: &str) -> std::vec::Vec<&str> {
let mut names = std::vec::Vec::new();
for line in section.lines() {
let content = match line.split('#').next() {
std::option::Option::Some(value) => value.trim(),
std::option::Option::None => continue,
};
if content.is_empty() {
continue;
}
let name = match content.split('=').next() {
std::option::Option::Some(value) => value.trim().trim_end_matches(".workspace"),
std::option::Option::None => continue,
};
if !name.is_empty() {
names.push(name);
}
}
names.sort_unstable();
return names;
}

View File

@@ -0,0 +1,15 @@
// file: crates/ksp-interface-lib/tests/public_api.rs
// version: 1
//! Integration canaries for the public `ksp-interface-lib` scaffold.
fn consume_pubkey(pubkey: ksp_interface_lib::Pubkey) -> [u8; 32] {
return pubkey.to_bytes();
}
#[test]
fn public_pre_002_pubkey_contract_is_available_from_crate_root() {
let pubkey = ksp_interface_lib::Pubkey::default();
assert_eq!(consume_pubkey(pubkey), [0_u8; 32]);
return;
}

205
deltas/0.2.13/pre.002.md Normal file
View File

@@ -0,0 +1,205 @@
<!-- file: deltas/0.2.13/pre.002.md -->
<!-- version: 1 -->
# Delta `0.2.13-pre.002` — scaffold `ksp-interface-lib`
## 1. Base requise
Cette tranche s'applique exclusivement sur :
```text
v0.2.12
+ 0.2.13-pre.001
```
Le gate opérateur fourni pour `pre.001` est intégralement vert : `cargo fmt --all`, audits Rust/Markdown, `cargo check --workspace`, Clippy workspace et `cargo test --workspace` passent.
La version workspace passe de :
```text
0.2.13-pre.1
```
à :
```text
0.2.13-pre.2
```
## 2. Objectif
Créer uniquement le scaffold de `ksp-interface-lib` et verrouiller sa frontière avant les types wire fonctionnels.
La tranche matérialise :
```text
nouveau membre workspace ksp-interface-lib
manifest avec ksp-core-lib comme seule dépendance normale
façade crate-root explicite
réexport contrôlé de ksp_core_lib::Pubkey
README/USAGE initiaux
canari public API minimal
canari dependency firewall
```
Elle ne matérialise pas encore :
```text
ProgramAccountMeta
ProgramInstruction
bornes instruction
codes d'erreur Interface
serde / serde_json
borsh / bincode / wincode
solana-instruction
network/runtime
Program behavior
```
## 3. Décision Logging
`0.2.13` reste une foundation de contrats passifs. Aucun comportement runtime n'est actuellement prévu dans `ksp-interface-lib`, donc aucun événement/span n'a besoin d'être émis.
En conséquence, la tranche maintient explicitement absents :
```text
ksp-logging-lib
src/constants.rs
TRACING_TARGET
tracing direct
```
Cette absence est volontaire et couverte par le canari de dépendances. Si un comportement runtime réel apparaît dans une future évolution d'Interface, l'instrumentation devra être ajoutée via `ksp-logging-lib`; `DEP-LOG-010` imposera alors un `pub(crate) const TRACING_TARGET: &str` possédé par `src/constants.rs`.
Les futures validations de bornes de `pre.003`/`pre.004` doivent retourner des erreurs structurées ; elles ne justifient pas à elles seules des logs runtime.
## 4. Surface publique de scaffold
La seule primitive publique nouvellement exposée est :
```rust
pub use ksp_core_lib::Pubkey;
```
Ce réexport confirme l'ownership décidé : Interface n'introduit aucun wrapper `ProgramId`/`Pubkey` parallèle et utilisera la primitive Core dans ses futurs contrats wire.
La façade ne contient aucun `pub mod`. Les types d'instruction restent absents pour éviter d'avancer `pre.003`/`pre.004`.
## 5. Dependency firewall
Le manifest membre possède exactement :
```text
[dependencies]
ksp-core-lib = { path = "../ksp-core-lib" }
```
Le canari `tests/dependency_boundary.rs` vérifie notamment l'absence de :
```text
ksp-logging-lib
ksp-program-*
ksp-*-transport-lib
ksp-config-lib
ksp-store-*
ksp-wallet-lib
serde / serde_json
borsh / bincode / wincode
solana-instruction
reqwest / tokio / tonic / tauri / tracing
```
Il verrouille aussi l'absence de `src/constants.rs` et `TRACING_TARGET` tant que la crate reste passive.
## 6. Tests ajoutés
`tests/public_api.rs` vérifie que le `Pubkey` canonique est consommable uniquement depuis le crate-root Interface.
`tests/dependency_boundary.rs` vérifie :
```text
dépendance normale exacte = ksp-core-lib
absence des dépendances interdites
absence de ProgramAccountMeta/ProgramInstruction en pre.002
absence de surface Logging runtime
```
Aucun unit test métier n'est ajouté : aucune primitive fonctionnelle n'existe encore.
## 7. Fichiers ajoutés
```text
crates/ksp-interface-lib/Cargo.toml
crates/ksp-interface-lib/README.md
crates/ksp-interface-lib/USAGE.md
crates/ksp-interface-lib/src/lib.rs
crates/ksp-interface-lib/tests/dependency_boundary.rs
crates/ksp-interface-lib/tests/public_api.rs
deltas/0.2.13/pre.002.md
```
## 8. Fichiers modifiés
```text
Cargo.toml
docs/plans/020-V0_2_13_INTERFACE_PLAN.md
docs/validation/016-V0_2_13_INTERFACE.md
```
## 9. Fichiers volontairement inchangés
```text
README.md
ROADMAP.md
CHANGELOG.md
.env.example
docs/architecture/**
docs/rules/**
crates/ksp-core-lib/**
crates/ksp-logging-lib/**
crates/ksp-onchain-transport-lib/**
crates/ksp-offchain-transport-lib/**
crates/ksp-config-lib/**
crates/ksp-wallet-lib/**
crates/ksp-app-*/**
prompts/**
```
Aucune architecture durable n'est rouverte : le graphe `Interface -> Core`, avec Logging uniquement lorsqu'un runtime logging réel existe, est déjà documenté.
## 10. Validations de génération
Les audits Python sont rejoués sur l'arbre matérialisé avant livraison. Le sandbox de génération ne fournit pas `cargo`, `rustc` ou `rustfmt`; aucun PASS Cargo nouveau n'est donc revendiqué localement.
## 11. Gate opérateur attendu
Après application :
```bash
cargo fmt --all
python3 scripts/audit_rust_workspace_rules.py
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas/0.2.13
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-interface-lib
cargo test --workspace
cargo tree -p ksp-interface-lib --edges normal
cargo tree --duplicates
```
Le `cargo tree -p ksp-interface-lib --edges normal` doit montrer Core comme unique dépendance KSP directe et ne doit pas révéler de codec/runtime ajouté par Interface.
Une correction découverte par ce gate reste un `0.2.13-pre.002-fix.NNN` et n'avance pas `pre.003`.
## 12. Suite
Après gate vert, `pre.003` pourra matérialiser uniquement :
```text
ProgramAccountMeta
constante de borne account metas
modèle d'erreur Interface minimal nécessaire
unit/public canaries correspondants
```
`ProgramInstruction`, sa data bound et son Debug résumé restent réservés à `pre.004`.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/020-V0_2_13_INTERFACE_PLAN.md -->
<!-- version: 1 -->
<!-- version: 2 -->
# Plan `0.2.13` — Interface / wire foundation
@@ -377,13 +377,13 @@ Le scope réduit permet de supprimer le second lot wire optionnel du forecast in
### pre.001 — audit + héritage + frontières + sizing
**Statut : EN COURS / sortie du présent delta**
**Statut : réalisé ; gate opérateur `pre.001` intégralement PASS.**
Relire les règles/architectures, auditer Core/Transport, classer kbot3, auditer les candidates externes, retenir la surface instruction passive, fixer bornes/firewall/threat model/tests et créer plan/validation.
### pre.002 — scaffold `ksp-interface-lib` + façade + firewall
**Statut : pvu**
**Statut : réalisé ; gate opérateur à confirmer.**
Créer la crate, l'ajouter au workspace, poser `lib.rs` avec exports explicites, lints, README/USAGE initiaux et canaris manifest/firewall. Dépendance normale unique : `ksp-core-lib`.
@@ -461,19 +461,21 @@ plan + validation créés
implementation Program absente
```
## 16. Gate attendu pour `pre.002`
## 16. Gate attendu pour `pre.003`
`pre.002` peut commencer si le présent delta est appliqué et le gate opérateur est vert. Il doit rester un scaffold strict :
`pre.002` matérialise le scaffold strict décidé par le gate précédent :
```text
nouvelle crate membre ksp-interface-lib
Cargo dépend uniquement de ksp-core-lib
lints workspace hérités
crate root explicite sans pub mod
Pubkey réexporté depuis Core
README/USAGE initiaux
canari public API minimal
canari dependency firewall
aucun ProgramAccountMeta/ProgramInstruction fonctionnel si le scaffold suffit à la tranche
aucun ProgramAccountMeta/ProgramInstruction fonctionnel
aucun ksp-logging-lib / constants.rs / TRACING_TARGET
```
Aucune question ouverte ne bloque `pre.002`.
`pre.003` peut commencer après application du delta et gate opérateur vert. Sa responsabilité reste limitée à `ProgramAccountMeta`, aux bornes communes et au modèle d'erreur Interface minimal ; `ProgramInstruction` reste réservé à `pre.004`.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/validation/016-V0_2_13_INTERFACE.md -->
<!-- version: 1 -->
<!-- version: 2 -->
# Validation `0.2.13` — Interface / wire foundation
@@ -85,9 +85,9 @@ aucun comportement Program
| Contrat | Attendu final `0.2.13` | Statut |
|----------------------|--------------------------------------------------------|------------------|
| crate | `ksp-interface-lib` membre workspace | TODO pre.002 |
| façade | exports explicites crate-root; aucun `pub mod` | TODO pre.002+ |
| Pubkey | réexport/usage contrôlé de Core; pas de type parallèle | TODO pre.002/003 |
| crate | `ksp-interface-lib` membre workspace | PASS pre.002 |
| façade | exports explicites crate-root; aucun `pub mod` | PASS pre.002 |
| Pubkey | réexport/usage contrôlé de Core; pas de type parallèle | PASS pre.002 |
| `ProgramAccountMeta` | private fields + writable/readonly + accessors | TODO pre.003 |
| `ProgramInstruction` | private fields + `try_new` + accessors | TODO pre.004 |
| account bound | `<= 255` | TODO pre.003/004 |
@@ -141,11 +141,11 @@ Si une nouvelle dépendance externe apparaît après `pre.001`, la présente mat
## 10. Tests de release
| Famille | Attendu | Statut |
|--------------------------|------------------------------------------------|--------|
|--------------------------|------------------------------------------------|--------------|
| unit tests privés | constructeurs/bornes/order/debug/errors | TODO |
| `tests/public_api.rs` | consommation crate-root uniquement | TODO |
| `tests/public_api.rs` | consommation crate-root uniquement | PASS pre.002 |
| external consumer canary | surface utilisable hors modules privés | TODO |
| dependency boundary | firewall exact | TODO |
| dependency boundary | firewall exact | PASS pre.002 |
| release completeness | inventaire exact, aucun domaine supplémentaire | TODO |
| round-trip codec | aucun tant qu'aucun codec | N/A |
| network smoke | aucun pour crate wire pure | N/A |
@@ -189,3 +189,27 @@ Aucun smoke réseau/live n'est exigé par défaut.
| implémentation Program lourde | ABSENTE |
Le passage à `pre.002` est autorisé après application du delta et validation opérateur. Le statut des items d'implémentation reste volontairement `TODO` jusqu'aux tranches correspondantes.
## 13. État préparé `pre.002`
Le scaffold matérialisé conserve volontairement une surface minimale :
```text
workspace member PASS structurel
normal dependency ksp-core-lib uniquement
Pubkey réexport Core au crate-root
public modules aucun
ProgramAccountMeta absent par contrat pre.002
ProgramInstruction absent par contrat pre.002
serde / borsh / bincode / wincode absents
network/runtime dependencies absentes
ksp-logging-lib absent
constants.rs / TRACING_TARGET absents
README / USAGE initiaux
public API canary présent
dependency firewall canary présent
```
Le logging reste volontairement absent : la foundation `0.2.13` est passive et n'émet aucun événement/span runtime. Si une future surface comportementale démontre un besoin réel de logging, `ksp-logging-lib`, `src/constants.rs` et `TRACING_TARGET` devront être introduits ensemble conformément à `DEP-LOG-004` et `DEP-LOG-010`.
Le passage à `pre.003` reste conditionné au gate opérateur complet sur l'overlay `pre.002`.