v0.4.8-pre.008

This commit is contained in:
2026-08-06 06:12:54 +02:00
parent 44088c71c9
commit f576fbade2
52 changed files with 3592 additions and 420 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: docs/audits/V0_4_8_PRE_007_MATERIALIZER_CONVENTION_AUDIT.md -->
<!-- version: 3 -->
<!-- version: 4 -->
# Audit des conventions et de la structure des matérialisateurs — `0.4.8-pre.007-fix-004`
@@ -45,37 +45,35 @@ Les identités runtime servent au code et au routage des logs. Les `processorNam
## 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` |
| 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 | `MtMetadataMetaplexTokenMetadataMaterializer` | actif | `kb-lib.materializer.metadata.metaplex_token_metadata` | `materializer.metadata.metaplex_token_metadata` |
| Solana Program Metadata | `MtMetadataSolanaProgramMaterializer` | actif | `kb-lib.materializer.metadata.solana_program_metadata` | `materializer.metadata.solana_program_metadata` |
| Token-2022 metadata | `MtMetadataToken2022Materializer` | actif | `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.
Bilan après correction `pre.008` : **25 composants nommés**, dont **11 matérialisateurs actifs** et **14 coquilles réservées**. Les trois domaines metadata exposent des types spécialisés ; aucun wrapper metadata générique ne masque leur ownership.
## 4. Structure normalisée
@@ -161,7 +159,7 @@ Les 22 chemins retirés sont fournis dans `delete-files.txt` à la racine du del
## 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.
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. Un composant peut être actif ou réservé ; les APIs stateful restent des capacités de son matérialiseur spécialisé et ne constituent pas un type générique parallèle.
## 11. Correction des identités opérationnelles et du tracing
@@ -171,7 +169,7 @@ La compilation du workspace corrigé a révélé trois tracing targets déclaré
- `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 composant de snapshots 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 :
@@ -186,4 +184,4 @@ 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.
La correction `pre.008` ajoute les matérialiseurs instructionnels spécialisés Metaplex et Token-2022 parce que leurs instructions sont effectivement décodées. Leurs APIs de snapshots restent distinctes et autoritatives, tandis que les sorties dinstructions restent des faits committés non autoritatifs.

View File

@@ -0,0 +1,52 @@
<!-- file: docs/audits/V0_4_8_PRE_008_METADATA_AND_PIPELINE_NOMENCLATURE_AUDIT.md -->
<!-- version: 1 -->
# Audit de nomenclature metadata et pipeline
## 1. Objet
Cet audit corrige deux dérives révélées après lintégration pipeline de `0.4.8-pre.008` : un matérialiseur Solana Program Metadata nommé hors de la hiérarchie `MtMetadata*`, et des modules `kb-pipeline` préfixés uniformément par `solana_` malgré des domaines Metaplex ou SPL distincts.
## 2. Matérialiseurs metadata
La surface publique canonique comprend désormais exactement trois types spécialisés :
| Domaine | Type | Processor |
|---------------------------|-----------------------------------------------|-------------------------------------------------|
| Metaplex Token Metadata | `MtMetadataMetaplexTokenMetadataMaterializer` | `materializer.metadata.metaplex_token_metadata` |
| Solana Program Metadata | `MtMetadataSolanaProgramMaterializer` | `materializer.metadata.solana_program_metadata` |
| Token-2022 metadata/group | `MtMetadataToken2022Materializer` | `materializer.metadata.token_2022` |
Le type `MtSolanaProgramMetadataMaterializer` et le wrapper `MtMetadataMaterializer` sont supprimés. Chaque type implémente les contrats legacy et contextuel, possède ses constantes, son tracing target et son ownership instructionnel. Les helpers `state.rs` et `account.rs` restent séparés : ils produisent les snapshots autoritatifs, alors que les matérialiseurs dinstructions produisent des faits committés non autoritatifs.
Les neuf instructions incorporées Token Metadata et Token Group sont classées sous `MdEventFamily::Metadata`. Cette classification évite de confier les changements dautorité propres aux interfaces metadata au matérialiseur dadministration générique.
## 3. Registre desktop
`demo_decode_replay` enregistre les trois types spécialisés. Un test construit une observation représentative de chaque domaine et vérifie quelle possède exactement un propriétaire dans le registre runtime.
## 4. Nomenclature `kb-pipeline`
Les modules privés suivent la hiérarchie suivante :
- `metadata_metaplex_token_metadata_*` ;
- `metadata_solana_program_*` ;
- `spl_ata_stateful` ;
- `spl_elgamal_registry_stateful` ;
- `spl_token_stateful` ;
- `spl_token_2022_*` ;
- `solana_stateful` uniquement pour les contrats Solana Core transversaux.
Les fonctions et structures publiques restent inchangées. Le renommage est donc structurel et documentaire, sans rupture volontaire de lAPI consommée par le desktop ou les futurs scénarios Devnet.
## 5. Fichiers remplacés
Les anciens fichiers `solana_*` de `kb-pipeline`, lancien test externe et lancienne matrice sont listés dans `delete-files.txt`. Leur suppression est obligatoire après extraction du delta.
## 6. Garde-fous
- les exports racine couvrent les trois matérialiseurs spécialisés ;
- le test externe nutilise que la façade `kb_lib::*` ;
- les familles Token-2022 metadata/group sont testées exhaustivement ;
- le test externe pipeline utilise des assertions de compilation `const` ;
- laudit des règles vérifie les façades, les exports, les constantes et la nomenclature des composants.

