673 lines
40 KiB
Markdown
673 lines
40 KiB
Markdown
<!-- file: docs/plans/020-V0_2_13_INTERFACE_PLAN.md -->
|
||
<!-- version: 8 -->
|
||
|
||
# Plan `0.2.13` — Interface / wire foundation
|
||
|
||
## 1. Base, autorité et nature de `pre.001`
|
||
|
||
La release est ouverte exclusivement depuis l'archive opérateur `khadhroony-solana-project-v0.2.12.zip`, annoncée comme issue du tag stable `v0.2.12`. L'archive fournie ne contient pas de metadata `.git`; `git describe` n'est donc pas vérifiable dans le sandbox. Les marqueurs internes sont cohérents :
|
||
|
||
```text
|
||
workspace.package.version = 0.2.12
|
||
prompts/018-V0_2_13_START_PROMPT.md présent
|
||
deltas/0.2.12/rel.001.md présent
|
||
crates/ksp-interface-lib absent
|
||
crates/ksp-program-api absent
|
||
```
|
||
|
||
Le log opérateur joint à la reprise établit sur la base stable :
|
||
|
||
```text
|
||
cargo fmt --all PASS
|
||
python3 scripts/audit_rust_workspace_rules.py PASS
|
||
python3 scripts/audit_markdown_tables.py ... PASS
|
||
cargo check --workspace PASS
|
||
cargo clippy --workspace --all-targets PASS
|
||
cargo test --workspace PASS
|
||
```
|
||
|
||
Dans le sandbox de préparation, `cargo` n'est pas installé. Les audits Python de la base ont été rejoués et sont propres ; aucune commande Cargo non exécutée localement n'est déclarée PASS.
|
||
|
||
`0.2.13-pre.001` reste un gate de lecture/audit/sizing. Il ne crée pas encore `ksp-interface-lib` et ne porte aucun code de l'ancien dépôt.
|
||
|
||
## 2. Décision de scope
|
||
|
||
Le minimum retenu pour `0.2.13` est une foundation **Program-facing passive** :
|
||
|
||
```text
|
||
ProgramAccountMeta
|
||
ProgramInstruction
|
||
bornes locales explicites sur account metas et data
|
||
façade crate-root explicite
|
||
Error/Result communs via ksp-core-lib
|
||
aucun serde/codec générique ajouté sans protocole réel
|
||
aucun comportement Program
|
||
```
|
||
|
||
Cette surface correspond à la forme fondamentale d'une invocation Solana : identité du programme, comptes ordonnés avec flags signer/writable, puis octets opaques. Elle prépare directement la future construction d'instructions de `ksp-program-api` sans absorber le modèle d'acquisition/replay qui appartient à `0.3.2+`.
|
||
|
||
Le scope est volontairement réduit par rapport au forecast initial : `0.2.13` ne crée ni modèle canonique de transaction, ni replay input, ni logs/return-data génériques, ni CPI path, ni discriminant spécifique d'un programme tant qu'aucun vertical slice officiel ne le justifie.
|
||
|
||
## 3. Règles et architecture confrontées à la base réelle
|
||
|
||
Sources internes relues avant décision :
|
||
|
||
```text
|
||
RULES.md
|
||
docs/000-README.md
|
||
docs/rules/RULES_GENERAL.md
|
||
docs/rules/RULES_KSP.md
|
||
docs/rules/RULES_RUST.md
|
||
docs/rules/RULES_DEPENDENCIES.md
|
||
docs/rules/RULES_DOCUMENTATION.md
|
||
docs/rules/FILE_CONTRACTS.md
|
||
docs/rules/VERSION_WORKFLOW.md
|
||
docs/rules/PROMPT_STRUCTURE.md
|
||
docs/architecture/000-README.md
|
||
docs/architecture/001-PROJECT_OBJECTIVES.md
|
||
docs/architecture/002-LAYERS_AND_DEPENDENCIES.md
|
||
docs/architecture/003-COMPONENT_CONTRACTS.md
|
||
docs/architecture/004-COMPONENT_INVENTORY.md
|
||
docs/architecture/005-DEPENDENCY_GRAPH.md
|
||
docs/architecture/006-WIRE_AND_PROGRAM.md
|
||
docs/architecture/007-EXECUTION_AND_POLICY.md
|
||
docs/architecture/008-DATA_MATERIALIZATION_AND_STORE.md
|
||
docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md
|
||
docs/architecture/010-APPS_SERVICES_SCENARIOS_AND_CONTROL.md
|
||
docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md
|
||
ROADMAP.md
|
||
```
|
||
|
||
Les contraintes structurantes sont confirmées :
|
||
|
||
```text
|
||
Core possède Pubkey, Error/Result et les Program IDs fondamentaux
|
||
Interface possède/reexporte de manière contrôlée les contrats wire officiels
|
||
Program API pourra dépendre de Core + Interface, jamais l'inverse
|
||
Transport reste propriétaire des DTOs RPC/WS/gRPC et ne dépend pas d'Interface
|
||
RAW/CORE n'exige aucun decoder Program
|
||
0.3.2 étendra Interface pour les wires génériques d'acquisition/CORE
|
||
pas de pub mod ; exports explicites depuis crate root
|
||
pas de dépendance externe sans usage réel
|
||
```
|
||
|
||
## 4. Inventaire interne stable pertinent
|
||
|
||
### 4.1 Core
|
||
|
||
| Surface stable | Owner actuel | Visibilité/consumer | Décision `0.2.13` |
|
||
|----------------------------------|----------------|-----------------------------------------------|---------------------------------------------------------------------|
|
||
| `Pubkey` | `ksp-core-lib` | public crate-root; consommé dans le workspace | réutiliser directement; aucun wrapper Interface |
|
||
| `Error` / `ErrorCode` / `Result` | `ksp-core-lib` | public crate-root; contrat commun | réutiliser pour les erreurs de bornes Interface |
|
||
| 18 Program IDs + registry/filter | `ksp-core-lib` | public crate-root | laisser Core; Interface ne duplique pas les identités fondamentales |
|
||
|
||
Les anciens wrappers textuels `MdProgramId` / `MdPubkey` de kbot3 n'apportent donc aucune valeur à la frontière KSP actuelle : un `Pubkey` typé existe déjà et doit rester l'identité fondamentale.
|
||
|
||
### 4.2 Transport
|
||
|
||
| Type/famille observée | Owner actuel | Sémantique réelle | Décision |
|
||
|----------------------------------------------------------|-------------------------|--------------------------------------------------------|-------------------|
|
||
| `SolanaEncodedTransaction` | On-chain Transport HTTP | projection JSON-RPC encodée | laisser Transport |
|
||
| `SolanaConfirmedTransaction` / `SolanaBlockTransaction` | On-chain Transport HTTP | réponse RPC avec états wire/metadata provider | laisser Transport |
|
||
| `SolanaWireField<T>` | On-chain Transport HTTP | distinction omitted/null/value propre aux réponses RPC | laisser Transport |
|
||
| `YellowstoneCompiledInstruction` | On-chain Transport gRPC | projection protobuf Yellowstone | laisser Transport |
|
||
| `YellowstoneInnerInstructions` / `YellowstoneReturnData` | On-chain Transport gRPC | metadata d'update Geyser | laisser Transport |
|
||
| `YellowstoneTransactionError` / `...Meta` | On-chain Transport gRPC | sémantique provider/protobuf | laisser Transport |
|
||
|
||
Ces DTOs peuvent ressembler à de futurs objets génériques, mais ils représentent aujourd'hui des formes de transport concrètes. `0.2.13` ne les déplace pas et ne force aucune dépendance `Transport -> Interface`.
|
||
|
||
### 4.3 Dépendances workspace
|
||
|
||
La base possède déjà notamment :
|
||
|
||
```text
|
||
solana-pubkey = ^4.3, default-features = false
|
||
serde = ^1.0
|
||
serde_json = ^1.0
|
||
```
|
||
|
||
Aucun `solana-instruction`, `borsh`, `wincode` ou crate d'interface Program n'est actuellement nécessaire au nouveau lot. Le graphe cible initial reste donc `Interface -> Core` uniquement.
|
||
|
||
## 5. Audit d'héritage `khadhroony-bot3`
|
||
|
||
Archive auditée : `khadhroony-bot3_v0.5.3-pre.005-fix010.zip`.
|
||
|
||
Familles inspectées :
|
||
|
||
```text
|
||
ks-lib/src/model/solana.rs
|
||
ks-lib/src/model/canonical_transaction.rs
|
||
ks-lib/src/model/replay.rs
|
||
ks-lib/src/decoder/api/contracts.rs
|
||
ks-lib/src/executor/api/execution.rs
|
||
familles decoder/* wire pertinentes comme points de comparaison uniquement
|
||
```
|
||
|
||
La matrice suivante porte sur les **concepts**, pas sur un portage de code :
|
||
|
||
| Concept kbot3 | Verdict | Cible KSP | Raison |
|
||
|--------------------------------------------------------------|------------|----------------------------------|--------------------------------------------------------------------------------|
|
||
| account `{ pubkey, is_signer, is_writable }` ordonné | REPRENDRE | Interface `0.2.13` | forme passive fondamentale d'une instruction; retirer le naming execution |
|
||
| instruction `{ program_id, accounts, data }` | REPRENDRE | Interface `0.2.13` | forme officielle minimale; retirer `operation_code` et toute policy |
|
||
| `MdPubkey` / `MdProgramId` en `String` | REDESSINER | Core | remplacer par `ksp_core_lib::Pubkey` déjà possédé par Core |
|
||
| payload `Vec<u8>` non borné | REDESSINER | Interface `0.2.13` | ajouter admission bornée et Debug résumé |
|
||
| `DcApiInstructionDecoder` + recognition/outcomes/proofs | REPORTER | Program API `0.2.14` | comportement de reconnaissance/decode, interdit dans Interface |
|
||
| `MdInstructionPath` / parent / stack height | REPORTER | Interface/CORE `0.3.2+` | contexte d'acquisition/replay, pas nécessaire au builder Program minimal |
|
||
| logs / return data / tx failure / balance changes génériques | REPORTER | Interface/CORE `0.3.2+` | faits d'exécution/acquisition; ne pas préfigurer CORE |
|
||
| `MdCanonicalTransaction` + canonical JSON/hash | REPORTER | CORE series après `0.3.2` | modèle source-neutral large à redéfinir avec Store/CORE réels |
|
||
| `MdCoreInstructionReplayInput` | REPORTER | CORE/replay après RAW | contrat transversal trop large, dépend de données encore non possédées |
|
||
| Prepared plan, signers, fee payer, policies | REPORTER | Program API/Execution ultérieurs | responsabilité d'orchestration/exécution, pas wire passif |
|
||
| monolithe `ks-lib` + générations d'API coexistantes | REJETER | aucune | ownership flou et couplage vertical/horizontal à ne pas reproduire |
|
||
| version/hash/JSON génériques par réflexe | REJETER | aucune dans `0.2.13` | aucun contrat sérialisé ne justifie une enveloppe/version générique maintenant |
|
||
|
||
Anti-patterns à ne pas reproduire :
|
||
|
||
```text
|
||
wrappers Pubkey/ProgramId textuels alors qu'une primitive typée existe
|
||
serde dérivé sur tous les contrats sans frontière de sérialisation réelle
|
||
JSON Value comme échappatoire pour des formes structurelles futures
|
||
contrat replay géant utilisé comme point de rencontre de toutes les couches
|
||
operation_code/policy/signers mêlés à l'instruction passive
|
||
traits decoder dans la même crate que les wires
|
||
```
|
||
|
||
## 6. Audit externe actuel — 27 août 2026
|
||
|
||
L'audit externe est limité aux candidates réellement proches du lot retenu.
|
||
|
||
| Candidate | Version actuelle observée | Contrat / graphe | Décision |
|
||
|------------------------------|---------------------------|----------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------|
|
||
| `solana-instruction` | 3.5.0 | `Instruction { program_id: Pubkey, accounts: Vec<AccountMeta>, data: Vec<u8> }`; `solana-pubkey ^4.3.0`; codecs optionnels | référence normative; pas de dépendance runtime `0.2.13` |
|
||
| `solana-program` syscalls | 4.1.0 | `MAX_CPI_INSTRUCTION_ACCOUNTS = 255`; data `10 KiB`; account infos uniques `128` | source normative des plafonds d'admission initiaux; pas de dépendance |
|
||
| `solana-loader-v3-interface` | 8.1.1 | interface officielle; dépend `solana-instruction ^3.5.0` + `solana-pubkey ^4.3.0`; wincode optionnel | compatible en apparence mais hors premier lot; réauditer au vertical loader-v3 |
|
||
|
||
Sources primaires/current utilisées :
|
||
|
||
```text
|
||
https://docs.rs/solana-instruction/3.5.0/solana_instruction/struct.Instruction.html
|
||
https://docs.rs/solana-program/4.1.0/solana_program/syscalls/index.html
|
||
https://docs.rs/solana-loader-v3-interface/8.1.1/solana_loader_v3_interface/
|
||
https://github.com/anza-xyz/solana-sdk
|
||
```
|
||
|
||
`solana-instruction` 3.5.0 est Apache-2.0 via le workspace Anza. Ses features `serde`, `borsh`, `bincode` et `wincode` sont optionnelles. La génération `solana-pubkey ^4.3.0` est cohérente avec la base KSP.
|
||
|
||
La dépendance directe n'est néanmoins pas retenue maintenant : ses champs `Vec` publics ne permettent pas à KSP de garantir les bornes d'admission sur sa propre API, et aucun interop runtime ne requiert encore de convertir vers ce type. `DEP-KSP-005` impose de ne pas ajouter une dépendance seulement pour refléter une forme triviale que KSP doit de toute façon borner.
|
||
|
||
## 7. Matrice de frontières
|
||
|
||
| Concept/type | Owner cible | 0.2.13 ? | 0.2.14 ? | 0.3.2+ ? | Autorité / raison |
|
||
|-------------------------------------------------------------|----------------|----------|------------------|------------------------|-----------------------------------------------|
|
||
| `Pubkey` | Core | reuse | reuse | reuse | primitive fondamentale KSP déjà stable |
|
||
| Program IDs fondamentaux | Core | reuse | reuse | reuse | registry Core déjà stable |
|
||
| account meta d'instruction | Interface | OUI | consume | reuse | forme Solana officielle passive |
|
||
| instruction Program passive | Interface | OUI | consume | reuse | minimum nécessaire au futur preparer |
|
||
| codec/discriminant Program spécifique | Interface | NON | si vertical réel | selon besoin | aucun protocole concret dans foundation |
|
||
| instruction path / CPI ancestry | Interface/CORE | NON | NON requis | OUI | fait structurel d'acquisition/normalisation |
|
||
| logs / return data / tx failure / balance deltas génériques | Interface/CORE | NON | NON requis | OUI | surface RAW/CORE future |
|
||
| DTOs RPC/WS/Yellowstone existants | Transport | laisser | laisser | adapter plus tard | projection transport concrète |
|
||
| decoder identity/recognition/decode | Program API | NON | OUI audit | consume CORE plus tard | comportement extensible Program |
|
||
| implémentations officielles de programmes | Program Lib | NON | NON | plus tard | vertical slices distincts |
|
||
| RAW persistence | Store | NON | NON | `0.3.1` | architecture RAW |
|
||
| transaction/replay canonique générique | CORE | NON | NON | après `0.3.2` | doit être défini avec acquisition/Store réels |
|
||
|
||
## 8. Surface API proposée
|
||
|
||
Les noms restent ajustables jusqu'à implémentation, mais le contrat conceptuel est fermé :
|
||
|
||
```rust
|
||
pub use ksp_core_lib::Pubkey;
|
||
|
||
pub const MAX_PROGRAM_INSTRUCTION_ACCOUNTS: usize = 255;
|
||
pub const MAX_PROGRAM_INSTRUCTION_DATA_LEN: usize = 10 * 1024;
|
||
|
||
pub struct ProgramAccountMeta { /* private */ }
|
||
pub struct ProgramInstruction { /* private */ }
|
||
```
|
||
|
||
Façade visée :
|
||
|
||
```text
|
||
ProgramAccountMeta::writable(pubkey, is_signer)
|
||
ProgramAccountMeta::readonly(pubkey, is_signer)
|
||
ProgramAccountMeta::{pubkey,is_signer,is_writable}
|
||
|
||
ProgramInstruction::try_new(program_id, accounts, data) -> ksp_core_lib::Result<Self>
|
||
ProgramInstruction::{program_id,accounts,data}
|
||
```
|
||
|
||
Décisions de contrat :
|
||
|
||
- `Pubkey` est consommé via Core ; aucun `ProgramId` wrapper supplémentaire ;
|
||
- les comptes gardent exactement leur ordre et les doublons restent permis ;
|
||
- comptes vides et data vide restent valides ;
|
||
- aucune validation sémantique de Program ID, signer ou writable au-delà de la forme passive ;
|
||
- les champs restent privés afin d'empêcher la construction d'un état hors bornes ;
|
||
- la construction valide les longueurs sans cloner les vecteurs fournis ;
|
||
- `Debug` de `ProgramInstruction` doit résumer `program_id`, `account_count` et `data_len`, sans imprimer tout le payload ;
|
||
- pas de `serde::{Serialize, Deserialize}` dans la foundation : aucune persistence/IPC/wire sérialisée générique ne l'exige, et une dérive `Deserialize` naïve affaiblirait le gate de taille avant allocation ;
|
||
- aucun `borsh`, `bincode` ou `wincode` générique : les codecs arrivent avec un vrai protocole Program dans Interface ;
|
||
- pas de `format_version` artificiel tant qu'aucun format sérialisé KSP n'est défini.
|
||
|
||
### 8.1 Bornes
|
||
|
||
Les bornes initiales suivent les plafonds runtime Solana actuels :
|
||
|
||
```text
|
||
account metas d'une instruction <= 255
|
||
data d'une instruction <= 10_240 octets
|
||
```
|
||
|
||
Elles sont des **bornes d'admission Interface**, pas la promesse qu'une instruction seule rentrera dans toute transaction top-level. Les contraintes de message/transaction, comptes uniques, fee payer, blockhash et assembly appartiennent aux couches d'exécution ultérieures.
|
||
|
||
### 8.2 Erreurs
|
||
|
||
Le crate n'introduit pas un second type d'erreur. Les violations de borne utilisent `ksp_core_lib::Error/Result` avec codes Interface stables et contexte sûr limité aux longueurs/plafonds. Aucun octet du payload, compte arbitraire ou valeur externe n'est copié dans les diagnostics.
|
||
|
||
Les codes exacts seront matérialisés avec la première primitive ; deux catégories suffisent conceptuellement :
|
||
|
||
```text
|
||
invalid_program_instruction
|
||
program_instruction_limit_exceeded
|
||
```
|
||
|
||
Si la première implémentation démontre qu'une seule catégorie bornée suffit, ne pas créer la seconde par symétrie.
|
||
|
||
## 9. Threat / robustness model
|
||
|
||
| Risque | Décision | Canari prévu |
|
||
|-------------------------------------|------------------------------------------------------|------------------------------------------------------|
|
||
| data surdimensionnée | refus avant stockage/copie supplémentaire | `10_240` accepté; `10_241` refusé |
|
||
| collection accounts surdimensionnée | refus déterministe | `255` accepté; `256` refusé |
|
||
| conversion/index overflow | aucun cast étroit en foundation; comparer en `usize` | borne 255 + absence de casts unchecked |
|
||
| ordre/doublons accounts | préserver exactement; ne pas dédupliquer | ordre et doublon round-trip structurel via accessors |
|
||
| wire malformé | N/A : aucun decoder/codec dans le lot | aucun faux test; réouvrir au premier codec réel |
|
||
| enum/discriminant inconnu | N/A : aucun discriminant dans le lot | réouvrir au vertical Program |
|
||
| structures imbriquées pathologiques | N/A au-delà des deux Vec plates | bornes accounts/data suffisent pour ce lot |
|
||
| Debug volumineux | Debug résumé | payload sentinelle absent du rendu Debug |
|
||
| allocation/copie excessive | `try_new` consomme les Vec; pas de clone interne | canari structure/API + revue source |
|
||
| serde hostile | serde absent | dependency/public API canary |
|
||
| panic/unwrap/expect/? | interdits par règles/lints | audit Rust + Clippy workspace |
|
||
| Program ID inconnu | accepté : Pubkey opaque typé | canari avec Pubkey non registry |
|
||
|
||
## 10. Dependency graph cible et firewall
|
||
|
||
Cible de `0.2.13` :
|
||
|
||
```text
|
||
ksp-interface-lib
|
||
-> ksp-core-lib
|
||
-> solana-pubkey ^4.3
|
||
```
|
||
|
||
Interdictions :
|
||
|
||
```text
|
||
ksp-interface-lib -X-> ksp-program-api
|
||
ksp-interface-lib -X-> ksp-program-lib
|
||
ksp-interface-lib -X-> ksp-onchain-transport-lib
|
||
ksp-interface-lib -X-> ksp-offchain-transport-lib
|
||
ksp-interface-lib -X-> ksp-config-lib
|
||
ksp-interface-lib -X-> ksp-store-*
|
||
ksp-interface-lib -X-> ksp-wallet-lib
|
||
ksp-interface-lib -X-> Tauri
|
||
ksp-interface-lib -X-> reqwest/tonic/tokio/network
|
||
```
|
||
|
||
Aucun logging runtime n'est attendu dans une crate de contrats passifs. `ksp-logging-lib` reste absent sauf comportement futur démontré.
|
||
|
||
Validation Cargo prévue dès le scaffold :
|
||
|
||
```bash
|
||
cargo tree -p ksp-interface-lib --edges normal
|
||
cargo tree --duplicates
|
||
```
|
||
|
||
Comme aucune nouvelle dépendance externe n'est retenue au gate, aucun doublon codec/Solana ne doit être créé par `pre.002`.
|
||
|
||
## 11. Stratégie de tests
|
||
|
||
### Tests unitaires privés
|
||
|
||
Sous `unit_tests/` rattachés aux modules privés :
|
||
|
||
```text
|
||
constructeurs account meta writable/readonly
|
||
bornes comptes 255/256
|
||
bornes data 10_240/10_241
|
||
empty accounts/data acceptés
|
||
ordre et doublons préservés
|
||
Pubkey inconnu accepté
|
||
Debug borné et payload absent
|
||
erreurs sans bytes ni valeur hostile
|
||
```
|
||
|
||
### Tests d'intégration `tests/`
|
||
|
||
```text
|
||
public_api.rs consommation uniquement via crate-root
|
||
external_consumer.rs petit consumer/crate canary si le pattern workspace le permet
|
||
dependency_boundary.rs manifest/source firewall et absence de serde/codecs/network
|
||
release_completeness.rs inventaire exact de la surface 0.2.13 retenue
|
||
```
|
||
|
||
Aucun smoke réseau n'est requis. Aucun round-trip binaire/JSON n'est inventé sans codec réel.
|
||
|
||
## 12. Hors scope explicite
|
||
|
||
```text
|
||
ksp-program-api et tout trait decoder/preparer
|
||
ksp-program-lib
|
||
codec Program spécifique sans vertical réel
|
||
system/token/loader/metaplex instruction families
|
||
PDA seeds sans protocole concret
|
||
transaction/message/compiled instruction génériques d'acquisition
|
||
replay input / instruction path / CPI tree
|
||
logs / return data / transaction errors / balances génériques
|
||
Store/persistence
|
||
Transport refactor ou dépendance vers Interface
|
||
Wallet/Tauri/Config
|
||
serde/JSON canonical/hash
|
||
execution policy, signer selection, blockhash, simulation, send
|
||
```
|
||
|
||
## 13. Prévision souple recalibrée
|
||
|
||
Le scope réduit permet de supprimer le second lot wire optionnel du forecast initial et de garder des tranches compatibles avec le budget KSP de 15–20 minutes de travail effectif.
|
||
|
||
### pre.001 — audit + héritage + frontières + sizing
|
||
|
||
**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 : réalisé ; gate opérateur intégralement PASS.**
|
||
|
||
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`.
|
||
|
||
### pre.003 — `ProgramAccountMeta` + bornes communes
|
||
|
||
**Statut : réalisé ; fmt/audits/check/Clippy/tests Interface PASS, `cargo test --workspace` non fourni dans la preuve opérateur.**
|
||
|
||
Matérialiser la primitive de compte ordonné, la borne accounts, le modèle d'erreur Interface minimal et les unit/public canaries associés. `ProgramInstruction` et la borne data restent réservés à `pre.004`.
|
||
|
||
### pre.004 — `ProgramInstruction` passif borné
|
||
|
||
**Statut : réalisé ; gate opérateur intégralement PASS.**
|
||
|
||
Ajouter l'instruction `{ program_id, accounts, data }`, constructeur validé, accessors, Debug résumé et canaris d'ordre/doublons/limites. Aucun serde/codec ou comportement Program.
|
||
|
||
### pre.005 — adversarial + consumer externe + API/dependency hardening
|
||
|
||
**Statut : réalisé ; `pre.005-fix.001` validé, gate opérateur intégralement PASS.**
|
||
|
||
Fermer les cas limites, surface crate-root, consumer externe, firewall source/manifest et graphes Cargo. Ne pas ajouter un second domaine wire opportuniste.
|
||
|
||
### pre.006 — gate technique final
|
||
|
||
**Statut : réalisé ; gate opérateur intégralement PASS.**
|
||
|
||
Workspace complet, canaris de complétude/public API/dependencies, ownership Logging, `cargo tree` et audit final du scope exact sont validés. Aucun README/USAGE final ni préparation de publication n'a été mélangé à cette tranche.
|
||
|
||
### pre.007 — réconciliation documentaire finale
|
||
|
||
**Statut : réalisé ; gate opérateur documentaire à confirmer.**
|
||
|
||
README/USAGE Interface, plan, validation, séquence fonctionnelle et index documentaires réellement affectés sont réconciliés. `CHANGELOG.md`, `ROADMAP.md` et le prompt suivant restent réservés à `pre.008`.
|
||
|
||
### pre.008 — préparation de publication minimale
|
||
|
||
**Statut : prévu**
|
||
|
||
Préparer uniquement `prompts/019-V0_2_14_START_PROMPT.md`, `CHANGELOG.md`, `ROADMAP.md`, le bump prerelease mécanique et le delta. Aucun code/test/README/USAGE/plan/validation/architecture ne doit être rouvert.
|
||
|
||
### rel.001 — publication stable
|
||
|
||
**Statut : prévu**
|
||
|
||
Passer `workspace.package.version` à `0.2.13`, rejouer le gate stable requis, publier le commit `v0.2.13-rel.001` puis le tag stable `v0.2.13`.
|
||
|
||
## 14. Sizing et critère session
|
||
|
||
| Tranche | Charge relative | Motif du découpage |
|
||
|---------|------------------|----------------------------------|
|
||
| pre.002 | petite | scaffold + firewall uniquement |
|
||
| pre.003 | petite | une primitive + bornes/erreurs |
|
||
| pre.004 | petite à moyenne | instruction + hardening local |
|
||
| pre.005 | moyenne | consumer + adversarial + graphes |
|
||
| pre.006 | gate | aucun développement fonctionnel |
|
||
| pre.007 | documentation | réconciliation séparée |
|
||
| pre.008 | publication prep | payload minimal séparé |
|
||
|
||
Le scope paraît clôturable dans une release/session sans sacrifier les lanes de sortie. Si `pre.003` ou `pre.004` révèle qu'une dépendance/codec spécifique est indispensable, le gate doit être rouvert avant d'étendre le scope ; il ne faut pas réactiver automatiquement `pre.005` comme second lot wire.
|
||
|
||
## 15. Gate `0.2.13-pre.001`
|
||
|
||
À la sortie préparée :
|
||
|
||
```text
|
||
base stable / prompt / rel confirmé
|
||
règles et architecture obligatoires relues
|
||
Core / Transport inventoriés
|
||
archive kbot3 auditée
|
||
matrice REPRENDRE/REDESSINER/REPORTER/REJETER produite
|
||
0.2.13 / 0.2.14 / 0.3.2 séparés
|
||
premier lot ProgramAccountMeta + ProgramInstruction
|
||
nouvelle dépendance externe aucune
|
||
threat model / tests / dependency graph définis
|
||
plan + validation créés
|
||
implementation Program absente
|
||
```
|
||
|
||
## 16. Gate attendu pour `pre.003`
|
||
|
||
`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
|
||
aucun ksp-logging-lib / constants.rs / TRACING_TARGET
|
||
```
|
||
|
||
`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`.
|
||
|
||
## 17. État préparé `pre.003`
|
||
|
||
`pre.003` matérialise uniquement la primitive de compte et les contrats nécessaires à la future admission de `ProgramInstruction` :
|
||
|
||
```text
|
||
ProgramAccountMeta présent
|
||
fields privés
|
||
constructeurs readonly / writable
|
||
accessors pubkey / is_signer / is_writable
|
||
Pubkey Core réutilisé
|
||
MAX_PROGRAM_INSTRUCTION_ACCOUNTS 255
|
||
ERROR_CODE_PROGRAM_INSTRUCTION_LIMIT_EXCEEDED interface.program_instruction_limit_exceeded
|
||
ProgramInstruction absent par contrat
|
||
MAX_PROGRAM_INSTRUCTION_DATA_LEN absent jusqu'à pre.004
|
||
serde / borsh / bincode / wincode absents
|
||
ksp-logging-lib / constants.rs / TRACING_TARGET absents
|
||
```
|
||
|
||
La constante `255` ferme le contrat public de borne accounts mais son enforcement `255/256` appartient au constructeur de `ProgramInstruction` de `pre.004`; `ProgramAccountMeta` représente un seul compte et n'invente donc pas une collection artificielle uniquement pour tester cette limite.
|
||
|
||
Une seule catégorie d'erreur Interface est introduite. `invalid_program_instruction` reste absent : aucun invariant de forme distinct des limites n'est encore matérialisé et le créer par symétrie serait prématuré. Les futures erreurs de borne doivent utiliser `ksp_core_lib::Error/Result` et ne projeter que des longueurs/plafonds sûrs.
|
||
|
||
La preuve opérateur fournie pour `pre.003` confirme fmt, audits, `cargo check`, Clippy, tests ciblés Interface et graphes Cargo. `cargo test --workspace` n'apparaît pas dans cette preuve ; il doit donc être rejoué au gate de `pre.004` avant de déclarer la continuité workspace complète.
|
||
|
||
## 18. État préparé `pre.004`
|
||
|
||
`pre.004` matérialise le second et dernier type du premier lot wire générique retenu :
|
||
|
||
```text
|
||
ProgramInstruction présent
|
||
fields privés
|
||
program_id Pubkey Core
|
||
accounts Vec<ProgramAccountMeta> consommé
|
||
data Vec<u8> opaque consommé
|
||
MAX_PROGRAM_INSTRUCTION_ACCOUNTS 255
|
||
MAX_PROGRAM_INSTRUCTION_DATA_LEN 10_240
|
||
try_new bornes accounts puis data
|
||
accounts 255 / 256 accepté / refusé
|
||
data 10_240 / 10_241 accepté / refusé
|
||
accounts/data vides acceptés
|
||
ordre/doublons préservés
|
||
Program Pubkey non registry accepté
|
||
Debug program_id/account_count/data_len uniquement
|
||
serde / borsh / bincode / wincode absents
|
||
solana-instruction absent
|
||
ksp-logging-lib / constants.rs / TRACING_TARGET absents
|
||
```
|
||
|
||
`ProgramInstruction::try_new` consomme les deux `Vec` fournis et compare leurs longueurs en `usize` avant stockage dans l'objet. La foundation n'ajoute aucun clone, cast étroit ou allocation de conversion. Une allocation éventuellement déjà réalisée par l'appelant pour construire le `Vec` reste naturellement hors du contrôle de l'API.
|
||
|
||
Les deux limites utilisent le code commun `interface.program_instruction_limit_exceeded`. Le contexte d'erreur est volontairement réduit à `field`, `actual_len` et `maximum_len`; aucune donnée du payload ni aucun account arbitraire n'est recopié dans le diagnostic.
|
||
|
||
Le `Debug` manuel n'imprime ni la collection accounts ni les octets `data`. Il expose uniquement l'identité publique du programme et les deux longueurs structurelles utiles au diagnostic.
|
||
|
||
Le gate opérateur `pre.004` confirme désormais fmt, audits Rust/Markdown, `cargo check --workspace`, Clippy, tests ciblés Interface, `cargo test --workspace` et les deux graphes Cargo. Le passage à `pre.005` se concentre donc exclusivement sur les canaris adversariaux/consumer externe/API/dependency hardening, sans ajouter un second domaine wire.
|
||
|
||
## 19. État préparé `pre.005`
|
||
|
||
`pre.005` n'ajoute aucun code de production et ferme uniquement les preuves de consommation, complétude et résistance adversariale autour de la surface déjà matérialisée :
|
||
|
||
```text
|
||
production src modifié non
|
||
nouveau domaine wire non
|
||
external consumer integration crate présent
|
||
release completeness inventory présent
|
||
façade crate-root exacte 6 exports contrôlés
|
||
modules de production 4 fichiers exacts
|
||
Vec accounts/data transfert sans réallocation interne testé
|
||
payload hostile dans erreur absent attendu
|
||
account material hostile dans erreur absent attendu
|
||
narrowing casts absents par source canary
|
||
codec encode/decode générique absent par source canary
|
||
manifest dependency ksp-core-lib uniquement
|
||
source dependency firewall renforcé sur tous les modules production
|
||
```
|
||
|
||
Le canari `tests/external_consumer.rs` est volontairement un test d'intégration Rust séparé : Cargo le compile comme un crate consommateur externe de la bibliothèque. Il n'utilise que la façade `ksp_interface_lib::*` accessible depuis le crate-root et n'exige donc ni fixture workspace artificielle ni invocation Cargo imbriquée.
|
||
|
||
`tests/release_completeness.rs` verrouille l'inventaire exact de la foundation `0.2.13` :
|
||
|
||
```text
|
||
ERROR_CODE_PROGRAM_INSTRUCTION_LIMIT_EXCEEDED
|
||
MAX_PROGRAM_INSTRUCTION_ACCOUNTS
|
||
ProgramAccountMeta
|
||
MAX_PROGRAM_INSTRUCTION_DATA_LEN
|
||
ProgramInstruction
|
||
Pubkey
|
||
```
|
||
|
||
Il verrouille également l'absence de `pub mod` et l'inventaire exact des quatre fichiers Rust de production. Ajouter une seconde famille wire dans `0.2.13` ferait ainsi échouer explicitement le canari de complétude au lieu d'élargir silencieusement la release.
|
||
|
||
Le hardening unitaire vérifie enfin que les allocations des `Vec` admis sont transférées telles quelles dans `ProgramInstruction` et que les erreurs de dépassement ne recopient ni marqueur hostile de payload ni représentation arbitraire d'account meta. Ces tests renforcent le contrat de construction sans changer l'API publique.
|
||
|
||
Après validation opérateur de `pre.005`, `pre.006` doit rester un gate technique pur sans nouveau développement fonctionnel.
|
||
|
||
## 20. Correctif préparé `pre.005-fix.001`
|
||
|
||
Le gate opérateur `pre.005` confirme les preuves suivantes :
|
||
|
||
```text
|
||
fmt / audits Rust / Markdown PASS
|
||
cargo check --workspace PASS
|
||
cargo clippy --workspace --all-targets PASS
|
||
cargo test -p ksp-interface-lib PASS
|
||
external consumer PASS
|
||
release completeness PASS
|
||
hardening adversarial PASS
|
||
cargo test --workspace FAIL cross-crate canary Logging
|
||
cargo tree Interface Core-only confirmé
|
||
```
|
||
|
||
L'échec workspace ne révèle aucun bypass runtime d'Interface. Le scanner `ksp-logging-lib/tests/ownership.rs` recherche littéralement le chemin source `tracing::` dans tous les fichiers Rust des crates KSP, tests compris. Le firewall `ksp-interface-lib/tests/dependency_boundary.rs` contenait cette chaîne comme **valeur de test interdite**, ce qui déclenchait le scanner Logging sur le canari lui-même.
|
||
|
||
Le fix conserve exactement la même interdiction mais construit le token de recherche sans faire apparaître le chemin littéral dans le source du test :
|
||
|
||
```rust
|
||
concat!("tracing", "::")
|
||
```
|
||
|
||
Le test Interface continue donc de refuser un chemin direct vers Tracing dans les sources de production, tandis que le scanner Logging ne confond plus la donnée du canari avec un usage runtime réel.
|
||
|
||
Aucun fichier `src/` de production, aucune dépendance, aucune API publique, aucune borne et aucune décision de logging ne sont modifiés. La version technique devient `0.2.13-pre.5.fix.1` parce que le fix touche un test Rust.
|
||
|
||
Le gate opérateur du fix est désormais intégralement vert : fmt, audits Rust/Markdown, `cargo check --workspace`, Clippy, tests Interface, canari Logging ciblé, `cargo test --workspace` et graphes Cargo sont tous validés/inspectés. Le faux positif est donc fermé sans élargissement du scope.
|
||
|
||
## 21. Gate technique final validé `pre.006`
|
||
|
||
`pre.006` n'a ajouté aucun code, aucun test et aucune dépendance. Le gate opérateur du **28 août 2026** ferme la lane technique avec les preuves suivantes :
|
||
|
||
```text
|
||
cargo fmt --all PASS
|
||
audits Rust / export completeness / workspace PASS
|
||
audit Markdown PASS — 162 tables / 119 fichiers
|
||
cargo check --workspace PASS
|
||
cargo clippy --workspace --all-targets PASS
|
||
cargo test -p ksp-interface-lib PASS
|
||
cargo test -p ksp-logging-lib --test ownership PASS
|
||
cargo test --workspace PASS
|
||
cargo tree -p ksp-interface-lib --edges normal Core-only confirmé
|
||
cargo tree --duplicates inspecté
|
||
```
|
||
|
||
La surface technique finale avant documentation reste donc :
|
||
|
||
```text
|
||
workspace.package.version 0.2.13-pre.6
|
||
production Interface inchangée
|
||
tests Interface inchangés
|
||
surface crate-root 6 exports exacts
|
||
modules production 4 fichiers exacts
|
||
dépendance normale Interface ksp-core-lib uniquement
|
||
codec / serde / solana-instruction absents
|
||
ksp-logging-lib / tracing runtime Interface absents
|
||
network/live smoke N/A pour foundation wire pure
|
||
```
|
||
|
||
Le gate `pre.006` autorise la réconciliation documentaire finale sans réouverture technique.
|
||
|
||
## 22. Réconciliation documentaire finale `pre.007`
|
||
|
||
`pre.007` ne modifie aucun fichier Rust, test, manifest de crate, dépendance ou comportement. La version workspace avance mécaniquement à `0.2.13-pre.7` conformément au workflow de prerelease non-fix.
|
||
|
||
Les références durables sont réconciliées autour du contrat réellement livré :
|
||
|
||
```text
|
||
crates/ksp-interface-lib/README.md
|
||
crates/ksp-interface-lib/USAGE.md
|
||
docs/000-README.md
|
||
docs/plans/000-README.md
|
||
docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md
|
||
docs/plans/020-V0_2_13_INTERFACE_PLAN.md
|
||
docs/validation/000-README.md
|
||
docs/validation/016-V0_2_13_INTERFACE.md
|
||
```
|
||
|
||
Le README Interface fixe l'ownership, la surface crate-root exacte, les deux bornes d'admission, le modèle d'erreur sûr, le Debug borné, le graphe `Interface -> Core`, l'absence de codecs/logging/runtime et les frontières avec Program API/Transport/Store. `USAGE.md` documente les constructeurs `readonly`/`writable`, `ProgramInstruction::try_new`, les accessors, les bornes et l'observation des erreurs sans dépendre des modules privés.
|
||
|
||
La séquence fonctionnelle précise désormais le contenu réellement livré par `0.2.13` et maintient les reports : Program API en `0.2.14`, wires génériques acquisition/CORE en `0.3.2+`. Les index plan/validation passent du statut actif au statut candidat réconcilié sans annoncer prématurément la release stable.
|
||
|
||
La tranche ne touche explicitement pas :
|
||
|
||
```text
|
||
CHANGELOG.md
|
||
ROADMAP.md
|
||
prompts/019-V0_2_14_START_PROMPT.md
|
||
architecture
|
||
code/tests/manifests de crate
|
||
```
|
||
|
||
Ces surfaces appartiennent à `pre.008` pour la préparation minimale de publication, sauf découverte d'un défaut réel imposant une nouvelle tranche corrective.
|