# Validation `0.3.16` -> `0.3.18` — résilience RAW et gestion des conflits ## 1. Objet Ce document suit le programme de résilience RAW depuis le gate `0.3.16-pre.001` jusqu'à la fermeture prévue de `0.3.18`. La présente révision réconcilie spécifiquement l'état réellement validé de `0.3.16` avant sa lane de préparation de publication. La première tranche ne prétend pas valider une implémentation qui n'existe pas encore. Elle valide le point de départ, les contrats acquis, les décisions d'architecture et la liste des preuves à construire. Le fix documentaire `0.3.16-pre.001-fix.001` répartit ensuite cette matrice sur trois releases stables afin de respecter la contrainte opérationnelle d'une version par session au maximum. ## 2. Base stable Base requise : ```text v0.3.15 commit 7328be6997399c513306f2f4c8cdf00bd8b22367 ``` Le delta stable `0.3.15-rel.001` documente : ```text cargo fmt --all -- --check : PASS General Rust rule audit : clean Rust export completeness audit : 0 candidate(s) KSP workspace Rust rule audit : clean Markdown table audit : clean (318 table(s), 232 file(s)) cargo check --workspace : PASS ``` Il documente également le gate technique/live de `pre.016`, le live Mainnet Yellowstone + HTTP Block Polling d'environ dix-neuf minutes et la fermeture `Stopped/Healthy` des deux routes. Ces résultats appartiennent à la fermeture `0.3.15` ; ils ne sont pas revendiqués comme réexécutés par `0.3.16-pre.001`. ## 3. Limitation de vérification de l'archive source dans l'environnement d'assemblage L'arbre canonique du tag et le commit stable ont été vérifiés via le dépôt public. L'archive binaire source `v0.3.15.zip` n'a pas pu être matérialisée dans l'environnement d'assemblage de `pre.001`. Aucun SHA/CRC ou byte-compare local de cette archive n'est donc déclaré PASS ici. Cette limitation ne doit pas être masquée par les gates historiques du delta stable. Après application du delta sur le checkout utilisateur taggé `v0.3.15`, les scripts et commandes du dépôt restent l'autorité de validation locale. ## 4. Vérification des règles Le gate `pre.001` a réaudité les familles de règles requises par le prompt : ```text RULES.md RULES_GENERAL.md RULES_KSP.md RULES_RUST.md RULES_DEPENDENCIES.md RULES_DOCUMENTATION.md FILE_CONTRACTS.md VERSION_WORKFLOW.md PROMPT_STRUCTURE.md ``` Décisions directement dérivées de ces règles : - première livraison `0.3.16-pre.001` -> Cargo `0.3.16-pre.1` ; - aucun Rust ni SQL lourd dans le gate d'ouverture ; - delta minimal ; - migrations V000/V001/V002 immuables ; - Store-lib façade unique ; - aucune dépendance Worker <-> Job Backfill ; - aucune queue non bornée ; - aucun PASS inventé ; - pas de `npm run build` comme gate Desk. ## 5. Inventaire de caractérisation `0.3.15` ### 5.1 Store RAW Caractérisé : ```text identity = network + signature au contrat backend PostgreSQL = une base liée à un network canonical unique actuel atomic canonical + observation additional observation content_conflict terminal hors cas narrow logs retention Full / Archived / Purged / ForceRehydrate ``` ### 5.2 Outcomes actuels Caractérisés : ```text Inserted AlreadyPresent Rehydrated SkippedPurged Observation: Inserted AlreadyPresent NotRecorded ``` ### 5.3 PostgreSQL Caractérisé : ```text V000/V001/V002 migration registry + checksum transaction d'écriture collision identité SELECT ... FOR UPDATE comparaison canonique observation transactionnelle retention sous verrou ``` ### 5.4 Worker Caractérisé : ```text convergence run-local existante Store content_conflict -> faute persistence faute persistence -> arrêt de source / route terminale pas de Store retry policy dédiée comparable au reconnect Transport ``` ### 5.5 Transport Caractérisé : ```text HTTP request retry déjà Transport-owned WebSocket reconnect borné avec backoff Yellowstone reconnect borné avec backoff Config projection déjà existante ``` ### 5.6 Store Desk Caractérisé : ```text inspection via ksp-store-lib pas de SQL direct pas encore de variants/conflicts/resolution actions ``` ## 6. Preuves externes réauditées ### 6.1 Log truncation Le collecteur SVM courant expose : ```text LOG_MESSAGES_BYTES_LIMIT = 10 * 1000 ``` et ajoute exactement : ```text Log truncated ``` une seule fois lorsque la limite est atteinte/dépassée, puis cesse d'enregistrer les lignes suivantes. Canari requis pour `0.3.16-pre.005` : ```text truncated exact prefix + marker vs full continuation -> Less/More selon direction different prefix before marker -> Conflict shorter list without marker -> Conflict/Incomparable ``` ### 6.2 Autres champs RPC La documentation Solana actuelle montre des différences de sérialisation/optionnalité pour : ```text innerInstructions loadedAddresses returnData computeUnitsConsumed costUnits rewards preTokenBalances postTokenBalances ``` Canari de politique : aucune de ces différences ne produit `CompatibleLessComplete` ou `CompatibleMoreComplete` sans nouvelle preuve normative explicite. ### 6.3 PostgreSQL Les mécanismes retenus sont compatibles avec la stratégie : - `SELECT ... FOR UPDATE` sérialise les writers/lockers concurrents d'une même ligne jusqu'à fin de transaction ; - `INSERT ... ON CONFLICT` possède une sémantique atomique pour les conflits arbitrés ; - certaines fautes d'isolation/serialization exigent le retry de la transaction complète. Ces propriétés doivent être traduites en tests KSP et non seulement citées dans la documentation. ## 7. Décisions fermées par `pre.001` ### 7.1 Modèle physique Décision : ledger V003 de variantes à `variant_id` surrogate + sélecteur canonique sidecar + projection V001 compatible. ### 7.2 Hash Décision : `content_hash` est un préfiltre/intégrité, jamais la preuve unique d'égalité lorsque les bytes sont disponibles. ### 7.3 Observations Décision : toute nouvelle observation V003 pointe vers la variante réellement reçue. Les observations legacy impossibles à reconstruire sont qualifiées explicitement comme telles. ### 7.4 Rétention Décision : toute variante requise pour conflit ouvert, canonique courant, restauration ou parent synthétique peut être archivée mais reste protégée contre une purge irréversible tant que l'invariant de rollback dépend de ses bytes. ### 7.5 Conflict case Décision : état principal `Open | Resolved`, réouverture possible, journal append-only des transitions/résolutions. ### 7.6 Qualité Décision : relation interne : ```text Exact CompatibleLessComplete CompatibleMoreComplete Conflict Incomparable ``` `Incomparable` est persisté prudemment comme réconciliation ouverte. ### 7.7 Store retry Décision : ```text Store backend -> classifie Transient/Terminal Worker -> orchestre retry/backpressure/health ``` ### 7.8 Transport reconnect Décision : reste dans `ksp-onchain-transport-lib` ; extension du mécanisme existant, sans fusion conceptuelle avec Store retry ni coverage. ### 7.9 Store Desk Décision : conflits/historique/actions via `ksp-store-lib` uniquement, bridge Tauri typé, frontend Vite/TypeScript, actions protégées par revision attendue. ## 8. Matrice de preuves à construire ### 8.1 API À prouver : - roundtrip/égalité des DTO variant/conflict/history ; - reason codes stables ; - outcomes distincts ; - classification Store transient/terminal sans type PostgreSQL exposé. ### 8.2 Migration V003 À prouver : - checksums V000/V001/V002 inchangés ; - V003 idempotente dans le registry ; - base vide ; - base existante Full ; - base existante Archived ; - base existante Purged ; - observation legacy non faussement attribuée ; - rollback de migration selon contrat KSP si applicable. ### 8.3 Variants/convergence À prouver : - exact concurrent -> une variante logique ; - less complete logs -> canonique inchangé ; - more complete logs -> promotion atomique ; - conflict -> canonique inchangé + variante durable + case Open ; - incomparable -> fail-closed durable ; - hash identique + payload différent -> jamais fusionné par hash seul. ### 8.4 Promotions À prouver : - selector et projection V001 cohérents après commit ; - ancien canonique conservé ; - restore local sans Internet ; - stale revision rejetée ; - crash/rollback ne laisse pas selector/projection divergents. ### 8.5 Rétention À prouver : - archive d'une variante rollbackable conserve bytes exacts ; - purge refusée lorsqu'une variante est épinglée ; - ForceRehydrate exact ; - ForceRehydrate payload différent -> nouvelle variante ; - legacy Purged ne prétend pas disposer d'une égalité byte-exact perdue. ### 8.6 Worker À prouver : - conflit durable -> route Running, health Degraded ; - autre identité continue ; - Store transient -> retry sans success prématuré ; - queue bornée -> backpressure ; - policy exhausted -> terminal explicite ; - Stop pendant backoff -> cancellation/drain propre. ### 8.7 Transport À prouver : - backoff initial/max/multiplier ; - max attempts ; - reset stable ; - jitter borné ; - reconnexion != coverage ; - comportement HTTP existant non régressé. ### 8.8 Store Desk À prouver : - pagination bornée ; - aucune dépendance backend direct ; - promote/keep/restore/reopen typés ; - stale action visible et recharge ; - aucune donnée sensible dans tracing frontend/backend ; - build via Tauri/Vite seulement. ## 9. Gate opérateur `0.3.16-pre.001` exécuté après application Le 20 septembre 2026, l'opérateur a exécuté sur son checkout KSP après application de `pre.001` : ```bash cargo fmt --all -- --check python3 scripts/audit_rust_workspace_rules.py python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas cargo check --workspace cargo clippy --workspace --all-targets --all-features -- -D warnings ``` Résultats observés dans le transcript fourni : ```text cargo fmt --all -- --check : aucun diagnostic affiché General Rust rule audit : clean Rust export completeness audit : 0 candidate(s) KSP workspace Rust rule audit : clean Markdown table audit : clean (352 table(s), 941 file(s)) cargo check --workspace : Finished dev profile (32.69 s) cargo clippy --workspace --all-targets --all-features -- -D warnings : Finished dev profile (12.26 s) ``` Le workspace résout bien les crates sur `v0.3.16-pre.1`. Aucun `npm run build` n'a été utilisé et aucun test live/provider/PostgreSQL n'était requis par ce gate documentaire. Ce résultat ferme le gate local demandé par `pre.001` et autorise la tranche d'implémentation suivante après application du présent fix documentaire. ## 10. Gate de sortie `pre.001` État documentaire : ```text modèle conceptuel CLOSED frontières de crates CLOSED avec vérification Cargo à chaque tranche migration strategy CLOSED logMessages quality semantics CLOSED other field policy CLOSED / fail-closed Store retry ownership CLOSED Transport reconnect ownership CLOSED Store Desk scope CLOSED races/retention risks IDENTIFIED prerelease sizing RECALIBRATED sur 0.3.16 -> 0.3.18 out-of-scope CLOSED ``` Le gate local `0.3.16-pre.001` est maintenant documenté comme propre. Après application de `0.3.16-pre.001-fix.001`, l'implémentation peut commencer en `0.3.16-pre.002` selon le découpage multi-version du plan 038. ## 11. Répartition des preuves par release Le fix `0.3.16-pre.001-fix.001` ne supprime aucune preuve de la matrice ; il change uniquement leur release cible : ```text 0.3.16 : API variantes + V003 + persistance + comparateur + promotion + conflit durable + Worker non terminal 0.3.17 : résolution + rétention + Store-lib + retry Worker + reconnect Transport + preuves live de résilience 0.3.18 : Store Desk + actions opérateur + éventuelle fusion synthétique prouvée + hardening end-to-end ``` Chaque stable possède son propre gate de fermeture. Une preuve non nécessaire au périmètre de la stable courante n'est pas déclarée manquante : elle reste explicitement attendue par la version suivante du programme. Les scopes Backfill initialement réservés à `0.3.17` et `0.3.18` sont déplacés après ce programme afin d'éviter une collision de roadmap ; les cibles de planning par défaut deviennent respectivement `0.3.19` et `0.3.20`. ## 12. Réconciliation finale `0.3.16-pre.009` ### 12.1 Périmètre réellement acquis par `0.3.16` La vertical slice `0.3.16` ferme les éléments suivants : ```text Store API RawTransactionVariantId / relation / reason code comparateur partagé fail-closed RawTransactionVariantWriteOutcome RawAcquisitionWriteOutcome::transaction_variant() PostgreSQL V003 ksp_raw_transaction_variants ksp_raw_transaction_canonical_selectors ksp_raw_transaction_observation_variants ksp_raw_transaction_conflicts Convergence Exact -> observation/réutilisation de variante CompatibleLessComplete -> variante observée, canonique inchangé CompatibleMoreComplete -> promotion atomique Conflict / Incomparable -> variante durable + conflict case Open, canonique inchangé Worker toute acquisition atteint le Store après sérialisation run-local par identité QuarantinedConflict -> succès durable, Running + Degraded identité suivante -> continue à être traitée ERROR_CODE_RAW_CONFLICT legacy -> terminal de compatibilité Job Backfill QuarantinedConflict -> BackfillEntityPersistence::Conflict outcome observation -> conservé, y compris AlreadyPresent ``` `content_hash` reste un préfiltre/intégrité et ne remplace jamais la comparaison des bytes lorsque ceux-ci sont disponibles. La seule dominance automatique admise en `0.3.16` reste la troncature `meta.logMessages` strictement prouvée ; les autres différences restent fail-closed. ### 12.2 Atomicité et rollback validés Le hardening `pre.008` verrouille les invariants suivants : - la branche de conflit ne modifie ni le sélecteur canonique ni la projection V001 ; - les helpers de promotion et de conflict case restent dans la transaction d'acquisition externe ; - un échec tardif après création de la variante divergente et du conflict case mais avant `COMMIT` annule ces écritures ; - après rollback, selector et projection V001 restent cohérents avec le canonique antérieur ; - deux écritures divergentes concurrentes produisent un canonique et une quarantaine durable, pas une erreur terminale de contenu. ### 12.3 Gate opérateur `0.3.16-pre.008-fix.001` Le 22 septembre 2026, l'opérateur a exécuté : ```bash cargo fmt --all cargo fmt --all -- --check python3 scripts/audit_rust_workspace_rules.py python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas cargo check --workspace cargo clippy --workspace --all-targets --all-features -- -D warnings cargo test -p ksp-store-api --all-targets --all-features cargo test -p ksp-store-lib --all-targets --all-features cargo test -p ksp-store-postgres-lib --all-targets --all-features cargo test -p ksp-job-backfill-lib --all-targets --all-features cargo test -p ksp-worker-raw-transaction-ingest-lib --all-targets --all-features ``` Résultats observés : ```text cargo fmt --all -- --check PASS General Rust rule audit clean Rust export completeness audit 0 candidate(s) KSP workspace Rust rule audit clean Markdown table audit clean (352 table(s), 958 file(s)) cargo check --workspace PASS cargo clippy --workspace --all-targets --all-features -D warnings PASS ksp-store-api 29 unit + 2 dependency + 1 external backend + 9 public API + 5 release completeness + 5 security hardening PASS ksp-store-lib 10 unit + 3 dependency + 1 feature mismatch + 6 hardening completeness + 5 public API PASS ksp-store-postgres-lib 88 unit + 13 dependency + 16 hardening completeness + 13 public API + 3 V003 migration + 8 V003 variant PASS foundation/raw-account/raw-transaction live tests ignored in normal gate as designed ksp-job-backfill-lib 53 unit + 4 dependency + 9 hardening + 1 HTTP block material + 6 public API + 3 release + 2 WS parity + 1 Yellowstone PASS ksp-worker-raw-transaction-ingest-lib 163 unit + 12 cross-layer + 21 dependency + 41 hardening + 22 public API + 18 release completeness PASS ``` Aucun warning Clippy n'est toléré par ce gate. ### 12.4 Preuve PostgreSQL réelle Le live RawTransaction a été exécuté séparément avec une URI dédiée fournie silencieusement sur stdin : ```bash read -rsp 'PostgreSQL URI: ' KSP_TEST_POSTGRES_URI printf '\n' printf '%s\n' "$KSP_TEST_POSTGRES_URI" \ | cargo test -p ksp-store-postgres-lib \ --test postgres_raw_transaction_live \ -- --ignored --nocapture unset KSP_TEST_POSTGRES_URI ``` Résultat observé : ```text KSP Store RawTransaction live proof: server major 17 test pre_009_real_postgres_raw_transaction_vertical_slice_is_atomic_concurrent_and_recoverable ... ok 1 passed; 0 failed ``` Cette preuve couvre notamment la concurrence divergente, la quarantaine durable, la cohérence selector/projection et le rollback tardif ajoutés au hardening `pre.008`. ### 12.5 Périmètre explicitement reporté Ne sont **pas** revendiqués comme acquis par `0.3.16` : ```text résolution/reopen/historique complet des conflict cases rétention/pins/purge guards propres aux variantes classification Store Transient/Terminal complète retry Store / Blocked / backoff Worker reconnexion WebSocket/Yellowstone configurable étendue inspection/résolution de variantes via ksp-store-lib Store Desk conflits/variantes/résolutions Backfill multi-route/multi-stratégie Backfill Desk multi-route ``` Les six premiers groupes appartiennent à `0.3.17`, Store Desk à `0.3.18`, puis les extensions Backfill sont ciblées par défaut sur `0.3.19`/`0.3.20`. ### 12.6 État de fermeture avant publication ```text architecture/sizing CLOSED Store API variantes/comparateur CLOSED migration V003 CLOSED variant ledger + observation mapping CLOSED promotion canonique atomique CLOSED conflit durable minimal CLOSED Worker non terminal sur quarantaine CLOSED régression Backfill CLOSED hardening concurrence/rollback CLOSED PostgreSQL RawTransaction live PASS sur PostgreSQL 17 gate technique pre.008-fix.001 PASS réconciliation documentaire pre.009 CURRENT LANE préparation publication pre.010 PENDING rel.001 PENDING ``` La lane `pre.009` ne doit modifier ni `CHANGELOG.md`, ni `ROADMAP.md`, ni le prompt de démarrage `0.3.17`. Ces trois responsabilités appartiennent exclusivement à `pre.010`.