View File

@@ -0,0 +1,113 @@
<!-- file: docs/audits/V0_4_8_PRE_008_METADATA_SOLANA_PROGRAM_PIPELINE_AUDIT.md -->
<!-- version: 2 -->
# Audit du pipeline Solana Program Metadata — `0.4.8-pre.008`
## 1. Objet
Cet audit ferme la frontière réutilisable de Solana Program Metadata dans `kb-pipeline` sans introduire de fixture, de wallet de démonstration ni de dépendance envers `kb-pipeline-demo-scenarios`.
La surface couverte est le programme :
```text
ProgM6JCCvbYkfKqJYHePx4xxSUSqJp7rh8Lyv7nk7S
```
## 2. Séparation des responsabilités
| Crate ou composant | Responsabilité en `pre.008` |
|-----------------------------------------------|----------------------------------------------------------------------------------------|
| `kb-lib` | modèles, décodage, matérialisation, intents, builders, exécuteur et safety commun |
| `kb-pipeline` | lectures stateful, préflight, readiness simulation-first et postconditions |
| `kb-pipeline-demo-scenarios` | aucune modification ; fixture et parcours Devnet réservés à `pre.009` |
| `kb-app-demo-desktop/demo_decode_replay` | enregistrement générique du décodeur et du matérialiseur pour la validation historique |
| `kb-app-demo-desktop/demo_execution_metadata` | aucune modification ; intégration `ProgM6…` réservée à `pre.009` |
## 3. Lectures stateful
Le pipeline distingue explicitement :
- compte absent ;
- compte présent mais vide ou intégralement nul ;
- compte `Buffer` initialisé ;
- compte `Metadata` initialisé.
Les réponses RPC doivent être confirmées, non exécutables, complètes et sous la borne maximale. Un état initialisé doit être détenu par `ProgM6…`. Le décodage et la projection autoritative sont délégués aux APIs publiques de `kb-lib`.
## 4. Préflight
Le préflight lie lintent typé au plan préparé et contrôle :
- le Program ID et le code dopération exacts ;
- lunique instruction du plan ;
- lapprobation explicite des mutations sensibles ;
- la décision de `ExSafetyChecker` ;
- les snapshots confirmés et non dupliqués ;
- létat du compte cible ;
- les sources `Buffer` ;
- lautorité explicite ou le contexte canonical ;
- le préfinancement rent des opérations dallocation ou dagrandissement.
Une décision `Deny` bloque le traitement. Une décision `RequireConfirmation` reste exécutable mais doit être satisfaite dans lenveloppe de readiness.
## 5. Readiness et postconditions
La readiness refuse :
- un plan non lié au préflight ;
- un message non simulé ou simulé sous un autre hash ;
- une simulation en échec ;
- un signer requis non résolu ;
- une soumission sans confirmation opérateur ;
- une soumission depuis un plan `dry_run`.
Les neuf opérations possèdent une postcondition stateful :
| Opération | Postcondition principale |
|----------------|-----------------------------------------------------------------|
| `Write` | octets attendus au bon offset du `Buffer` |
| `Initialize` | état `Metadata`, PDA, seed, descripteurs et contenu compatibles |
| `SetAuthority` | autorité finale exacte ou supprimée |
| `SetData` | descripteurs et contenu final compatibles |
| `SetImmutable` | `mutable = false` |
| `Trim` | même type détat et taille non croissante |
| `Close` | compte absent |
| `Allocate` | état `Buffer`, autorité, seed et canonicité compatibles |
| `Extend` | même type détat et taille augmentée exactement |
Une lecture finale absente du rapport produit `NotApplicable`, jamais `Confirmed`.
## 6. Validation historique prévue
La validation historique opérateur suit :
1. `demo_backfill` sur un échantillon borné de signatures ;
2. extraction Core ;
3. decode replay ciblé sur `ProgM6…` et `metadata.solana_program_metadata` ;
4. matérialisation via `materializer.metadata.solana_program_metadata` ;
5. lecture bornée des événements matérialisés.
Cette validation précède les scénarios Devnet de `pre.009` et ne dépend pas de leur fixture.
## 7. Matrice
La matrice machine-readable est :
```text
test-fixtures/contract-matrices/METADATA_SOLANA_PROGRAM_PIPELINE_MATRIX.json
```
Elle distingue explicitement la crate généraliste du package de scénarios et ferme linventaire des neuf opérations.
## 8. Correction de nomenclature `pre.008`
Les modules privés de `kb-pipeline` sont renommés selon leur domaine :
- `metadata_metaplex_token_metadata_*` pour Metaplex Token Metadata ;
- `metadata_solana_program_*` pour Solana Program Metadata ;
- `spl_ata_stateful` et `spl_elgamal_registry_stateful` pour les programmes SPL correspondants ;
- `spl_token_stateful` et `spl_token_2022_*` pour SPL Token et Token-2022 ;
- `solana_stateful` reste réservé aux primitives Solana Core transversales.
Les fonctions et structures publiques restent stables. La matrice et le test externe suivent la même nomenclature de fichier.
Le registre de replay desktop utilise désormais trois matérialiseurs metadata spécialisés : `MtMetadataMetaplexTokenMetadataMaterializer`, `MtMetadataSolanaProgramMaterializer` et `MtMetadataToken2022Materializer`. Aucun wrapper générique `MtMetadataMaterializer` nest conservé.

