Files
khadhroony-solana-project/deltas/0.3.17/pre.002.md
2026-09-24 10:55:34 +02:00

9.0 KiB

Delta 0.3.17-pre.002 — contrats Store API conflict lifecycle et classification d'erreur

Base requise

0.3.17-pre.001 appliquée
workspace.package.version = 0.3.17-pre.1

Le gate opérateur reçu le 24 septembre 2026 est propre :

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), 965 file(s))
cargo check --workspace                            PASS, 6.11 s
cargo clippy --workspace --all-targets --all-features -- -D warnings
                                                     PASS, 25.28 s

Objet

Figer la surface backend-neutral requise par le cycle de vie complet des variantes/conflits avant toute migration PostgreSQL V004.

Cette tranche reste strictement dans ksp-store-api et ajoute :

inspection des variantes
inspection des conflict cases
participant ledger DTO
historique append-only DTO/query
actions compare-and-set à double revision
outcomes stale/idempotent explicites
StoreErrorClass Transient/Terminal
StoreErrorClassifier backend-neutral

Elle ne modifie encore :

aucune migration SQL
aucun backend PostgreSQL
aucun ksp-store-lib
aucun Worker
aucun Transport/Config
aucun Job Backfill
aucune application Desk

Version workspace

Cargo.toml :

header version : 652 -> 653
workspace      : 0.3.17-pre.1 -> 0.3.17-pre.2

Fichiers ajoutés

crates/ksp-store-api/src/capability/raw_conflict.rs
crates/ksp-store-api/src/model/raw_conflict.rs
crates/ksp-store-api/unit_tests/model/raw_conflict.rs
deltas/0.3.17/pre.002.md

Fichiers modifiés

Cargo.toml
crates/ksp-store-api/src/capability.rs
crates/ksp-store-api/src/error.rs
crates/ksp-store-api/src/lib.rs
crates/ksp-store-api/src/model.rs
crates/ksp-store-api/tests/dependency_boundary.rs
crates/ksp-store-api/tests/external_backend.rs
crates/ksp-store-api/tests/public_api.rs
crates/ksp-store-api/tests/release_completeness.rs
crates/ksp-store-api/tests/security_hardening.rs
docs/validation/034-V0_3_17_RAW_OPERATIONAL_RESILIENCE.md

Contrats variantes

La lecture opérateur des variantes est portée par :

RawTransactionVariantInspectionQuery
RawTransactionVariantSummary
RawTransactionVariantDetail
RawTransactionVariantInspectionRead

La query est random-access bornée via RawInspectionPageRequest, exige un network et accepte seulement un filtre transaction exact cohérent avec ce network.

Le summary reste payload-free et expose uniquement les métadonnées nécessaires :

variant reference
origin
slot / block_time
format id/version
retention state
payload size si disponible
is_current_canonical
observation_count
created_at

RawTransactionVariantDetail peut porter la transaction RAW complète uniquement dans la lecture explicite d'un variant. Le constructeur vérifie transaction identity, slot, block time, format et taille déclarée ; un variant Purged ne peut pas prétendre contenir encore le payload.

Contrats conflict case

Identité :

RawTransactionConflictReference
  -> RawTransactionReference

Inspection :

RawTransactionConflictInspectionQuery
RawTransactionConflictSummary
RawTransactionConflictParticipantSummary
RawTransactionConflictDetail
RawTransactionConflictInspectionRead

La projection courante conserve explicitement :

status Open/Resolved
conflict revision > 0
canonical variant
canonical selector revision > 0
latest incoming variant
latest Conflict/Incomparable relation + reason
resolved canonical variant si Resolved
latest resolution action si Resolved
participant_count >= 2
created_at / updated_at

Les références canonical/incoming/resolved doivent appartenir à la même transaction que le conflict case.

Le detail valide que le participant ledger :

contient exactement participant_count entrées
n'a aucun variant_id dupliqué
reste dans le même scope transaction
n'annonce aucun first_seen_revision > current conflict revision
contient canonical/latest incoming/resolved target requis

Historique append-only

Types ajoutés :

