v0.4.7-pre.003

This commit is contained in:
2026-08-02 09:04:23 +02:00
parent 7a50ddd531
commit 1bddeb834d
22 changed files with 1656 additions and 369 deletions

View File

@@ -1,20 +1,18 @@
<!-- file: docs/validation/V0_4_7_PRE_002_METAPLEX_COVERAGE_AND_FACT_OWNERSHIP.md -->
<!-- version: 1 -->
<!-- version: 2 -->
# `0.4.7-pre.002` — couverture Metaplex et propriété des faits
## Résultat
## Résultat corrigé
Le contrat couvre les 58 discriminants `0..57` sans trou ni statut ambigu. La source des comptes et signers est lIDL Metaplex archivée `V1_14_0`; la constructibilité courante est confrontée à linventaire `mpl-token-metadata 5.1.1`.
Le contrat couvre les 58 discriminants `0..57` sans trou. La classification a été corrigée pendant `pre.003` après confrontation avec les recommandations de dépréciation officielles de Metaplex : une instruction encore décodable dans lIDL historique nest pas nécessairement légitime à reconstruire.
### Classification fermée
- `decode_only_bridge_boundary` : 1 ;
- `decode_only_obsolete` : 15 ;
- `decode_only_replaced` : 22 ;
- `executable_current` : 20.
- `decode_only_bridge_boundary` : 1 instruction(s) ;
- `decode_only_obsolete` : 7 instruction(s) ;
- `decode_only_replaced` : 9 instruction(s) ;
- `executable_current` : 41 instruction(s) ;
Les opérations `executable_current` doivent toutes posséder un intent et un builder à la fin de `pre.006`. Les statuts decode-only ne peuvent être utilisés que pour une frontière Bubblegum, une opération obsolète ou une opération remplacée par une variante canonique.
Les 20 opérations courantes doivent toutes posséder un intent et un builder à la fin de `pre.006`. Les instructions remplacées ou obsolètes restent décodées et peuvent produire les faits stables prouvés, mais leur reconstruction est interdite.
## Contrat par instruction
@@ -24,38 +22,38 @@ Les opérations `executable_current` doivent toutes posséder un intent et un bu
| 1 | `UpdateMetadataAccount` | `decode_only_replaced` | `forbidden_replaced` | `—` | updateAuthority |
| 2 | `DeprecatedCreateMasterEdition` | `decode_only_obsolete` | `forbidden_obsolete` | `—` | updateAuthority, printingMintAuthority, mintAuthority, payer, oneTimePrintingAuthorizationMintAuthority |
| 3 | `DeprecatedMintNewEditionFromMasterEditionViaPrintingToken` | `decode_only_obsolete` | `forbidden_obsolete` | `—` | mintAuthority, burnAuthority, payer |
| 4 | `UpdatePrimarySaleHappenedViaToken` | `executable_current` | `required` | `pre.004` | owner |
| 4 | `UpdatePrimarySaleHappenedViaToken` | `decode_only_obsolete` | `forbidden_obsolete` | `—` | owner |
| 5 | `DeprecatedSetReservationList` | `decode_only_obsolete` | `forbidden_obsolete` | `—` | resource |
| 6 | `DeprecatedCreateReservationList` | `decode_only_obsolete` | `forbidden_obsolete` | `—` | payer, updateAuthority |
| 7 | `SignMetadata` | `executable_current` | `required` | `pre.004` | creator |
| 7 | `SignMetadata` | `decode_only_replaced` | `forbidden_replaced` | `—` | creator |
| 8 | `DeprecatedMintPrintingTokensViaToken` | `decode_only_obsolete` | `forbidden_obsolete` | `—` | burnAuthority |
| 9 | `DeprecatedMintPrintingTokens` | `decode_only_obsolete` | `forbidden_obsolete` | `—` | updateAuthority |
| 10 | `CreateMasterEdition` | `decode_only_replaced` | `forbidden_replaced` | `—` | updateAuthority, mintAuthority, payer |
| 11 | `MintNewEditionFromMasterEditionViaToken` | `executable_current` | `required` | `pre.006` | newMintAuthority, payer, tokenAccountOwner |
| 12 | `ConvertMasterEditionV1ToV2` | `decode_only_replaced` | `forbidden_replaced` | `—` | aucun |
| 11 | `MintNewEditionFromMasterEditionViaToken` | `decode_only_replaced` | `forbidden_replaced` | `—` | newMintAuthority, payer, tokenAccountOwner |
| 12 | `ConvertMasterEditionV1ToV2` | `decode_only_obsolete` | `forbidden_obsolete` | `—` | aucun |
| 13 | `MintNewEditionFromMasterEditionViaVaultProxy` | `decode_only_obsolete` | `forbidden_obsolete` | `—` | newMintAuthority, payer, vaultAuthority |
| 14 | `PuffMetadata` | `executable_current` | `required` | `pre.003` | aucun |
| 15 | `UpdateMetadataAccountV2` | `executable_current` | `required` | `pre.003` | updateAuthority |
| 14 | `PuffMetadata` | `decode_only_obsolete` | `forbidden_obsolete` | `—` | aucun |
| 15 | `UpdateMetadataAccountV2` | `decode_only_replaced` | `forbidden_replaced` | `—` | updateAuthority |
| 16 | `CreateMetadataAccountV2` | `decode_only_replaced` | `forbidden_replaced` | `—` | mintAuthority, payer |
| 17 | `CreateMasterEditionV3` | `executable_current` | `required` | `pre.006` | updateAuthority, mintAuthority, payer |
| 18 | `VerifyCollection` | `executable_current` | `required` | `pre.004` | collectionAuthority, payer |
| 19 | `Utilize` | `executable_current` | `required` | `pre.006` | useAuthority |
| 20 | `ApproveUseAuthority` | `executable_current` | `required` | `pre.006` | owner, payer |
| 21 | `RevokeUseAuthority` | `executable_current` | `required` | `pre.006` | owner |
| 22 | `UnverifyCollection` | `executable_current` | `required` | `pre.004` | collectionAuthority |
| 23 | `ApproveCollectionAuthority` | `executable_current` | `required` | `pre.004` | updateAuthority, payer |
| 24 | `RevokeCollectionAuthority` | `executable_current` | `required` | `pre.004` | revokeAuthority |
| 25 | `SetAndVerifyCollection` | `executable_current` | `required` | `pre.004` | collectionAuthority, payer |
| 17 | `CreateMasterEditionV3` | `decode_only_replaced` | `forbidden_replaced` | `—` | updateAuthority, mintAuthority, payer |
| 18 | `VerifyCollection` | `decode_only_replaced` | `forbidden_replaced` | `—` | collectionAuthority, payer |
| 19 | `Utilize` | `decode_only_obsolete` | `forbidden_obsolete` | `—` | useAuthority |
| 20 | `ApproveUseAuthority` | `decode_only_obsolete` | `forbidden_obsolete` | `—` | owner, payer |
| 21 | `RevokeUseAuthority` | `decode_only_obsolete` | `forbidden_obsolete` | `—` | owner |
| 22 | `UnverifyCollection` | `decode_only_replaced` | `forbidden_replaced` | `—` | collectionAuthority |
| 23 | `ApproveCollectionAuthority` | `decode_only_replaced` | `forbidden_replaced` | `—` | updateAuthority, payer |
| 24 | `RevokeCollectionAuthority` | `decode_only_replaced` | `forbidden_replaced` | `—` | revokeAuthority |
| 25 | `SetAndVerifyCollection` | `decode_only_replaced` | `forbidden_replaced` | `—` | collectionAuthority, payer |
| 26 | `FreezeDelegatedAccount` | `decode_only_replaced` | `forbidden_replaced` | `—` | delegate |
| 27 | `ThawDelegatedAccount` | `decode_only_replaced` | `forbidden_replaced` | `—` | delegate |
| 28 | `RemoveCreatorVerification` | `executable_current` | `required` | `pre.004` | creator |
| 28 | `RemoveCreatorVerification` | `decode_only_replaced` | `forbidden_replaced` | `—` | creator |
| 29 | `BurnNft` | `decode_only_replaced` | `forbidden_replaced` | `—` | owner |
| 30 | `VerifySizedCollectionItem` | `executable_current` | `required` | `pre.004` | collectionAuthority, payer |
| 31 | `UnverifySizedCollectionItem` | `executable_current` | `required` | `pre.004` | collectionAuthority, payer |
| 32 | `SetAndVerifySizedCollectionItem` | `executable_current` | `required` | `pre.004` | collectionAuthority, payer |
| 33 | `CreateMetadataAccountV3` | `executable_current` | `required` | `pre.003` | mintAuthority, payer |
| 34 | `SetCollectionSize` | `executable_current` | `required` | `pre.004` | collectionAuthority |
| 35 | `SetTokenStandard` | `executable_current` | `required` | `pre.003` | updateAuthority |
| 30 | `VerifySizedCollectionItem` | `decode_only_replaced` | `forbidden_replaced` | `—` | collectionAuthority, payer |
| 31 | `UnverifySizedCollectionItem` | `decode_only_replaced` | `forbidden_replaced` | `—` | collectionAuthority, payer |
| 32 | `SetAndVerifySizedCollectionItem` | `decode_only_replaced` | `forbidden_replaced` | `—` | collectionAuthority, payer |
| 33 | `CreateMetadataAccountV3` | `decode_only_replaced` | `forbidden_replaced` | `—` | mintAuthority, payer |
| 34 | `SetCollectionSize` | `decode_only_obsolete` | `forbidden_obsolete` | `—` | collectionAuthority |
| 35 | `SetTokenStandard` | `decode_only_obsolete` | `forbidden_obsolete` | `—` | updateAuthority |
| 36 | `BubblegumSetCollectionSize` | `decode_only_bridge_boundary` | `forbidden_cross_program_boundary` | `—` | collectionAuthority, bubblegumSigner |
| 37 | `BurnEditionNft` | `decode_only_replaced` | `forbidden_replaced` | `—` | owner |
| 38 | `CreateEscrowAccount` | `executable_current` | `required` | `pre.006` | payer, authority |
@@ -79,51 +77,18 @@ Les opérations `executable_current` doivent toutes posséder un intent et un bu
| 56 | `Resize` | `executable_current` | `required` | `pre.006` | authority |
| 57 | `CloseAccounts` | `executable_current` | `required` | `pre.005` | authority |
Les listes positionnelles complètes des comptes, leurs flags writable/signer, les préflights et les postconditions sont conservés sous `instruction_execution_contract` dans la matrice JSON active.
## Propriété des faits
## Propriété unique des faits
La matrice contient 26 faits à propriétaire unique. Les domaines Metaplex et Token-2022 embedded restent séparés.
| Fait | Propriétaire | Source autoritative |
|--------------------------------------|-------------------|---------------------------------------------------|
| `metadata.name` | `metadata` | `MetadataV1.name` |
| `metadata.symbol` | `metadata` | `MetadataV1.symbol` |
| `metadata.uri` | `metadata` | `MetadataV1.uri` |
| `metadata.seller_fee_basis_points` | `metadata` | `MetadataV1.seller_fee_basis_points` |
| `metadata.creators` | `metadata` | `MetadataV1.data.creators` |
| `metadata.collection` | `metadata` | `MetadataV1.collection` |
| `metadata.uses` | `metadata` | `MetadataV1.uses` |
| `metadata.token_standard` | `metadata` | `MetadataV1.token_standard` |
| `metadata.is_mutable` | `metadata` | `MetadataV1.is_mutable` |
| `metadata.programmable_config` | `metadata` | `MetadataV1.programmable_config` |
| `admin.update_authority` | `admin` | `MetadataV1.update_authority` |
| `admin.collection_authority` | `admin` | `CollectionAuthorityRecord` |
| `admin.use_authority` | `admin` | `UseAuthorityRecord` |
| `admin.delegate` | `admin` | `MetadataDelegate/HolderDelegate/TokenRecord` |
| `lifecycle.primary_sale_happened` | `lifecycle` | `MetadataV1.primary_sale_happened` |
| `lifecycle.edition` | `lifecycle` | `Edition/MasterEdition` |
| `lifecycle.edition_marker` | `lifecycle` | `EditionMarker/EditionMarkerV2` |
| `lifecycle.programmable_token_state` | `lifecycle` | `TokenRecord.state` |
| `lifecycle.locked_transfer` | `lifecycle` | `TokenRecord.locked_transfer` |
| `lifecycle.token_owned_escrow` | `lifecycle` | `TokenOwnedEscrow` |
| `lifecycle.historical_reservation` | `lifecycle` | `ReservationListV1/V2` |
| `risk.royalty_configuration` | `risk_compliance` | `seller_fee_basis_points fact reference` |
| `risk.unverified_creators` | `risk_compliance` | `creators verification fact reference` |
| `risk.mutable_metadata` | `risk_compliance` | `is_mutable fact reference` |
| `risk.rule_set` | `risk_compliance` | `programmable_config rule_set fact reference` |
| `risk.sensitive_delegation` | `risk_compliance` | `delegate records and TokenRecord fact reference` |
## Validations exécutées par lopérateur pour `pre.002`
Les observations dinstruction décrivent uniquement les mutations. Les snapshots de comptes possédés restent autoritatifs pour létat final et ne doivent jamais être dupliqués par une projection concurrente.
```text
cargo fmt --all OK
cargo check --workspace OK
cargo clippy --all-targets OK
python3 scripts/audit_rust_workspace_rules.py clean
cargo test -p kb-lib 627 + 4 tests OK
```
## Non-fusion Token-2022
- domaine Metaplex : `metaplex_token_metadata` ;
- domaine Token-2022 : `spl_token_2022_embedded_metadata` ;
- aucune identité, URI ou autorité nest fusionnée implicitement entre les deux domaines ;
- une corrélation ultérieure doit conserver les deux provenances et signaler les conflits.
## Validation disponible dans cet environnement
- parsing JSON : effectué ;
- inventaire `0..57` : effectué ;
- unicité des faits : effectuée ;
- tests Cargo : non exécutés, car `cargo` est absent de lenvironnement de préparation.
La classification corrigée et le code de `pre.003` doivent être revalidés avant acceptation.

