v0.4.8-pre.007

This commit is contained in:
2026-08-06 00:52:08 +02:00
parent 80c439c988
commit 44088c71c9
122 changed files with 8903 additions and 3914 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: docs/audits/V0_4_8_PRE_002_METADATA_CONTRACT_AUDIT.md -->
<!-- version: 1 -->
<!-- version: 2 -->
# Audit contractuel `0.4.8-pre.002` — Solana Program Metadata et Token-2022
@@ -48,11 +48,11 @@ La structure, le Program ID, la version déclarée, les PDA, les comptes et les
### 4.1 PDA
| PDA | Seeds |
|---|---|
| canonical | `[program, seed]` |
| non-canonical | `[program, authority, seed]` |
| metadata | helper conditionnel sélectionnant lune des deux dérivations selon la présence dune autorité tierce |
| PDA | Seeds |
|---------------|------------------------------------------------------------------------------------------------------|
| canonical | `[program, seed]` |
| non-canonical | `[program, authority, seed]` |
| metadata | helper conditionnel sélectionnant lune des deux dérivations selon la présence dune autorité tierce |
`seed` est une chaîne UTF-8 de taille fixe 16 octets dans lIDL. Le code doit distinguer longueur en octets et nombre de caractères Unicode.
@@ -76,27 +76,27 @@ Ces valeurs décrivent uniquement les données on-chain. `Url` ne déclenche auc
### 4.4 Instructions
| Discriminant | Instruction | Comptes | Arguments |
|---:|---|---|---|
| `0` | `write` | `buffer` (writable)<br>`authority` (signer)<br>`sourceBuffer` (optional) | `offset: u32`<br>`data: Option<bytes>` |
| `1` | `initialize` | `metadata` (writable)<br>`authority` (signer)<br>`program`<br>`programData` (optional)<br>`system` (optional) | `seed: Seed`<br>`encoding: Encoding`<br>`compression: Compression`<br>`format: Format`<br>`dataSource: DataSource`<br>`data: Option<bytes>` |
| `2` | `setAuthority` | `account` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional) | `newAuthority: Option<pubkey>` |
| `3` | `setData` | `metadata` (writable)<br>`authority` (signer)<br>`buffer` (writable, optional)<br>`program` (optional)<br>`programData` (optional) | `encoding: Encoding`<br>`compression: Compression`<br>`format: Format`<br>`dataSource: DataSource`<br>`data: Option<bytes>` |
| `4` | `setImmutable` | `metadata` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional) | — |
| `5` | `trim` | `account` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional)<br>`destination` (writable)<br>`rent` | — |
| `6` | `close` | `account` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional)<br>`destination` (writable) | — |
| `7` | `allocate` | `buffer` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional)<br>`system` (optional) | `seed: Option<Seed>` |
| `8` | `extend` | `account` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional) | `length: u16` |
| Discriminant | Instruction | Comptes | Arguments |
|-------------:|----------------|----------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------|
| `0` | `write` | `buffer` (writable)<br>`authority` (signer)<br>`sourceBuffer` (optional) | `offset: u32`<br>`data: Option<bytes>` |
| `1` | `initialize` | `metadata` (writable)<br>`authority` (signer)<br>`program`<br>`programData` (optional)<br>`system` (optional) | `seed: Seed`<br>`encoding: Encoding`<br>`compression: Compression`<br>`format: Format`<br>`dataSource: DataSource`<br>`data: Option<bytes>` |
| `2` | `setAuthority` | `account` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional) | `newAuthority: Option<pubkey>` |
| `3` | `setData` | `metadata` (writable)<br>`authority` (signer)<br>`buffer` (writable, optional)<br>`program` (optional)<br>`programData` (optional) | `encoding: Encoding`<br>`compression: Compression`<br>`format: Format`<br>`dataSource: DataSource`<br>`data: Option<bytes>` |
| `4` | `setImmutable` | `metadata` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional) | — |
| `5` | `trim` | `account` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional)<br>`destination` (writable)<br>`rent` | — |
| `6` | `close` | `account` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional)<br>`destination` (writable) | — |
| `7` | `allocate` | `buffer` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional)<br>`system` (optional) | `seed: Option<Seed>` |
| `8` | `extend` | `account` (writable)<br>`authority` (signer)<br>`program` (optional)<br>`programData` (optional) | `length: u16` |
### 4.5 Erreurs officielles
| Code | Erreur |
|---:|---|
| 0 | `NotExecutableAccount` |
| 1 | `InvalidProgramState` |
| 2 | `InvalidProgramDataAccount` |
| 3 | `ImmutableMetadataAccount` |
| 4 | `InvalidDataLength` |
| Code | Erreur |
|-----:|-----------------------------|
| 0 | `NotExecutableAccount` |
| 1 | `InvalidProgramState` |
| 2 | `InvalidProgramDataAccount` |
| 3 | `ImmutableMetadataAccount` |
| 4 | `InvalidDataLength` |
## 5. Décisions de modèles et de validation `ProgM6…`
@@ -113,13 +113,13 @@ Ces valeurs décrivent uniquement les données on-chain. `Url` ne déclenche auc
## 6. Matrice de couverture Token-2022 réelle
| Capacité | Décodage wire | Intent public | Builder | Exécution | Lecture stateful | Matérialisation | Scénario dédié | Desktop | Devnet confirmé |
|---|---|---|---|---|---|---|---|---|---|
| `Initialize` | oui | oui | oui | oui, via builder générique | état extension lisible | extension observée | non dédié | non dédié | non établi |
| `UpdateField` | oui | oui | oui | oui, via builder générique | état extension lisible | extension observée | non dédié | non dédié | non établi |
| `RemoveKey` | oui | oui | oui | oui, via builder générique | état extension lisible | extension observée | non dédié | non dédié | non établi |
| `UpdateAuthority` | oui | non | non | non | état extension lisible | extension observée | non | non | non |
| `Emit` | oui | non | non | non | résultat de retour non orchestré | non dédiée | non | non | non |
| Capacité | Décodage wire | Intent public | Builder | Exécution | Lecture stateful | Matérialisation | Scénario dédié | Desktop | Devnet confirmé |
|-------------------|---------------|---------------|---------|----------------------------|----------------------------------|--------------------|----------------|-----------|-----------------|
| `Initialize` | oui | oui | oui | oui, via builder générique | état extension lisible | extension observée | non dédié | non dédié | non établi |
| `UpdateField` | oui | oui | oui | oui, via builder générique | état extension lisible | extension observée | non dédié | non dédié | non établi |
| `RemoveKey` | oui | oui | oui | oui, via builder générique | état extension lisible | extension observée | non dédié | non dédié | non établi |
| `UpdateAuthority` | oui | non | non | non | état extension lisible | extension observée | non | non | non |
| `Emit` | oui | non | non | non | résultat de retour non orchestré | non dédiée | non | non | non |
Constats complémentaires :