RawTransactionConflictEventKind
RawTransactionConflictEventOrigin
RawTransactionConflictEventSummary
RawTransactionConflictHistoryQuery
RawTransactionConflictHistoryRead

Event kinds figés :

Opened
ParticipantAdded
ResolvedKeepCanonical
ResolvedPromoteVariant
ResolvedRestoreVariant
Reopened

Origins sûres :

Automatic
Operator

Aucun acteur libre, texte backend, SQL ou payload RAW n'entre dans le DTO d'historique.

Une transition de résolution exige exactement le RawTransactionConflictResolutionAction correspondant. Opened et ParticipantAdded exigent une comparaison durable Conflict ou Incomparable.

Actions compare-and-set

Types :

RawTransactionConflictResolutionAction
RawTransactionConflictResolution
RawTransactionConflictAction
RawTransactionConflictActionRequest
RawTransactionConflictActionOutcome
RawTransactionConflictActionWrite

Actions disponibles :

KeepCurrentCanonical
PromoteVariant(target)
RestoreVariant(target)
Resolve(explicit canonical resolution)
Reopen

Chaque request transporte obligatoirement :

conflict reference
expected_conflict_revision > 0
expected_canonical_revision > 0
action

Tout target variant doit appartenir à la transaction du conflict case.

Outcomes backend-neutral :

Applied
AlreadyAtTarget
StaleRevision
ConflictNotOpen
ConflictNotResolved
VariantNotParticipant
VariantPayloadUnavailable

AlreadyAtTarget et StaleRevision restent volontairement distincts : une répétition idempotente n'est pas une perte de compare-and-set concurrente.

Classification Store error

ksp-store-api expose désormais :

StoreErrorClass::Transient
StoreErrorClass::Terminal
StoreErrorClassifier

Le classifier reçoit une ksp_core_lib::Error déjà projetée/redacted. Le Worker futur consommera ce contrat au lieu de comparer des codes PostgreSQL ou des chaînes libres.

Cette tranche ne classe encore aucun SQLSTATE concret : le raffinement physique reste réservé à pre.006. La politique fail-closed définie par le plan reste inchangée : tout code non explicitement reconnu par l'implémentation future sera Terminal.

Frontières préservées

Le manifest ksp-store-api reste inchangé :

runtime dependency exacte = ksp-core-lib uniquement

Aucun nouveau crate externe n'est introduit.

Tous les nouveaux items publics sont réexportés depuis la racine ksp-store-api; aucun pub mod n'est ajouté. Les enums évolutifs sont #[non_exhaustive].

Les capabilities restent object-safe et implémentables par un backend externe sans dépendre de ksp-store-lib ou PostgreSQL.

Tests/canaris ajoutés ou étendus

La tranche couvre statiquement et par tests Rust :

network coherence des queries variant/conflict
double revision strictement positive
scope transaction des targets d'action
status Open/Resolved et projection resolution cohérente
relation conflict/incomparable requise pour le conflict current
participant ledger complet, unique et revision-safe
history event/action consistency
outcomes Applied/AlreadyAtTarget/StaleRevision distincts
codes event/origin/resolution stables
variant detail payload debug redacted
object safety des quatre nouvelles capabilities + classifier
inventaire exact crate-root/module/capability
frontière dépendances backend-neutral
#[non_exhaustive] des nouveaux enums

Validation locale de l'assemblage

L'environnement d'assemblage ne fournit toujours pas cargo, rustc ou rustfmt. Aucun PASS Cargo n'est inventé pour pre.002.

Audits réellement exécutés après les changements Rust :

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))

Le gate Cargo utilisateur reste autoritaire pour confirmer compilation, rustfmt, Clippy et tests.

Gate requis après application

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

Ne pas lancer de test PostgreSQL live pour cette tranche : aucune migration ni implémentation backend n'est encore modifiée.

Prochaine tranche

Après gate propre :

0.3.17-pre.003

Objet prévu : migration PostgreSQL V004 additive pour participants, historique append-only, projection de résolution et bootstrap legacy, avec canaris garantissant l'immuabilité byte/checksum de V000/V001/V002/V003.