View File

@@ -0,0 +1,58 @@
<!-- file: docs/validation/V0_4_7_PRE_003_METAPLEX_EXECUTOR_FOUNDATIONS.md -->
<!-- version: 3 -->
# `0.4.7-pre.003` — fondations de lexécuteur Metaplex
## Portée
Cette prerelease remplace la frontière réservée de lexécuteur Metaplex Token Metadata par une surface typée initiale comprenant :
- `Create`, discriminant `42`, avec `CreateArgs::V1` ;
- `Update`, discriminant `50`, avec `UpdateArgs::AsUpdateAuthorityV2` ;
- `PuffMetadata`, discriminant `14`, exécutable dépréciée ;
- `SetTokenStandard`, discriminant `35`, exécutable dépréciée.
Les autres variantes du wrapper `Update` restent planifiées selon leurs domaines dautorité. Les anciennes instructions create/update remplacées restent decode-only et pointent vers leur wrapper canonique final.
## Contrats introduits
- intents typés et codes dopération stables ;
- `#[deprecated]` sur les variantes Rust obsolètes ;
- approbation opérateur runtime obligatoire pour toute opération dépréciée ;
- builders officiels `mpl-token-metadata 5.1.x` ;
- validation des PDA metadata et edition ;
- comptes et signers exacts dérivés de linstruction construite ;
- simulation obligatoire et dry-run imposé pour cette première tranche ;
- plafonds positifs de frais et de dépense ;
- paire complète obligatoire pour les comptes Token Authorization Rules ;
- autorisation explicite de chaque signer requis ;
- erreurs fail-closed avant production du plan préparé.
## Classification corrigée
- 20 instructions courantes et constructibles ;
- 15 instructions obsolètes mais constructibles, classées `executable_deprecated` ;
- 22 instructions remplacées par leur version canonique finale ;
- 1 frontière Bubblegum.
`pre.003` implémente les deux opérations courantes de sa tranche et les deux opérations obsolètes qui lui sont affectées. Les autres opérations dépréciées sont réparties jusquà `pre.006`.
## Validation attendue
```bash
cargo fmt --all
cargo check --workspace
cargo clippy --all-targets
python3 scripts/audit_rust_workspace_rules.py
cargo test -p kb-lib
```
Cargo nest pas disponible dans lenvironnement de préparation. Les validations Rust doivent être exécutées par lopérateur avant acceptation.
## Correctif de conformité `fix-002`
- la dépendance directe `solana-program` introduite par `pre.003` est retirée ;
- les contrats internes reposent sur `solana_instruction::Instruction` et `solana_pubkey::Pubkey` ;
- les types historiques internes de `mpl-token-metadata 5.1.1` sont laissés à linférence puis convertis immédiatement, sans fuite dans lAPI de `kb-lib` ;
- tous les usages de lopérateur `?` introduits dans le builder et le dispatcher Metaplex sont remplacés par une propagation explicite des erreurs ;
- les TODO de réaudit des exécuteurs Solana Core/SPL et de lorchestration pipeline sont enregistrés pour une version ultérieure à déterminer.