Files
khadhroony-solana-project/docs/rules/RULES_KSP.md
2026-08-14 12:07:18 +02:00

147 lines
16 KiB
Markdown

<!-- file: docs/rules/RULES_KSP.md -->
<!-- version: 10 -->
# Règles spécifiques à KSP
## Nomenclature
- **KSP-NAME-001** — Une bibliothèque Rust d'implémentation réutilisable se nomme `ksp-<role>-lib`, sauf famille explicitement définie par une règle plus spécifique.
- **KSP-NAME-002** — Une crate publique de contrats extensibles se nomme `ksp-<domain>-api`. Elle est techniquement une bibliothèque Rust mais ne porte volontairement pas le suffixe `-lib`.
- **KSP-NAME-003** — Une crate `ksp-<domain>-api` expose principalement les types/traits/contrats nécessaires aux implémentations ; elle n'est pas une implémentation fonctionnelle directement destinée aux exécutables.
- **KSP-NAME-004** — Une application se nomme `ksp-app-<role>-<interface>` lorsque l'interface doit être indiquée.
- **KSP-NAME-005** — Un worker continu se nomme `ksp-worker-<role>`.
- **KSP-NAME-006** — Un job ponctuel/historique/terminable se nomme `ksp-job-<role>`.
- **KSP-NAME-007** — Une démonstration se termine par `-demo`.
- **KSP-NAME-008** — Les crates Rust sont placées directement sous `crates/`.
- **KSP-NAME-009** — Une application desktop de scénario spécialisée suit la forme `ksp-app-scenario-<domain>-<environment>-desk-demo` lorsque l'environnement est imposé.
## Architecture et APIs
- **KSP-API-001** — Un domaine extensible peut séparer `ksp-<domain>-api` et `ksp-<domain>-lib`.
- **KSP-API-002** — Les premiers couples retenus sont `ksp-program-api` / `ksp-program-lib`, `ksp-materializer-api` / `ksp-materializer-lib` et `ksp-store-api` / `ksp-store-lib`.
- **KSP-API-003** — KSP ne crée pas de `ksp-api-lib` monolithique regroupant les contrats de domaines indépendants.
- **KSP-API-004** — Un contrat public extensible doit pouvoir être implémenté depuis une crate séparée du workspace principal lorsque cela est techniquement pertinent.
- **KSP-API-005** — Les signatures des contrats publics utilisent en priorité des types publics KSP et les primitives externes explicitement admises ; elles ne doivent pas imposer des détails internes instables.
- **KSP-API-006** — `ksp-store-lib` contient PostgreSQL comme implémentation officielle de référence derrière `ksp-store-api`.
- **KSP-API-007** — Une crate `*-api` n'est créée que lorsqu'un vrai besoin d'extension, backend ou lifecycle le justifie ; la symétrie de nommage n'est jamais une justification suffisante.
## Programmes et exécution
- **KSP-PROGRAM-001** — Les contrats de décodage et de préparation d'exécution appartiennent à `ksp-program-api`; les implémentations officielles intégrées appartiennent à `ksp-program-lib`.
- **KSP-PROGRAM-002** — Le decoder vise toute surface techniquement décodable dont la définition est connue, y compris les formats anciens, obsolètes ou expérimentaux encore distinguables.
- **KSP-PROGRAM-003** — Le statut `deprecated` concerne la capacité d'exécution, pas la capacité de décodage.
- **KSP-PROGRAM-004** — Lorsqu'une définition wire a été réellement écrasée/remplacée sous la même identité et que l'ancienne définition n'est plus distinguable de manière fiable, le decoder utilise la définition la plus récente applicable.
- **KSP-PROGRAM-005** — Une opération devenue obsolète mais toujours identifiable/exécutable peut rester implémentée dans l'executor et être marquée `deprecated`.
- **KSP-PROGRAM-006** — `ksp-program-lib` ne contient pas la politique de sécurité de production.
- **KSP-EXEC-001** — `ksp-execution-policy-api` est l'API publique de décision/safety d'exécution ; chaque contexte fournit sa propre implémentation.
- **KSP-EXEC-002** — Toute exécution réelle via `ksp-execution-lib` reçoit explicitement une policy ; aucun fallback implicite permissif n'est prévu.
- **KSP-EXEC-003** — Une policy peut être évaluée à plusieurs checkpoints et peut autoriser, refuser ou imposer des requirements ; elle ne signe pas, n'appelle pas le réseau et n'interagit pas directement avec l'UI.
- **KSP-EXEC-004** — `ksp-execution-lib` consomme fondamentalement `PreparedProgramExecution`, dépend de `ksp-program-api` et non de `ksp-program-lib`.
- **KSP-EXEC-005** — `ksp-execution-lib` orchestre simulation, signature, submission, confirmation et retry de lifecycle à partir de primitives possédées par transport/wallet.
- **KSP-EXEC-006** — Wallet/signers et transport/provider sont sélectionnés/fournis par la composition supérieure ; l'execution lib ne choisit pas arbitrairement ces ressources.
- **KSP-EXEC-007** — Une approbation externe peut produire un état suspendu/reprenable sans dépendance de la policy/execution vers Tauri ou une UI.
- **KSP-EXEC-008** — `ksp-execution-lib` ne persiste pas automatiquement son résultat et ne dépend pas du store.
## Transports
- **KSP-TRANSPORT-001** — KSP ne crée pas de `ksp-onchain-transport-api` séparée dans l'architecture actuelle.
- **KSP-TRANSPORT-002** — `ksp-onchain-transport-lib` ne dépend pas de `ksp-store-api`.
- **KSP-TRANSPORT-003** — Les providers on-chain normalisent leurs sorties dans des modèles de transport homogènes par catégorie de données avant exposition aux consommateurs.
- **KSP-TRANSPORT-004** — Les modèles de transport restent sans décodage métier/protocolaire et doivent être explicitement/facilement convertibles vers les modèles raw persistants de `ksp-store-api` par la couche d'acquisition.
- **KSP-TRANSPORT-005** — KSP ne crée pas de `ksp-offchain-transport-api` globale ni de trait universel artificiel pour des domaines off-chain hétérogènes.
## Wallet
- **KSP-WALLET-001** — KSP ne crée pas de `ksp-wallet-api` dans l'architecture actuelle ; `ksp-wallet-lib` possède le format wallet KSP et ses capacités de lecture/protection/import/export/pubkey/secret/signature.
- **KSP-PROGRAM-007** — Le contrat de préparation d'exécution est nommé conceptuellement `ProgramExecutionPreparer`; il ne signe, ne simule, n'envoie et ne confirme pas une transaction.
- **KSP-PROGRAM-008** — `ksp-program-api` reste ouvert : aucun enum central fermé ne doit imposer une modification de l'API pour ajouter un Program ID externe.
- **KSP-PROGRAM-009** — Le résultat décodé doit pouvoir être auto-identifié et devenir persistable ; `Any` ne constitue pas à lui seul un contrat de résultat acceptable.
- **KSP-PROGRAM-010** — Une extension de programme est une implémentation `ksp-program-<name>-lib`, pas une nouvelle crate `*-api`.
- **KSP-PROGRAM-011** — `ksp-program-lib` est organisé selon `domain -> program/protocol -> capability`; les dossiers globaux regroupant tous les decoders de tous les protocoles sont évités.
- **KSP-PROGRAM-012** — Le statut legacy/deprecated d'une opération est machine-readable et indépendant du décodage historique.
- **KSP-PROGRAM-013** — `#[deprecated]` n'est pas imposé pour les opérations historiques ; un warning runtime et la policy supérieure peuvent porter la décision d'usage.
- **KSP-WIRE-001** — `ksp-interface-lib` est le propriétaire normal des codecs wire pour les interfaces officielles KSP.
- **KSP-WIRE-002** — Les interfaces externes sont sélectionnées aussi selon la modernité/cohérence de leur graphe de dépendances, pas uniquement selon la commodité de leur API.
- **KSP-WIRE-003** — Les contrats wire d'une crate protocolaire rejetée sont réimplémentés de manière bornée dans `ksp-interface-lib` lorsque KSP en a besoin.
## Niveaux durables et Store
- **KSP-DURABLE-001** — Les niveaux persistants utilisent la nomenclature D1 à D4, distincte des couches architecturales N1 à N4.
- **KSP-DURABLE-002** — D1 est Raw, D2 Core canonique, D3 le journal générique de matérialisation et D4 les projections spécialisées/queryables.
- **KSP-DURABLE-003** — D1/D2/D3 sont destinés à devenir fortement stables après stabilisation de la première série Store ; D4 reste plus évolutif.
- **KSP-DURABLE-004** — Le journal D3 est durable et obligatoire ; il ne peut pas être supprimé au profit de projections D4 directes.
- **KSP-DURABLE-005** — Les replays D1 -> D2, D2 -> D3 et D3 -> D4 sont indépendants.
- **KSP-DURABLE-006** — Les instructions top-level et CPI restent des faits Core distincts lorsque leurs invariants/requêtes diffèrent.
- **KSP-DURABLE-007** — D4 modélise des faits canoniques plutôt que des familles de tables par protocole lorsque les invariants sont normalisables.
- **KSP-DURABLE-008** — Les temporalités blockchain et locales restent distinctes ; un `block_time` absent n'est jamais remplacé par une date locale inventée.
## Materialization
- **KSP-MAT-001** — `ksp-materializer-api` est l'unique API publique de matérialisation actuellement prévue et peut exposer des capacités distinctes D2 -> D3 et D3 -> D4.
- **KSP-MAT-002** — `ksp-materializer-lib` transforme mais ne persiste pas directement et ne dépend pas du Store.
- **KSP-MAT-003** — Une extension externe de materializer doit pouvoir produire du D3 générique sans migration PostgreSQL spécialisée.
- **KSP-MAT-004** — Une nouvelle projection relationnelle D4 exige explicitement un contrat Store/migration/backend correspondant ; cette responsabilité n'est pas cachée dans `ksp-materializer-api`.
## Notifications de données persistées
- **KSP-NOTIFY-001** — `ksp-store-api` possède le format canonique d'une notification signalant qu'une donnée persistée est disponible.
- **KSP-NOTIFY-002** — Le format est indépendant de l'origine de la donnée : worker live, backfill, import, replay ou autre source.
- **KSP-NOTIFY-003** — Une notification est un signal de réveil et n'est jamais la source de vérité du backlog.
- **KSP-NOTIFY-004** — La persistence et le commit réussissent avant publication d'une notification.
- **KSP-NOTIFY-005** — Le payload de notification privilégie une référence durable compacte plutôt que la duplication du payload persistant.
- **KSP-NOTIFY-006** — Le contrat de notification reste indépendant du mécanisme de diffusion concret.
## Workers
- **KSP-WORKER-001** — Un worker représente un service continu/live ; il est distinct d'un job.
- **KSP-WORKER-002** — Les contrats communs des workers appartiennent à `ksp-worker-api` et ne contiennent aucun contrat propre aux jobs.
- **KSP-WORKER-003** — `ksp-worker-api` est principalement une lifecycle API de services continus : identité, état, health, démarrage/arrêt et événements communs ; les capacités optionnelles ne deviennent universelles que si plusieurs workers les partagent réellement.
- **KSP-WORKER-004** — `ksp-worker-control-lib` est une implémentation commune de gouvernance/contrôle réutilisable par managers desktop, future application globale et orchestrateur ; les apps ne réimplémentent pas cette gouvernance.
- **KSP-WORKER-005** — `ksp-worker-raw-retriever` est le worker d'acquisition raw live/quasi-live. Il ne décode pas, ne matérialise pas et ne réalise pas de replay/backfill historique.
- **KSP-WORKER-006** — `ksp-worker-raw-retriever` persiste les données raw puis notifie leur disponibilité selon les contrats de données normalisés.
- **KSP-WORKER-007** — `ksp-worker-raw-retriever` doit pouvoir faire évoluer à chaud les listeners et la sélection des données qu'il rapatrie/stocke.
- **KSP-WORKER-008** — Les workers de processing actuellement retenus sont `ksp-worker-core-processor`, `ksp-worker-generic-materializer` et `ksp-worker-domain-projector`; le dernier nom reste provisoire.
## Jobs
- **KSP-JOB-001** — Un job représente un travail déclenché à la demande, suivable et terminable ; il est distinct d'un worker continu.
- **KSP-JOB-002** — Les contrats communs des jobs appartiennent à `ksp-job-api` et ne contiennent aucun contrat propre aux workers.
- **KSP-JOB-003** — `ksp-job-api` est principalement une lifecycle API de travaux terminables : identité, état, progression, annulation, résultat et capacités de reprise lorsqu'elles sont pertinentes.
- **KSP-JOB-004** — Les implémentations concrètes utilisent le préfixe `ksp-job-`.
- **KSP-JOB-005** — `ksp-job-backfill` est retenu pour le backfill historique ; il ne doit pas être implémenté comme un mode du worker raw.
- **KSP-JOB-006** — D'autres jobs peuvent être introduits pour metadata, quotes ou autres travaux ponctuels lorsqu'un besoin réel le justifie.
- **KSP-JOB-007** — Aucune `ksp-job-control-lib` commune n'est prévue actuellement ; elle ne sera créée que si une duplication concrète entre plusieurs jobs le justifie.
- **KSP-JOB-008** — Le contrôle/gouvernance des jobs reste séparé du contrôle des workers.
## Matérialisation et persistence
- **KSP-MAT-001** — `ksp-materializer-api` peut dépendre de `ksp-program-api` ; `ksp-materializer-lib` dépend de son API mais ne dépend pas du store.
- **KSP-MAT-002** — `ksp-materializer-api` / `ksp-materializer-lib` ne réalisent pas eux-mêmes la persistance ; les workers/jobs/pipelines spécialisés composent matérialisation et store.
- **KSP-STORE-001** — `ksp-store-api` reste indépendant des APIs Program/Materializer/Transport et possède les contrats persistants.
- **KSP-STORE-002** — Les conversions entre modèles runtime et DTO persistants sont explicites aux frontières de composition ; aucun `ksp-data-api` global n'est introduit actuellement.
## Notifications de données
- **KSP-DATA-001** — Une notification de donnée décrit la donnée disponible et non le worker/job qui l'a produite.
- **KSP-DATA-002** — Le même type de donnée utilise le même contrat de notification quelle que soit son origine : worker, job, import ou autre source.
- **KSP-DATA-003** — `ksp-store-api` est le propriétaire retenu des références/notifications canoniques lorsqu'elles signifient qu'une donnée persistée est disponible.
- **KSP-DATA-004** — Le contrat de notification est séparé de son mécanisme de transport concret.
## Pipelines et scénarios
- **KSP-PIPE-001** — KSP ne crée pas de `ksp-pipeline-lib` monolithique. Les pipelines sont introduits séparément à la demande selon leur responsabilité réelle.
- **KSP-SCENARIO-001** — Il n'existe pas de crate monolithique `ksp-scenarios-lib`.
- **KSP-SCENARIO-002** — Les scénarios sont séparés en crates `ksp-scenario-<domain>-lib` par responsabilité fonctionnelle cohérente.
- **KSP-SCENARIO-003** — `ksp-scenario-api` n'est pas retenu actuellement ; KSP privilégie d'abord une norme documentaire/structurelle commune qui ne limite pas les contrats spécifiques des scénarios.
- **KSP-SCENARIO-004** — Memo, SPL Token classique, ATA et Token-2022 restent dans des crates/scénarios séparés.
- **KSP-SCENARIO-005** — Une famille metadata d'assets/tokens peut regrouper Metaplex Token Metadata et Token-2022 Metadata ; Solana Program Metadata reste séparé.
- **KSP-SCENARIO-006** — Lorsqu'un scénario réutilisable existe dans KSP, l'application demo le consomme et ne réimplémente pas le workflow.
## Applications
- **KSP-APP-001** — Une application KSP est une interface et une couche de composition. Elle ne réimplémente pas une opération appartenant conceptuellement à un composant KSP réutilisable inférieur.
- **KSP-APP-002** — Les applications/demos ne dépendent pas directement de crates Solana/protocoles externes.
- **KSP-APP-003** — Les applications/demos peuvent réaliser les opérations strictement liées à l'interface, mais pas la logique métier/protocolaire réutilisable.
- **KSP-APP-004** — Une demo scenario desktop consomme la crate `ksp-scenario-<domain>-lib` correspondante ; elle suit la convention `ksp-app-scenario-<domain>-<environment>-desk-demo` lorsque l'environnement est imposé.