View File

@@ -0,0 +1,189 @@
<!-- file: docs/audits/V0_4_8_PRE_007_MATERIALIZER_CONVENTION_AUDIT.md -->
<!-- version: 3 -->
# Audit des conventions et de la structure des matérialisateurs — `0.4.8-pre.007-fix-004`
## 1. Objet
Cet audit couvre lintégralité de `kb-lib/src/materializer` après lactivation du matérialisateur Solana Program Metadata et lextraction des projections Metaplex Token Metadata et Token-2022.
Les contrôles portent sur :
- les identités runtime et les `processorName` persistés ;
- les tracing targets ;
- la structure des façades et sous-modules ;
- lemplacement, le nommage et la réexportation des constantes ;
- les contrats communs `MtMaterializer` et `MtApiEventMaterializer` ;
- la neutralité effective des matérialisateurs encore réservés ;
- la provenance et les versions de projection des sorties actives.
## 2. Convention retenue
Chaque composant possède une paire didentités issue de son `constants.rs` :
```text
runtime component : kb-lib.materializer.<domain>[.<subsystem>]
processorName : materializer.<domain>[.<subsystem>]
```
Le `processorName` est exactement lidentité runtime privée du préfixe `kb-lib.`. Le tracing target dun composant actif est identique à son identité runtime.
Exemples :
```text
kb-lib.materializer.compliance.audit
materializer.compliance.audit
kb-lib.materializer.transaction.annotations
materializer.transaction.annotations
kb-lib.materializer.metadata.solana_program_metadata
materializer.metadata.solana_program_metadata
```
Les identités runtime servent au code et au routage des logs. Les `processorName` servent aux sorties persistées, au replay et à la provenance. Ils ne doivent pas être interchangeables.
## 3. Inventaire audité
| Composant | Type principal ou API | Statut | Identité runtime | `processorName` |
|-------------------------|---------------------------------------|------------|--------------------------------------------------------|-------------------------------------------------|
| Administration | `MtAdminMaterializer` | actif | `kb-lib.materializer.admin` | `materializer.admin` |
| Bridge | `MtBridgeMaterializer` | réservé | `kb-lib.materializer.bridge` | `materializer.bridge` |
| Compliance audit | `MtComplianceAuditMaterializer` | actif | `kb-lib.materializer.compliance.audit` | `materializer.compliance.audit` |
| Fees | `MtFeesMaterializer` | actif | `kb-lib.materializer.fees` | `materializer.fees` |
| Governance | `MtGovernanceMaterializer` | réservé | `kb-lib.materializer.governance` | `materializer.governance` |
| Lending | `MtLendingMaterializer` | réservé | `kb-lib.materializer.lending` | `materializer.lending` |
| Lifecycle | `MtLifecycleMaterializer` | actif | `kb-lib.materializer.lifecycle` | `materializer.lifecycle` |
| Liquidity | `MtLiquidityMaterializer` | réservé | `kb-lib.materializer.liquidity` | `materializer.liquidity` |
| Metaplex Token Metadata | APIs de snapshots | state-only | `kb-lib.materializer.metadata.metaplex_token_metadata` | `materializer.metadata.metaplex_token_metadata` |
| Solana Program Metadata | `MtSolanaProgramMetadataMaterializer` | actif | `kb-lib.materializer.metadata.solana_program_metadata` | `materializer.metadata.solana_program_metadata` |
| Token-2022 metadata | API de snapshots | state-only | `kb-lib.materializer.metadata.token_2022` | `materializer.metadata.token_2022` |
| NFT | `MtNftMaterializer` | réservé | `kb-lib.materializer.nft` | `materializer.nft` |
| Oracle | `MtOracleMaterializer` | réservé | `kb-lib.materializer.oracle` | `materializer.oracle` |
| Orderbook | `MtOrderbookMaterializer` | réservé | `kb-lib.materializer.orderbook` | `materializer.orderbook` |
| Perpetuals | `MtPerpetualsMaterializer` | réservé | `kb-lib.materializer.perpetuals` | `materializer.perpetuals` |
| Pool state | `MtPoolStateMaterializer` | réservé | `kb-lib.materializer.pool.state` | `materializer.pool.state` |
| Rewards | `MtRewardsMaterializer` | réservé | `kb-lib.materializer.rewards` | `materializer.rewards` |
| Risk | `MtRiskMaterializer` | actif | `kb-lib.materializer.risk` | `materializer.risk` |
| Routing | `MtRoutingMaterializer` | réservé | `kb-lib.materializer.routing` | `materializer.routing` |
| Staking | `MtStakingMaterializer` | actif | `kb-lib.materializer.staking` | `materializer.staking` |
| Token accounts | `MtTokenAccountsMaterializer` | actif | `kb-lib.materializer.token.accounts` | `materializer.token.accounts` |
| Token metadata risk | `MtTokenMetadataRiskMaterializer` | réservé | `kb-lib.materializer.token.metadata_risk` | `materializer.token.metadata_risk` |
| Trades | `MtTradesMaterializer` | réservé | `kb-lib.materializer.trades` | `materializer.trades` |
| Transaction annotations | `MtTransactionAnnotationMaterializer` | actif | `kb-lib.materializer.transaction.annotations` | `materializer.transaction.annotations` |
| Vault | `MtVaultMaterializer` | réservé | `kb-lib.materializer.vault` | `materializer.vault` |
Bilan : **25 composants nommés**, dont **9 matérialisateurs actifs**, **14 coquilles réservées** et **2 composants state-only**.
`MtMetadataMaterializer` reste un wrapper public de compatibilité vers `MtSolanaProgramMetadataMaterializer`. Il ne possède pas une identité distincte et ne crée pas un second propriétaire de projection.
## 4. Structure normalisée
Un matérialisateur simple suit désormais la structure :
```text
<component>.rs
<component>/constants.rs
<component>/materializer.rs
```
La façade `<component>.rs` ne contient que les déclarations de sous-modules et leurs réexports. Les composants complexes peuvent ajouter des fichiers spécialisés, par exemple `state.rs` ou `account.rs`, sans placer dimplémentation dans la façade.
Les domaines imbriqués suivent la même règle :
```text
compliance/audit.rs
compliance/audit/constants.rs
compliance/audit/materializer.rs
transaction/annotations.rs
transaction/annotations/constants.rs
transaction/annotations/materializer.rs
```
Les anciens noms génériques `core.rs` ont été remplacés par `materializer.rs`. Les tables de surfaces, familles acceptées, identités, versions de projection et tracing targets résident dans les `constants.rs`, sont réexportées jusquà `kb-lib/src/lib.rs` et sont consommées via `crate::`.
## 5. Coquilles réservées
Une coquille réservée doit :
- conserver son type public `Mt*Materializer` ;
- implémenter les deux traits communs ;
- exposer une constante `MT_*_ACCEPTED_FAMILIES` vide ;
- retourner `false` depuis lancien `accepts_event` ;
- retourner une liste vide depuis lancien `materialize_event` ;
- retourner `Ignored` depuis le contrat contextuel ;
- ne produire aucun événement, aucune sortie et aucune provenance fictive.
Le comportement antérieur qui pouvait retourner un événement legacy malgré une frontière inactive a été supprimé.
## 6. Provenance et versionnement
Les sorties actives utilisent uniquement leur constante `MT_*_PROCESSOR_NAME`. Aucun `processorName` littéral ne reste dans les implémentations.
Les changements de provenance Metaplex et Token-2022 livrés dans `fix-002` restent associés à `projectionVersion = 2`. Solana Program Metadata conserve `projectionVersion = 1`, car sa projection est introduite dans `0.4.8`.
Lajout dune provenance explicite aux sorties qui ne possédaient encore quune version numérique modifie leur contrat persisté. Les matérialisateurs `admin`, `compliance.audit`, `fees`, `lifecycle` et `staking` passent donc de `projectionVersion = 1` à `projectionVersion = 2`. Les matérialisateurs `risk`, `token.accounts` et `transaction.annotations` conservaient déjà une provenance spécialisée et gardent leurs versions existantes.
Les `output_key` et les familles métier existantes ne sont pas renommées par cet audit.
## 7. Configuration de logging
Les routes de `config/example.config.json` sont alignées sur les tracing targets spécialisés :
```text
kb-lib.materializer.compliance.audit
kb-lib.materializer.transaction.annotations
kb-lib.materializer.token.accounts
```
Les noms de sinks et leurs chemins sont harmonisés avec les mêmes sous-domaines.
## 8. Garde-fous ajoutés
Laudit mécanique du workspace vérifie désormais :
- la paire obligatoire `MT_*_COMPONENT_NAME` / `MT_*_PROCESSOR_NAME` ;
- la relation exacte obtenue par suppression du préfixe `kb-lib.` ;
- labsence de constantes hors `constants.rs` ;
- la présence dun `constants.rs` à côté de chaque implémentation ;
- labsence didentités littérales dans les implémentations ;
- la présence conjointe de `projectionVersion` et `processorName` dans chaque payload versionné ;
- lutilisation obligatoire des constantes `MT_*_PROJECTION_VERSION` et `MT_*_PROCESSOR_NAME` dans ces payloads ;
- la pureté des façades ;
- le résultat vide des deux contrats dune coquille réservée.
Les tests Rust conservent en plus linventaire typé des matérialisateurs et contrôlent la convention de nommage.
## 9. Fichiers obsolètes à supprimer
Les 22 chemins retirés sont fournis dans `delete-files.txt` à la racine du delta. Leur suppression est obligatoire avant la validation, car une extraction ZIP ne peut pas retirer les anciens fichiers.
## 10. Conclusion
Les matérialisateurs utilisent désormais une convention unique pour les identités runtime, les processeurs persistés, les tracing targets, les constantes, les façades et les coquilles réservées. Les différences restantes sont fonctionnelles et explicites : un composant peut être actif, réservé ou state-only, mais il ne change pas de convention structurelle ou de provenance selon son statut.
## 11. Correction des identités opérationnelles et du tracing
La compilation du workspace corrigé a révélé trois tracing targets déclarés mais sans événement réel :
- `kb-lib.materializer.fees` ;
- `kb-lib.materializer.metadata.metaplex_token_metadata` ;
- `kb-lib.materializer.metadata.token_2022`.
Le composant state-only Token-2022 réexportait également `MT_METADATA_TOKEN_2022_COMPONENT_NAME` sans le consommer dans son implémentation. Cette situation ne signifiait pas que les snapshots Token-2022 nétaient pas matérialisés : la fonction `materializer_metadata_materialize_token_2022_snapshot` produisait déjà les projections `TokenMetadata`, `TokenGroup` et `TokenGroupMember`. Elle révélait en revanche que lidentité runtime du composant nétait pas attachée à une opération observable.
Le correctif ajoute des événements structurés réels pour les chemins suivants :
- observation et snapshots de frais Token-2022 ;
- snapshots de comptes Metaplex et `MetadataV1` ;
- snapshots metadata, group et group-member Token-2022.
Les événements portent le tracing target du composant, son `component_name`, son `processor_name`, sa version, le statut et les identités disponibles. Aucun faux `let _target` nest utilisé et aucun champ persistant nest ajouté uniquement pour supprimer un warning.
Laudit mécanique refuse désormais :
- un `TRACING_TARGET_*` de `kb-lib` déclaré sans macro `tracing` réelle ;
- un `MT_*_COMPONENT_NAME` qui nest consommé par aucun fichier dimplémentation du composant.
Les composants state-only restent distincts des matérialiseurs instructionnels : ils nimplémentent pas artificiellement `MtApiEventMaterializer`, mais leur identité runtime est désormais effectivement utilisée par leurs opérations de snapshot.

