0.3.16-pre.007

This commit is contained in:
2026-09-22 06:22:40 +02:00
parent a97837b832
commit d768737629
22 changed files with 842 additions and 276 deletions

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-job-backfill-lib/src/persistence.rs
// version: 3
// version: 4
/// Canonical entity disposition produced by one Backfill Store persistence attempt.
#[non_exhaustive]
@@ -13,7 +13,7 @@ pub enum BackfillEntityPersistence {
SkippedPurged,
/// `getTransaction` returned JSON `null`, so no canonical Store write was attempted.
Missing,
/// Store reported divergent canonical content for the same network-scoped transaction identity.
/// Store durably quarantined divergent/incomparable content, or a legacy backend reported a conflict error.
Conflict,
}
@@ -25,7 +25,7 @@ pub enum BackfillObservationPersistence {
Inserted,
/// The same deterministic acquisition observation was already durable.
AlreadyPresent,
/// Store intentionally recorded no observation because normal persistence skipped a purged entity or detected a conflict.
/// Store intentionally recorded no observation because normal persistence skipped a purged entity or a legacy conflict error predated durable quarantine.
NotRecorded,
/// No observation existed because hydration returned `Missing` before persistence.
NotApplicable,
@@ -75,9 +75,9 @@ impl crate::BackfillPersistenceOutcome {
///
/// Available acquisitions use the existing atomic transaction-plus-observation Store contract in
/// `Normal` mode. A durable purge is therefore respected and never rehydrated implicitly.
/// `Missing` performs no Store write. Stable Store content conflicts are projected explicitly as
/// [`BackfillEntityPersistence::Conflict`] rather than being silently treated as idempotent skips.
/// Other Store failures remain errors.
/// `Missing` performs no Store write. Durable quarantined conflicts are projected explicitly as
/// [`BackfillEntityPersistence::Conflict`] while preserving the actual observation disposition;
/// legacy Store conflict errors remain compatible and other Store failures remain errors.
pub async fn persist_backfill_hydration(
store: &ksp_store_lib::Store,
hydration: crate::BackfillHydrationOutcome,
@@ -170,6 +170,17 @@ fn map_store_outcome(
) -> ksp_core_lib::Result<crate::BackfillPersistenceOutcome> {
let entity = outcome.entity();
let observation = outcome.observation();
if outcome.transaction_variant() == std::option::Option::Some(ksp_store_lib::RawTransactionVariantWriteOutcome::QuarantinedConflict) {
let projected_observation = match observation {
ksp_store_lib::RawObservationWriteOutcome::Inserted => crate::BackfillObservationPersistence::Inserted,
ksp_store_lib::RawObservationWriteOutcome::AlreadyPresent => crate::BackfillObservationPersistence::AlreadyPresent,
_ => return std::result::Result::Err(persistence_error("store.conflict_observation")),
};
if entity != ksp_store_lib::RawEntityWriteOutcome::AlreadyPresent {
return std::result::Result::Err(persistence_error("store.conflict_entity"));
}
return std::result::Result::Ok(crate::BackfillPersistenceOutcome::new(reference, crate::BackfillEntityPersistence::Conflict, projected_observation));
}
if entity == ksp_store_lib::RawEntityWriteOutcome::Inserted && observation == ksp_store_lib::RawObservationWriteOutcome::Inserted {
return std::result::Result::Ok(crate::BackfillPersistenceOutcome::new(
reference,