View File

@@ -0,0 +1,54 @@
<!-- file: docs/audits/V0_4_8_PRE_008_SOLANA_PROGRAM_METADATA_HISTORICAL_REPLAY_FIX.md -->
<!-- version: 1 -->
# Correctif du replay historique Solana Program Metadata
## 1. Validation ayant révélé le défaut
La validation Mainnet a importé deux pages de 100 transactions du programme `ProgM6JCCvbYkfKqJYHePx4xxSUSqJp7rh8Lyv7nk7S`, puis extrait 200 transactions et rejoué 582 instructions. Le processeur `metadata.solana_program_metadata` a reconnu et dispatché 132 instructions, mais les 132 ont terminé en échec de décodage.
Les surfaces observées étaient :
| Instruction | Observations |
|-----------------|-------------:|
| `write` | 88 |
| `allocate` | 15 |
| `initialize` | 11 |
| `set_authority` | 7 |
| `close` | 5 |
| `set_data` | 5 |
| `set_immutable` | 1 |
| `trim` | 0 |
| `extend` | 0 |
Le fait que toutes les instructions observées échouent malgré des discriminants reconnus et des transactions réussies indique un défaut transversal après reconnaissance, et non sept défauts wire indépendants.
## 2. Cause
`MdCoreInstructionReplayInput.account_keys_json` est produit depuis len-tête du message Solana. Ses champs `signer` et `writable` représentent donc les privilèges globaux de chaque clé pour lensemble de la transaction.
Le décodeur comparait ces champs par égalité avec les privilèges minimaux documentés pour chaque position de linstruction. Cette égalité est invalide : une autorité peut être readonly dans le contrat de linstruction tout en étant writable au niveau du message parce quelle est aussi fee payer ou intervient comme compte writable dans une autre instruction.
Le programme on-chain vérifie les privilèges nécessaires, notamment `authority.is_signer()`, mais ne refuse pas un sur-ensemble de privilèges fourni par le message.
## 3. Correction
La validation applique désormais les règles suivantes :
- un compte déclaré signer doit être signer dans le message ;
- un compte déclaré writable doit être writable dans le message ;
- un compte déclaré readonly peut être globalement writable ;
- un compte déclaré non-signer peut être globalement signer ;
- les positions, rôles, placeholders optionnels et contrats de source restent vérifiés séparément ;
- labsence dun privilège requis reste un échec fermé.
Une régression couvre les neuf instructions stables avec une autorité globalement signer et writable.
## 4. Validation à rejouer
Après application du correctif, relancer les 132 entrées en échec, de préférence avec le replay forcé limité au programme `ProgM6…`. Le résultat attendu est :
- `decoded = 132` ;
- `failed = 0` ;
- une matérialisation pour chaque instruction committée ;
- `trim` et `extend` restent non observés dans cet échantillon et devront être couverts par les scénarios Devnet.