Files
khadhroony-solana-project/docs/rules/RULES_KSP.md
2026-08-14 13:05:50 +02:00

200 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- file: docs/rules/RULES_KSP.md -->
<!-- version: 14 -->
# 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é.
- **KSP-NAME-010** — Un pipeline spécialisé réutilisable se nomme `ksp-pipeline-<role>-lib`; aucun `ksp-pipeline-lib` générique n'est créé.
## 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 réellement deprecated mais toujours identifiable et techniquement préparabile peut rester supportée par son `ProgramExecutionPreparer`, avec statut/warning machine-readable et décision finale laissée à la policy supérieure.
- **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`.
## Backlog, claims et reprise
- **KSP-PROC-001** — Le backlog est défini relativement à l'identité/version/capability du processor et non par simple absence d'une row de sortie.
- **KSP-PROC-002** — Une nouvelle version de processor peut rendre de nouveau candidat un input déjà terminal pour une version précédente.
- **KSP-PROC-003** — Un input peut avoir plusieurs outcomes indépendants lorsqu'il est candidat pour plusieurs materializers/projectors.
- **KSP-PROC-004** — Les claims sont temporaires ; une lease expirée après crash rend le candidat de nouveau traitable.
- **KSP-PROC-005** — Les erreurs transitoires utilisent retry/backoff borné ; les failures déterministes doivent pouvoir devenir un état durable afin d'éviter une boucle infinie.
- **KSP-PROC-006** — Unsupported/NotApplicable ne sont pas nécessairement des erreurs et constituent des outcomes terminaux pour la version/capability concernée.
- **KSP-PROC-007** — Les consumers combinent wake-up par notification et polling périodique du backlog.
- **KSP-PROC-008** — Un backlog downstream croissant n'entraîne pas automatiquement le ralentissement du raw retriever ; une éventuelle backpressure globale appartient à une policy/configuration/orchestration supérieure.
## 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 d'abord par les apps manager spécialisées, puis éventuellement par un futur orchestrateur/application globale ; 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.
- **KSP-WORKER-009** — Les workers de processing utilisent notification comme wake-up mais reconstruisent leur backlog depuis le Store.
- **KSP-WORKER-010** — `ksp-worker-raw-retriever` distingue une configuration desired et une configuration effective lors des reconfigurations à chaud.
- **KSP-WORKER-011** — Un cursor de scan est une optimisation ; les processing outcomes durables constituent la preuve qu'un input a été traité pour un processor/version/capability.
- **KSP-WORKER-012** — La concurrence de processing utilise une sémantique de claim/lease récupérable après expiration/crash.
- **KSP-WORKER-013** — Chaque worker doit pouvoir fonctionner comme service/processus indépendant afin d'être arrêté/redémarré/mis à jour sans imposer l'arrêt volontaire des autres workers.
- **KSP-WORKER-014** — La direction de packaging préférée est un package worker avec cible bibliothèque réutilisable et binaire autonome mince.
- **KSP-WORKER-015** — Les workers ne dépendent pas directement les uns des autres ; D1D4 constituent leur data plane partagé.
- **KSP-WORKER-016** — Aucun ordre global strict de démarrage des workers n'est figé actuellement.
## 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.
- **KSP-JOB-009** — Les jobs de replay retenus sont `ksp-job-replay-core`, `ksp-job-replay-generic-materialization` et `ksp-job-replay-domain-projection`.
- **KSP-JOB-010** — Les jobs de replay réutilisent exactement le pipeline spécialisé de la frontière correspondante.
- **KSP-JOB-011** — Le backfill conserve un checkpoint de progression dans la source historique en plus des outcomes de persistence D1.
- **KSP-JOB-012** — Replay normal/reprise et force replay sont deux intentions distinctes ; un force replay conserve provenance/historique et ne supprime pas silencieusement le résultat courant.
## Persistence
- **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.
- **KSP-PIPE-002** — Les quatre pipelines spécialisés retenus pour les frontières durables sont raw ingestion, Core processing, generic materialization et domain projection.
- **KSP-PIPE-003** — Un pipeline spécialisé contient la logique réutilisable d'une frontière mais aucun lifecycle worker/job.
- **KSP-PIPE-004** — Les pipelines utilisent les APIs Program/Materializer/Store lorsque ces frontières doivent être injectables ; les implémentations officielles sont composées par workers/jobs.
- **KSP-PIPE-005** — Le traitement est at-least-once avec persistence idempotente et outcomes durables, plutôt qu'une promesse exactly-once distribuée.
- **KSP-PIPE-006** — Un traitement valide produisant zéro output possède malgré tout un outcome terminal explicite tel que NoOutput/NotApplicable/Unsupported selon la sémantique finale.
- **KSP-PIPE-007** — Outputs obligatoires et processing outcome d'une unité logique sont atomiques du point de vue durable.
- **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.
- **KSP-SCENARIO-007** — La logique fonctionnelle d'un scenario s'exécute dans `ksp-scenario-<domain>-lib` et reste appelable hors desktop.
- **KSP-SCENARIO-008** — Les scenarios suivent `docs/rules/SCENARIO_CONVENTION.md` tant qu'aucun contrat Rust commun suffisamment utile ne justifie `ksp-scenario-api`.
## 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é.
- **KSP-APP-005** — Les applications spécialisées précèdent toute future application globale ; aucune app globale n'est un livrable actuel.
- **KSP-APP-006** — Une app manager worker utilise le control plane et ne modifie pas directement l'état interne de processing du worker en base.
- **KSP-APP-007** — Une future application globale est conservée comme idée produit et sera cadrée seulement après validation suffisante des apps spécialisées/demos.
## Data plane / control plane
- **KSP-CONTROL-001** — Le data plane des workers passe par transport + D1/D2/D3/D4 et notifications de données persistées.
- **KSP-CONTROL-002** — Le control plane porte lifecycle, status, health et reconfiguration ; il ne transporte pas les payloads de processing entre workers.
- **KSP-CONTROL-003** — La sémantique de `ksp-worker-api` doit rester utilisable avec un handle local ou un futur proxy IPC.
- **KSP-CONTROL-004** — Aucun `ksp-ipc-api` générique n'est prévu actuellement ; le premier manager/service concret doit d'abord démontrer le transport nécessaire.
- **KSP-CONTROL-005** — `ksp-orchestrator-lib` est seulement un concept futur et n'est pas une crate retenue dans le plan actuel.
## Releases fonctionnelles
- **KSP-REL-001** — Une série `X.Y.x` est une famille fonctionnelle ; chaque release concrète `X.Y.Z` est dimensionnée séparément.
- **KSP-REL-002** — À partir de `0.1.x`, chaque delta/prerelease/fix est commité afin de préserver l'historique réel du développement.
- **KSP-REL-003** — Une erreur intermédiaire est corrigée par un delta/commit suivant ; l'historique n'est pas réécrit pour supprimer artificiellement l'étape erronée.
- **KSP-REL-004** — Seul le commit d'une release stable reçoit le tag `vX.Y.Z`.
- **KSP-REL-005** — Le premier `pre.001` d'une release fonctionnelle commence par brainstorming, audit, vérification des dépendances actuelles lorsque concernées, plan détaillé et dimensionnement.
- **KSP-REL-006** — Une release ou prerelease trop grosse est scindée plutôt que compressée pour respecter un numéro prévu.
- **KSP-REL-007** — La dernière prerelease d'une release fonctionnelle réalise par défaut validations finales, documentation, nettoyage/archivage, changelog et prompt de la release suivante.
- **KSP-REL-008** — La première release fonctionnelle sélectionnée est `0.1.1`, dédiée à la stabilisation de `ksp-core-lib`.