# Validation `0.3.17` — résilience opérationnelle et cycle de vie des variantes RAW ## 1. Objet Ce document suit les preuves de `0.3.17`. La révision initiale correspond au gate `0.3.17-pre.001`. Elle valide le point de départ, l'audit des règles, le modèle conceptuel, le sizing et la matrice de preuves à construire. Elle ne déclare aucune implémentation future comme acquise. ## 2. Base source reçue Archive source fournie pour l'ouverture : ```text khadhroony-solana-project-v0.3.16.zip ``` SHA-256 local de l'archive reçue : ```text db3cc1b3fc3fb07ee864b02e2a7346c673d4cf63b33e8e872aca6c6458856ca0 ``` L'arbre extrait déclare : ```text workspace.package.version = 0.3.16 edition = 2024 workspace members = 22 ``` Le handoff stable est complet : `pre.001` à `pre.010`, les `fix.*` réellement publiés et `rel.001` sont présents sous `deltas/0.3.16/`. L'archive contient également le prompt `036` attendu et les plans/validations de fermeture `0.3.16`. ## 3. Limite de vérification du tag La provenance annoncée par l'opérateur est le ZIP téléchargé depuis le tag Gitea `v0.3.16`. L'environnement local d'assemblage ne dispose pas d'un accès Git/DNS exploitable vers le dépôt permettant de comparer indépendamment le SHA du commit taggé avec cette archive. Le gate ne transforme donc pas cette absence de comparaison réseau en faux PASS. Contrôles réellement établis sur les bytes fournis : ```text version stable interne = 0.3.16 rel.001 présent prompt 036 présent inventaire deltas 0.3.16 complet manifests membres cohérents aucun lockfile versionné aucun target/node_modules/.git distribué aucune clé .pem/.key détectée ``` ## 4. Audit des règles avant modification Commandes réellement exécutées dans l'environnement d'assemblage : ```bash 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 ``` Résultat : ```text 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), 962 file(s)) ``` Contrôle statique complémentaire : ```text workspace_version = 0.3.16 workspace_members = 22 delta_0.3.16_count = 21 manifest members inherit workspace version/edition = PASS mandatory rule/handoff files present = PASS forbidden distribution artifacts = absent root rust/clippy lint contract = exact ``` ## 5. Gate Cargo de la stable fourni par l'opérateur Le log joint à la session de démarrage documente sur la stable `0.3.16` : ```text cargo fmt --all cargo fmt --all -- --check Rust audits Markdown audit cargo check --workspace cargo clippy --workspace --all-targets --all-features -- -D warnings ``` ainsi que les suites ciblées : ```text ksp-store-api ksp-store-lib ksp-store-postgres-lib ksp-job-backfill-lib ksp-worker-raw-transaction-ingest-lib ``` Ces résultats appartiennent au checkout utilisateur `0.3.16` et ne sont pas présentés comme réexécutés dans l'environnement d'assemblage. ## 6. Limitation Cargo de `pre.001` Le binaire `cargo` n'est pas disponible dans l'environnement d'assemblage. Les commandes suivantes sont donc `NOT RUN` ici après le bump `0.3.17-pre.1` : ```text cargo fmt --all -- --check cargo check --workspace cargo clippy --workspace --all-targets --all-features -- -D warnings cargo test ... ``` `pre.001` ne modifie aucun Rust. Le gate opérateur demandé après application reste néanmoins obligatoire. ## 7. Sources internes auditées Relues conformément au prompt : ```text gouvernance/règles complètes handoff 0.3.16 complet Store API README/USAGE/src/tests Store lib README/USAGE/src/tests PostgreSQL README/USAGE/src/tests/unit_tests/resources Common RAW README/USAGE/src/tests Worker API + Worker RAW README/USAGE/src/tests/unit_tests Transport README/USAGE/src/tests Config README/USAGE/src/tests Backfill README/USAGE + persistence/tests ciblés architectures 004/009/011 validation 033 ``` ## 8. Constat Store API Acquis : ```text variant identity/reference/origin variant relation + reason shared fail-closed comparator variant-aware acquisition outcome minimal conflict status Open/Resolved canonical/observation inspection canonical retention contracts ``` Manquant pour `0.3.17` : ```text variant inspection capability conflict inspection capability participant projection history read capability resolution/reopen action capability expected conflict revision expected canonical revision stable stale-action outcome backend-neutral StoreErrorClass ``` Verdict du gate : ```text CONTRACT GAP CONFIRMED ``` ## 9. Constat PostgreSQL V003 V003 est additive et fournit : ```text variants canonical selector + revision observation -> variant mapping minimal conflict current row ``` La table conflit courante est une projection, pas un historique complet. Manquant : ```text participants monotones append-only transitions resolved target/action legacy bootstrap qualification operator CAS actions variant archive sidecar/purge guards ``` Verdict : ```text V004 ADDITIVE REQUIRED V000/V001/V002/V003 MUST REMAIN IMMUTABLE ``` ## 10. Constat locks/races L'acquisition actuelle verrouille d'abord la row canonical V001 puis manipule V003 dans la même transaction. La promotion canonique utilise un selector revisionné et CAS ; le conflict current row utilise lui aussi une revision monotone. Le gate fixe l'ordre cible : ```text V001 transaction identity -> selector -> conflict current row -> variants ordered by variant_id if lock needed -> participant/history/retention sidecars -> projection updates -> commit ``` Aucune attente externe n'est autorisée sous transaction. Scénarios obligatoires : ```text ingestion vs resolution promotion auto vs manual resolution resolution A vs resolution B resolved -> new divergence -> reopen retention vs resolution ForceRehydrate exact/different late failure -> full rollback ``` Verdict : ```text CAS MODEL DEFINED RACE MATRIX DEFINED IMPLEMENTATION PENDING pre.003-pre.005 ``` ## 11. Constat rétention V003 conserve un `retention_state` sur chaque variante mais ne matérialise pas encore l'archive locale complète des payloads de variante. Politique validée au gate : ```text variant row identity never deleted when referenced current canonical payload cannot be purged Open conflict participant payload cannot be purged history retains identity but is not an eternal payload pin by itself archive is allowed when guards permit purge is explicit, never automatic Store policy restore uses local Full/Archived bytes only purged restore target -> explicit VariantPayloadUnavailable network is not normal rollback ForceRehydrate does not select a historical variant ``` Verdict : ```text RETENTION/PIN SEMANTICS DEFINED PHYSICAL ARCHIVE IMPLEMENTATION PENDING pre.005 ``` ## 12. Constat Store errors Aujourd'hui : ```text Deadpool timeout -> PoolTimeout Deadpool backend/closed -> ConnectFailed statement/transaction errors -> frequently ReadFailed/WriteFailed ``` La dernière catégorie perd trop tôt le SQLSTATE et ne permet pas une classification retry sûre. Politique retenue : ```text StoreErrorClass = Transient | Terminal classifier contract backend-neutral unknown code -> Terminal SQLSTATE inspected privately before redaction no free-form DB text in public errors ``` Transient initialement autorisés : ```text connection/reset/unavailable after valid config pool timeout/unavailable 40001 serialization_failure 40P01 deadlock_detected 57P01 admin_shutdown 57P02 crash_shutdown 57P03 cannot_connect_now ``` Terminal initialement autorisés : ```text config/secret/TLS local invalid backend not compiled wrong network model/query/data invalid migration mismatch/schema newer KSP invariant constraint failure legacy raw conflict stale revision retention/pin conflict missing/unavailable variant for local action ``` `23505` et `23P01` ne sont jamais generic-retry par défaut. Verdict : ```text CLASSIFICATION POLICY DEFINED PHYSICAL MAPPING PENDING pre.006 ``` ## 13. Constat Worker retry/Blocked Le Worker a aujourd'hui : ```text admission queue bounded: default 256, max 65536 persistence concurrency: default 8, max 64 shutdown drain timeout: default 10 s, max 30 s no Store retry settings WorkerActivity = Unknown/Idle/Active ``` Politique retenue : ```text retry owned by Worker no retry queue persistence permit held across retry sequence max_retries default 5, maximum 20 initial backoff default 250 ms max backoff default 5 s absolute settings backoff max 30 s no jitter in first implementation sleep stop-preemptible Transient -> Running/Blocked/Degraded recovery -> Running/Active-or-Idle exhaustion/Terminal -> Faulted/Unhealthy ``` Verdict : ```text RETRY/BACKPRESSURE MODEL DEFINED WORKER IMPLEMENTATION PENDING pre.007 ``` ## 14. Constat Transport/Config WebSocket : reconnect déjà existant avec max retries/backoff/resubscribe et stop-aware actor. Yellowstone : reconnect déjà existant, `from_slot`, `SubscribeReplayInfo`, compteurs replay et distinction explicite `replay_coverage_unproven`. Config projette déjà les settings/overrides reconnect. Gap observé : ```text Yellowstone max_retries possède une borne KSP explicite = 100 WebSocket max_retries ne possède pas encore de borne maximale KSP équivalente ``` Décision : durcir la pile existante en `pre.008`, sans nouveau reconnect Worker. Verdict : ```text RECONNECT OWNERSHIP ALREADY CORRECT BOUNDS/PARITY HARDENING REQUIRED COVERAGE SEMANTICS UNCHANGED ``` ## 15. Réaudit upstream Faits confirmés : ```text PostgreSQL 17 row locks et deadlock detection documentés consistent lock order recommandé serialization_failure SQLSTATE 40001 retryable deadlock_detected SQLSTATE 40P01 retryable lorsque pertinent tokio-postgres DbError::code() -> SqlState structuré deadpool-postgres PoolError distingue Timeout/Backend/Closed/config-hook classes Solana PubSub subscription semantics documentées signatureSubscribe one-shot auto-cancel serveur aucune preuve générale de replay/coverage après reconnect Yellowstone upstream SubscribeRequest.from_slot existe replay availability est une notion distincte Tokio cancellation safety doit être raisonnée autour de select!/queues fair ``` Politique KSP correspondante documentée dans le plan 039. ## 16. Compatibilité Job Backfill Le Backfill actuel passe par les contrats Store communs et ne dépend ni du Worker ni du backend PostgreSQL direct. Décision : ```text nouveaux traits séparés pas d'ajout obligatoire à RawTransactionWrite pas de retry live Worker dans Job QuarantinedConflict reste compatible pas de scope multi-route dans 0.3.17 ``` Verdict : ```text BACKFILL BOUNDARY PRESERVED BY DESIGN REGRESSION TESTS REQUIRED pre.006/pre.009 ``` ## 17. Migration sizing Migration prévue : ```text V004 additive participants append-only history resolved projection fields variant archive support if needed by final retention design ``` La migration doit conserver strictement les resources/checksums V000-V003. Le bootstrap V003 -> V004 ne peut créer que des faits prouvables depuis l'état courant ; aucun historique antérieur détaillé n'est reconstruit artificiellement. ## 18. Prévision de prereleases validée par le gate ```text pre.001 audit + architecture + sizing + plan pre.002 Store API variants/conflicts/history/actions + StoreErrorClass pre.003 PostgreSQL V004 additive + bootstrap legacy pre.004 PostgreSQL lifecycle/actions/CAS/races/history pre.005 variant retention/archive/purge guards/restore pre.006 Store facade + physical error classification + Backfill compatibility pre.007 Worker Store retry/backpressure/Blocked/cancellation pre.008 Transport/Config reconnect bounds/hardening pre.009 technical/live final gate pre.010 documentation reconciliation pre.011 publication preparation rel.001 stable mechanical publication ``` Cette prévision peut recevoir des `fix.*` ou subdivisions si une tranche ne peut pas rester petite et validable. ## 19. Matrice de preuve à remplir Etat au gate `pre.001` : ```text base archive internal consistency PASS rules static audit PASS Markdown audit baseline PASS Cargo post-bump in assembly environment NOT RUN (toolchain absent) Store API contract model DEFINED conflict lifecycle model DEFINED revision/CAS model DEFINED race matrix DEFINED retention/pin model DEFINED Store Transient/Terminal policy DEFINED Worker retry/backpressure/Blocked policy DEFINED Transport reconnect ownership/bounds DEFINED Backfill compatibility strategy DEFINED V004 migration strategy DEFINED PostgreSQL live 0.3.17 PENDING pre.009 Store outage/recovery proof PENDING pre.009 reconnect live/deterministic proof PENDING pre.009 workspace final technical gate PENDING pre.009 documentation reconciliation PENDING pre.010 publication preparation PENDING pre.011 ``` ## 20. Hors périmètre validé ```text Store Desk Tauri -> 0.3.18 Backfill multi-route -> 0.3.19 Backfill Desk multi-route -> 0.3.20 RAW -> STRUCTURAL STRUCTURAL persistence DECODED / DOMAIN provider voting/priority heuristic JSON merge unbounded Store retry hidden backend retry loop Worker-owned network stack Worker <-> Backfill dependency network rollback of old variant free-form operator identity without auth contract ``` ## 21. Gate `pre.001` Le gate conceptuel est fermé : ```text archive/rules audit CLOSED Store API proposal CLOSED conflict lifecycle CLOSED revision/races CLOSED retention/pins CLOSED Transient/Terminal CLOSED Worker retry/Blocked CLOSED Transport reconnect ownership CLOSED Backfill compatibility CLOSED migration strategy CLOSED live proof plan CLOSED prerelease sizing CLOSED out-of-scope CLOSED ``` Aucune implémentation Rust/SQL lourde n'est autorisée dans `pre.001`. La tranche suivante est : ```text 0.3.17-pre.002 — Store API variants/conflicts/history/actions + StoreErrorClass ``` ## 22. Gate opérateur après application de `pre.001` Comme seuls `Cargo.toml` et des Markdown sont modifiés/ajoutés : ```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 ``` Aucun test live n'est requis par cette tranche documentaire de planning. ## 23. Gate opérateur `0.3.17-pre.001` reçu avant `pre.002` Le 24 septembre 2026, l'opérateur a exécuté sur son checkout après application de `0.3.17-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 fournis : ```text cargo fmt --all -- --check aucun diagnostic 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), 965 file(s)) cargo check --workspace PASS, 0.3.17-pre.1, 6.11 s cargo clippy --workspace --all-targets --all-features -- -D warnings PASS, 0.3.17-pre.1, 25.28 s ``` Ce gate ferme `pre.001` et autorise `0.3.17-pre.002`. Aucun test runtime/live supplémentaire n'était requis par le delta `pre.001`. ## 24. Assemblage `0.3.17-pre.002` La tranche `pre.002` matérialise uniquement les contrats backend-neutral prévus au sizing : ```text variant inspection conflict inspection + participants append-only history DTO/query double-revision action request stale/idempotent outcomes StoreErrorClass + StoreErrorClassifier ``` Aucune migration V004, implémentation PostgreSQL, façade Store, politique Worker retry ou reconnexion Transport n'est introduite. Audits locaux après assemblage : ```text 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), 966 file(s)) ``` Limitation inchangée de l'environnement d'assemblage : ```text cargo/rustc/rustfmt unavailable cargo fmt/check/clippy/test pre.002 NOT RUN ici ``` Le gate opérateur requis pour fermer `pre.002` est celui de `deltas/0.3.17/pre.002.md`, incluant `cargo test -p ksp-store-api --all-targets --all-features`. ## 25. Gate opérateur `0.3.17-pre.002` et correctif `fix.001` Le 24 septembre 2026, l'opérateur a exécuté le gate complet demandé pour `pre.002`. Résultats avant le test ciblé : ```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), 966 file(s)) cargo check --workspace PASS, 0.3.17-pre.2, 5.97 s cargo clippy --workspace --all-targets --all-features -- -D warnings PASS, 0.3.17-pre.2, 8.83 s ``` `cargo test -p ksp-store-api --all-targets --all-features` a ensuite compilé et exécuté correctement les 35 tests unitaires, mais le gate a échoué dans `tests/dependency_boundary.rs` : ```text unit tests PASS 35/35 dependency_boundary FAIL 1/2 pre_006_source_boundary_keeps_models_and_capabilities_backend_free ``` La cause est un faux positif du canari historique. Il interdisait la sous-chaîne : ```text trait Store ``` Le nouveau contrat backend-neutral légitime : ```text trait StoreErrorClassifier ``` contient cette sous-chaîne sans déclarer un trait générique `Store`. Le correctif `pre.002-fix.001` resserre donc uniquement le canari afin d'interdire un identifiant de trait exactement nommé `Store` (`Store `, `Store:`, `Store<` ou séparation de ligne), tout en conservant l'interdiction de `StoreBackend`, `PostgresStore`, `MySqlStore` et `Arc