10 KiB
Delta 0.3.16-pre.007 — conflit RAW durable minimal et Worker non terminal
Base requise
0.3.16-pre.006-fix.001 appliqué
workspace.package.version = 0.3.16-pre.6.fix.1
Le gate opérateur fourni pour cette base est entièrement propre : audits Rust/export/KSP/Markdown, cargo check --workspace, Clippy -D warnings, les 29 tests unitaires ksp-store-api, les 87 tests unitaires ksp-store-postgres-lib et les suites d'intégration ciblées passent. Les trois preuves PostgreSQL live restent opt-in et sont ignorées par le gate déterministe normal.
Version
Cette tranche modifie les contrats Store, le runtime PostgreSQL, le Worker et la projection Backfill :
workspace.package.version = 0.3.16-pre.7
Objectif
Fermer le comportement durable minimal prévu par le plan 038 pour Conflict et Incomparable :
incoming divergent/incomparable
-> variante entrante conservée
-> canonique courant inchangé
-> conflict case durable Open
-> observation liée à la variante entrante
-> COMMIT atomique
-> outcome QuarantinedConflict
-> Worker continue en Running
-> health Degraded
Cette tranche n'introduit ni résolution manuelle/automatique du conflict case, ni historique append-only complet, ni politique générale de retry Store. Ces responsabilités restent différées selon le plan 038.
Contrat Store variant-aware
RawAcquisitionWriteOutcome conserve son constructeur historique new(entity, observation) pour les backends et consommateurs existants. Il expose désormais en plus une classification transactionnelle optionnelle :
transaction_variant: Option<RawTransactionVariantWriteOutcome>
Le constructeur with_transaction_variant(...) permet à un backend transaction-aware de retourner explicitement le verdict de convergence. PostgreSQL renseigne cette classification pour toutes les acquisitions RAW Transaction :
InsertedCanonical
ObservedExact
ObservedCompatibleLessComplete
PromotedCompatibleMoreComplete
QuarantinedConflict
Rehydrated
SkippedPurged
QuarantinedConflict reste un succès de durabilité Store et non une erreur terminale.
ksp-store-lib réexporte RawTransactionVariantWriteOutcome afin que les consumers restent dépendants de la façade et non de ksp-store-api directement.
Conflict case PostgreSQL
Aucune migration V003 n'est modifiée : la table ksp_raw_transaction_conflicts et ses contraintes appartiennent déjà au schéma figé livré en amont.
Lorsqu'un comparateur partagé retourne Conflict ou Incomparable, persist_raw_transaction_acquisition(...) :
verrouille l'identité transactionnelle existante
persiste/reuse la variante entrante exacte
verrouille le conflict case existant FOR UPDATE
insère un case Open revision 1 s'il n'existe pas
ou valide/met à jour le case existant avec garde de revision
persiste l'observation
lie observation -> variante entrante
COMMIT
émet le journal opérationnel minimal après commit
retourne QuarantinedConflict
Le canonique courant et son selector ne sont pas modifiés par ce chemin.
Une réobservation strictement identique d'un même case déjà Open est idempotente : elle ne fabrique pas une nouvelle révision. Une modification réelle du couple canonique/entrant, de la relation ou du reason code incrémente la révision par checked_add; l'épuisement est fail-closed.
Le conflit reste dans la même transaction que la variante, l'observation et le lien observation-variante. Tout échec avant COMMIT laisse PostgreSQL rollbacker l'ensemble.
Arbitrage Worker
La convergence run-local ne conserve plus de représentation locale du contenu canonique et ne peut plus rejeter une divergence avant Store.
La cache bornée (network, signature) reste uniquement un verrou de sérialisation run-local. Chaque acquisition, y compris une réobservation ou une forme divergente, repasse par RawTransactionWrite::persist_raw_transaction_acquisition(...). Le Store reste donc l'unique autorité de comparaison et de convergence durable.
Le Worker valide la cohérence entre l'outcome entity/observation et l'outcome transactionnel. Pour :
QuarantinedConflict
il considère la persistence comme réussie, incrémente persisted_total et content_conflict_total, reste Running et projette une health Degraded.
Un backend legacy qui retourne encore ERROR_CODE_RAW_CONFLICT reste converti vers l'erreur Worker terminale historique. Ce chemin est conservé uniquement pour compatibilité ; PostgreSQL pre.007 n'utilise plus cette erreur pour un conflit actif variant-aware.
Projection Backfill
Le Job Backfill reconnaît également QuarantinedConflict comme résultat Store durable. Il projette l'entité vers BackfillEntityPersistence::Conflict tout en conservant l'outcome réel de l'observation (Inserted ou AlreadyPresent).
L'ancien mapping d'un ERROR_CODE_RAW_CONFLICT vers Conflict + NotRecorded est conservé pour un backend legacy.
Le delta ne change pas la politique de progression/frontier Backfill ; le hardening cross-layer final appartient à pre.008.
Documentation Worker
Le README et le USAGE du Worker ne décrivent plus la divergence comme nécessairement terminale ni la cache run-local comme autorité de contenu. Ils documentent le passage systématique par Store, la quarantaine durable et la health Degraded.
Tests et canaris
Les tests ajoutés/révisés verrouillent notamment :
- l'exposition publique de la classification transactionnelle dans
RawAcquisitionWriteOutcome; - le réexport façade de
RawTransactionVariantWriteOutcome; - les SQL conflict
INSERT,FOR UPDATEet update compare-and-set surrevision; - l'ordre transactionnel variante -> conflict case -> observation -> commit -> journal ;
- la conservation du canonique lors d'un conflit ;
- la suppression de l'arbitrage run-local par contenu dans le Worker ;
- le passage de chaque acquisition par Store malgré la cache de sérialisation ;
QuarantinedConflictcomme succès Worker explicite ;Running + Degraded,persisted_total + 1,content_conflict_total + 1et absence destore_failure_totalpour la quarantaine ;- la compatibilité terminale du legacy
ERROR_CODE_RAW_CONFLICT; - la projection Backfill explicite du conflit durable avec conservation de l'observation.
Fichiers modifiés
Cargo.toml
crates/ksp-job-backfill-lib/src/persistence.rs
crates/ksp-job-backfill-lib/unit_tests/persistence.rs
crates/ksp-store-api/src/capability/raw_transaction.rs
crates/ksp-store-api/src/model/raw_outcome.rs
crates/ksp-store-api/tests/public_api.rs
crates/ksp-store-lib/src/lib.rs
crates/ksp-store-lib/tests/hardening_completeness.rs
crates/ksp-store-postgres-lib/src/raw_transaction.rs
crates/ksp-store-postgres-lib/tests/hardening_completeness.rs
crates/ksp-store-postgres-lib/tests/v003_variant_persistence.rs
crates/ksp-store-postgres-lib/unit_tests/raw_transaction.rs
crates/ksp-worker-raw-transaction-ingest-lib/README.md
crates/ksp-worker-raw-transaction-ingest-lib/USAGE.md
crates/ksp-worker-raw-transaction-ingest-lib/src/persistence.rs
crates/ksp-worker-raw-transaction-ingest-lib/src/snapshot.rs
crates/ksp-worker-raw-transaction-ingest-lib/tests/cross_layer_completeness.rs
crates/ksp-worker-raw-transaction-ingest-lib/tests/dependency_boundary.rs
crates/ksp-worker-raw-transaction-ingest-lib/tests/hardening.rs
crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/persistence.rs
crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/runtime.rs
Fichier ajouté
deltas/0.3.16/pre.007.md
Fichiers supprimés
aucun
Validation exécutée lors de la génération
Sur le checkout complet final :
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
Le toolchain Rust n'est pas installé dans l'environnement de génération ; cargo fmt, cargo check, Clippy et les tests Cargo ne sont donc pas déclarés exécutés ici. La base pre.006-fix.001 dispose en revanche du gate Cargo opérateur entièrement vert fourni avant l'ouverture de cette tranche.
Le ZIP minimal doit être rejoué sur une copie fraîche de pre.006-fix.001, avec réexécution des audits Python, vérification byte-exacte du payload et confirmation que toutes les ressources de migration PostgreSQL restent inchangées.
Validation opérateur demandée
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
Les preuves PostgreSQL live restent opt-in et ne sont pas requises dans ce delta fonctionnel minimal ; pre.008 porte le hardening ciblé et les régressions finales prévues par le plan.
Décisions prises
ConflictetIncomparableactifs deviennent des résultats durables non terminaux ;- le canonique courant n'est jamais remplacé par un conflit ;
- la variante entrante et son observation sont conservées dans la même transaction que le conflict case ;
- le conflict case minimal réutilise le schéma V003 existant sans migration ;
- la cache Worker ne possède plus d'autorité de contenu supérieure au Store ;
QuarantinedConflictdégrade la health mais ne fault pas le Worker ;- les backends legacy peuvent encore omettre l'outcome transactionnel et retourner l'ancien conflit terminal ;
- la résolution des conflits, l'historique append-only et le retry Store restent hors scope.
Questions ouvertes
Aucune question bloquante pour cette tranche.
Suite
Après gate propre : 0.3.16-pre.008 — hardening ciblé de la vertical slice : concurrence, rollback transactionnel, régressions Store/Backfill/Worker, gates workspace, validation documentaire et préparation de 0.3.16-rel.001.