277 lines
7.4 KiB
Markdown
277 lines
7.4 KiB
Markdown
<!-- file: docs/OPERATION_NAMING_CONVENTION.md -->
|
||
<!-- version: 5 -->
|
||
|
||
# Convention canonique des identités runtime et des codes d’opération
|
||
|
||
## 1. Objet
|
||
|
||
Ce document définit les chaînes stables utilisées par `khadhroony-bot3` dans le code, les plans d’exécution, les événements décodés, les sorties matérialisées, les journaux et PostgreSQL.
|
||
|
||
Ces chaînes sont des contrats de données. Elles ne doivent pas être renommées localement, improvisées dans un test ou dérivées du nom d’une ancienne crate. Toute nouvelle surface doit être ajoutée à la matrice `test-fixtures/contract-matrices/OPERATION_NAMING_MATRIX.json` avant son premier remplissage persistant.
|
||
|
||
## 2. Principe général
|
||
|
||
Les valeurs persistées utilisent une hiérarchie en segments séparés par un point :
|
||
|
||
```text
|
||
<domain>.<family>[.<generation-or-subsystem>][.<operation>]
|
||
```
|
||
|
||
Chaque segment utilise `snake_case`. Un underscore reste autorisé à l’intérieur d’un concept indivisible, par exemple `token_2022`, `compute_budget` ou `associated_token_account`. Il ne doit pas remplacer un séparateur hiérarchique.
|
||
|
||
Correct :
|
||
|
||
```text
|
||
solana.core.system.transfer
|
||
spl.memo.v4.add_memo
|
||
spl.token_2022.transfer_checked
|
||
spl.associated_token_account.create_idempotent
|
||
metadata.metaplex_token_metadata.create_metadata_account_v3
|
||
```
|
||
|
||
Interdit :
|
||
|
||
```text
|
||
solana_core.system.transfer
|
||
spl_memo_v4.add_memo
|
||
spl_token_2022.transfer_checked
|
||
spl_associated_token_account.create_idempotent
|
||
metadata_metaplex_token_metadata.create_metadata_account_v3
|
||
```
|
||
|
||
## 2.1 Frontière avec les codes de registre
|
||
|
||
La notation par points s’applique aux identités runtime, processeurs, surfaces, opérations et événements persistés. Elle ne s’applique pas aux codes techniques du registre `ks-program-ids`, qui restent des identifiants Rust/registre en `lower_snake_case` afin de préserver leur ordre lexical, leur compatibilité et leur rôle de clé interne.
|
||
|
||
Exemples de codes de registre :
|
||
|
||
```text
|
||
metadata_metaplex_token_metadata
|
||
spl_memo_v4
|
||
spl_token
|
||
spl_token_2022
|
||
```
|
||
|
||
Le même programme peut donc avoir :
|
||
|
||
```text
|
||
registry code : spl_token_2022
|
||
processor_name : spl.token_2022
|
||
surface_code : spl.token_2022
|
||
```
|
||
|
||
## 3. Catégories de noms
|
||
|
||
### 3.1 Identité runtime d’un composant
|
||
|
||
Format :
|
||
|
||
```text
|
||
ks-lib-<role>.<domain>.<family>[.<subsystem>]
|
||
```
|
||
|
||
Exemples :
|
||
|
||
```text
|
||
ks-lib-decoder.solana.core
|
||
ks-lib-executor.solana.core
|
||
ks-lib-decoder.spl.memo
|
||
ks-lib-executor.spl.token_2022
|
||
ks-lib-materializer.transaction.annotations
|
||
```
|
||
|
||
Cette identité désigne le composant logiciel, pas une opération on-chain.
|
||
|
||
Pour un matérialisateur, le tracing target reprend exactement cette identité runtime. La paire avec le `processor_name` est déterministe :
|
||
|
||
```text
|
||
component_name = ks-lib-materializer.<suffixe>
|
||
processor_name = materializer.<suffixe>
|
||
```
|
||
|
||
Les domaines spécialisés ne doivent pas être raccourcis : utiliser `compliance.audit`, `transaction.annotations` et `token.accounts`, et non les parents génériques `compliance`, `transaction` ou `token`.
|
||
|
||
### 3.2 `processor_name`
|
||
|
||
Format :
|
||
|
||
```text
|
||
<domain>.<family>[.<subsystem>]
|
||
```
|
||
|
||
Exemples :
|
||
|
||
```text
|
||
solana.core
|
||
spl.memo
|
||
spl.token
|
||
spl.token_2022
|
||
spl.associated_token_account
|
||
spl.elgamal_registry
|
||
metadata.metaplex_token_metadata
|
||
materializer.transaction.annotations
|
||
materializer.token.accounts
|
||
materializer.risk
|
||
```
|
||
|
||
`processor_name` doit rester stable entre les campagnes et ne doit pas inclure une version. La version est stockée séparément dans `processor_version`.
|
||
|
||
### 3.3 `surface_code`
|
||
|
||
Format :
|
||
|
||
```text
|
||
<domain>.<family>[.<generation-or-subsystem>]
|
||
```
|
||
|
||
La surface représente la frontière on-chain effectivement observée.
|
||
|
||
Exemples :
|
||
|
||
```text
|
||
solana.core.system
|
||
solana.core.compute_budget
|
||
solana.core.loader_v4
|
||
spl.memo.v1
|
||
spl.memo.v3
|
||
spl.memo.v4
|
||
spl.token
|
||
spl.token_2022
|
||
spl.token_2022.confidential_transfer
|
||
spl.associated_token_account
|
||
metadata.metaplex_token_metadata
|
||
```
|
||
|
||
Une génération est ajoutée seulement lorsqu’elle change l’identité du programme ou le contrat observé.
|
||
|
||
### 3.4 `operation_code`
|
||
|
||
Format :
|
||
|
||
```text
|
||
<generic-executable-surface>.<operation>
|
||
```
|
||
|
||
`operation_code` décrit une intention constructible par un exécuteur. Il peut être plus générique que l’événement observé lorsque l’exécuteur cible une seule génération actuelle.
|
||
|
||
Exemples :
|
||
|
||
```text
|
||
solana.core.system.transfer
|
||
spl.memo.add_memo
|
||
spl.token.transfer_checked
|
||
spl.token_2022.close_account
|
||
spl.associated_token_account.create
|
||
```
|
||
|
||
Pour Memo, l’exécuteur ne construit que Memo v4, mais l’intention reste `spl.memo.add_memo`. Le Program ID du plan fixe la génération réellement construite.
|
||
|
||
### 3.5 `event_code`
|
||
|
||
Format :
|
||
|
||
```text
|
||
<observed-surface>.<event>
|
||
```
|
||
|
||
`event_code` décrit ce qui a été observé et conserve la génération lorsque celle-ci est significative.
|
||
|
||
Exemples :
|
||
|
||
```text
|
||
spl.memo.v1.add_memo
|
||
spl.memo.v3.add_memo
|
||
spl.memo.v4.add_memo
|
||
spl.token.transfer_checked
|
||
spl.token_2022.close_account
|
||
solana.core.system.transfer
|
||
```
|
||
|
||
### 3.6 `protocol_code`
|
||
|
||
`protocol_code` identifie le protocole fonctionnel sans opération :
|
||
|
||
```text
|
||
solana.core
|
||
spl.memo
|
||
spl.token
|
||
spl.token_2022
|
||
spl.associated_token_account
|
||
spl.elgamal_registry
|
||
metadata.metaplex_token_metadata
|
||
```
|
||
|
||
Il ne doit pas réintroduire les anciennes formes `solana_native`, `spl_token` ou `spl_memo`.
|
||
|
||
## 4. Correspondance entre Rust et les valeurs persistées
|
||
|
||
Les symboles Rust suivent les règles Rust habituelles, tandis que leurs valeurs suivent cette convention :
|
||
|
||
```rust
|
||
pub const EX_SPL_TOKEN_2022_TRANSFER_CHECKED_OPERATION: &str =
|
||
"spl.token_2022.transfer_checked";
|
||
```
|
||
|
||
- symbole Rust : `SCREAMING_SNAKE_CASE` ;
|
||
- module Rust : `snake_case` ;
|
||
- valeur persistée : segments hiérarchiques séparés par `.` ;
|
||
- type Rust : `PascalCase`, par exemple `Token2022`.
|
||
|
||
## 5. Stabilité et migrations
|
||
|
||
Ces valeurs peuvent participer à :
|
||
|
||
- des clés de ledger ;
|
||
- des contraintes d’unicité ;
|
||
- des clés d’idempotence ;
|
||
- des événements Decode ;
|
||
- des observations de couverture ;
|
||
- des sorties matérialisées ;
|
||
- des filtres SQL et frontend ;
|
||
- des preuves de scénarios Devnet.
|
||
|
||
Un renommage après remplissage d’une base est donc une migration de données. Avant production, toute modification exige :
|
||
|
||
1. une mise à jour coordonnée du code, des matrices et des règles ;
|
||
2. une décision explicite entre migration SQL et reconstruction des tables dérivées ;
|
||
3. une validation de l’idempotence ;
|
||
4. une vérification des filtres et APIs ;
|
||
5. une nouvelle preuve runtime.
|
||
|
||
Pendant la phase actuelle de développement, les bases Devnet et recherche peuvent être recréées depuis les raws.
|
||
|
||
## 6. Matrice normative
|
||
|
||
La source machine-readable est :
|
||
|
||
```text
|
||
test-fixtures/contract-matrices/OPERATION_NAMING_MATRIX.json
|
||
```
|
||
|
||
Chaque entrée documente au minimum :
|
||
|
||
- `programId` ;
|
||
- `processorName` ;
|
||
- `surfaceCode` ;
|
||
- `operationCode` ;
|
||
- `eventCode` ;
|
||
- `decoderName` ;
|
||
- `executorName` ;
|
||
- `status` ;
|
||
- `source`.
|
||
|
||
Une surface `decode_only` peut avoir `operationCode` et `executorName` à `null`.
|
||
|
||
## 7. Règles d’ajout d’une nouvelle opération
|
||
|
||
Avant de fusionner une nouvelle opération :
|
||
|
||
1. choisir son domaine et sa famille ;
|
||
2. identifier le Program ID canonique dans `ks-program-ids` ;
|
||
3. définir `processor_name` et `surface_code` ;
|
||
4. définir séparément `operation_code` et `event_code` ;
|
||
5. ajouter les constantes Rust ;
|
||
6. ajouter ou mettre à jour la matrice normative ;
|
||
7. ajouter les tests de cohérence entre constantes et matrice ;
|
||
8. vérifier l’impact PostgreSQL avant tout backfill ou replay durable.
|