View File

@@ -0,0 +1,109 @@
<!-- file: docs/audits/V0_4_8_PRE_007_METAPLEX_MATERIALIZER_STRUCTURE_AUDIT.md -->
<!-- version: 4 -->
# Audit `0.4.8-pre.007` — structure et identités des matérialiseurs metadata
## 1. Questions vérifiées
Deux ambiguïtés structurelles ont été vérifiées :
- labsence initiale dun sous-module dédié à Metaplex Token Metadata ;
- lemplacement et la couverture de la matérialisation Token-2022 Token Metadata.
Laudit a également séparé lidentité runtime dun composant de son `processorName` persisté.
## 2. Metaplex Token Metadata
Il nexistait pas doubli fonctionnel en `0.4.7`. Les APIs publiques suivantes étaient déjà implémentées :
- `materializer_metadata_materialize_metaplex_metadata_snapshot` pour létat autoritatif `MetadataV1` ;
- `materializer_metadata_materialize_metaplex_account_snapshot` pour les autres comptes Metaplex canoniques matérialisables.
Le défaut était structurel : ces fonctions partageaient auparavant `metadata/core.rs` avec dautres domaines. Elles sont désormais isolées dans :
```text
kb-lib/src/materializer/metadata/metaplex_token_metadata.rs
kb-lib/src/materializer/metadata/metaplex_token_metadata/constants.rs
kb-lib/src/materializer/metadata/metaplex_token_metadata/state.rs
kb-lib/src/materializer/metadata/metaplex_token_metadata/account.rs
```
Les clés de sortie et la sémantique métier restent inchangées. La provenance utilise désormais le `processorName` dédié :
```text
materializer.metadata.metaplex_token_metadata
```
Comme cette valeur persistée change par rapport au contrat antérieur, `projectionVersion` passe de `1` à `2`.
## 3. Token-2022 Token Metadata
Les états Token-2022 étaient déjà matérialisés par :
```text
materializer_metadata_materialize_token_2022_snapshot
```
Cette fonction projette les extensions de mint suivantes :
- `TokenMetadata` ;
- `TokenGroup` ;
- `TokenGroupMember`.
Elle était cependant placée dans `metadata/core.rs`. Le correctif lextrait vers :
```text
kb-lib/src/materializer/metadata/token_2022.rs
kb-lib/src/materializer/metadata/token_2022/constants.rs
kb-lib/src/materializer/metadata/token_2022/state.rs
```
La fonction publique et les `output_key` restent inchangées. Sa provenance utilise :
```text
materializer.metadata.token_2022
```
Le schéma de projection passe à `2` pour refléter cette correction didentité.
## 4. Écart fonctionnel Token-2022 restant
La matérialisation détat ne couvre pas à elle seule toutes les observations décodées.
Les faits `InitializeMetadataPointer` et `UpdateMetadataPointer` sont déjà possédés par le matérialiseur dadministration. En revanche, les cinq observations de `spl-token-metadata-interface` ne disposent pas encore dune matérialisation dinstruction dédiée :
- `Initialize` ;
- `UpdateField` ;
- `RemoveKey` ;
- `UpdateAuthority` ;
- `Emit`.
Cet écart doit être fermé dans `0.4.8-pre.010`, en même temps que la complétude des intents, builders, lectures avant/après et postconditions Token-2022.
## 5. Solana Program Metadata
Lidentité runtime du composant reste :
```text
kb-lib.materializer.metadata.solana_program_metadata
```
Le `processorName` persistant du composant Solana Program Metadata est corrigé en :
```text
materializer.metadata.solana_program_metadata
```
Le tracing target reste distinct et conserve son préfixe runtime :
```text
kb-lib.materializer.metadata.solana_program_metadata
```
## 6. Conséquence de migration
Les projections dérivées Metaplex et Token-2022 produites avec les anciennes provenances doivent être reconstruites depuis les raws ou migrées si elles sont conservées. Les clés de sortie ne changent pas.
## 7. Conclusion
Metaplex et les états metadata Token-2022 étaient déjà matérialisés. `pre.007-fix-002` corrige leurs identités et leur organisation modulaire. `pre.007-fix-003` étend ensuite la même convention à lintégralité des matérialisateurs ; voir `V0_4_8_PRE_007_MATERIALIZER_CONVENTION_AUDIT.md`. La seule lacune fonctionnelle confirmée concerne les cinq faits dinstructions `spl-token-metadata-interface`, explicitement reportés à `pre.010`.