use super::SourceProvenance;
const MATCH: &str = "source and target embedding provenance match";
const MODEL_DIFFERS: &str = "target model differs";
const DIMENSION_DIFFERS: &str = "target dimension differs";
const PROVENANCE_UNKNOWN: &str = "source provenance is unknown";
const PROVENANCE_CONTRADICTS: &str = "source provenance contradicts the stored dimension";
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Compatibility {
Match,
ModelDiffers,
DimensionDiffers,
ProvenanceUnknown,
ProvenanceContradictsDimension,
}
impl Compatibility {
#[must_use]
pub fn reason(self) -> &'static str {
match self {
Self::Match => MATCH,
Self::ModelDiffers => MODEL_DIFFERS,
Self::DimensionDiffers => DIMENSION_DIFFERS,
Self::ProvenanceUnknown => PROVENANCE_UNKNOWN,
Self::ProvenanceContradictsDimension => PROVENANCE_CONTRADICTS,
}
}
#[must_use]
pub fn permits_reuse(self) -> bool {
matches!(self, Self::Match)
}
#[must_use]
pub fn all() -> Vec<Self> {
vec![
Self::Match,
Self::ModelDiffers,
Self::DimensionDiffers,
Self::ProvenanceUnknown,
Self::ProvenanceContradictsDimension,
]
}
}
#[must_use]
pub fn assess(
provenance: &SourceProvenance,
source_dimension: Option<usize>,
target_model: &str,
target_dimension: usize,
) -> Compatibility {
let SourceProvenance::Known { model, dimension } = provenance else {
return Compatibility::ProvenanceUnknown;
};
if source_dimension != Some(*dimension) {
return Compatibility::ProvenanceContradictsDimension;
}
if model != target_model {
return Compatibility::ModelDiffers;
}
if *dimension != target_dimension {
return Compatibility::DimensionDiffers;
}
Compatibility::Match
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Strategy {
Auto,
Reuse,
Reembed,
}
impl Strategy {
pub fn parse(value: &str) -> Result<Self, String> {
match value {
"auto" => Ok(Self::Auto),
"reuse" => Ok(Self::Reuse),
"reembed" => Ok(Self::Reembed),
"force-reuse" | "force_reuse" => Err(format!(
"--strategy {value} does not exist, and not by oversight: reusing vectors against \
an unproven provenance is an official route to a store whose vectors and whose \
recorded model disagree, which recall would answer from without ever failing. \
Use --strategy reembed to rebuild from the stored text"
)),
other => Err(format!(
"--strategy expects auto, reuse or reembed, got {other:?}"
)),
}
}
#[must_use]
pub fn all() -> Vec<Self> {
vec![Self::Auto, Self::Reuse, Self::Reembed]
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(tag = "resolution", rename_all = "snake_case")]
pub enum Resolution {
Reuse,
Reembed {
because: Compatibility,
},
Refuse {
because: Compatibility,
requested: Strategy,
},
}
impl Resolution {
#[must_use]
pub fn diagnostic(self) -> String {
match self {
Self::Reuse => format!("REUSE: {MATCH}"),
Self::Reembed { because } => format!("REEMBED: {}", because.reason()),
Self::Refuse {
because,
requested: Strategy::Reuse,
} => format!("REFUSE: reuse was requested, but {}", because.reason()),
Self::Refuse { because, .. } => format!("REFUSE: {}", because.reason()),
}
}
#[must_use]
pub fn guidance(self) -> Option<&'static str> {
match self {
Self::Reuse | Self::Reembed { .. } => None,
Self::Refuse {
requested: Strategy::Reuse,
..
} => Some(
"reuse is legitimate only when the source records the target model at the target \
width. Re-run with --strategy auto to let the source's own record decide, or \
--strategy reembed to rebuild every vector from the stored text.",
),
Self::Refuse { .. } => Some(
"the record and the vectors cannot both be right, so neither is read as truth. \
Re-run with --strategy reembed to rebuild from the stored text on the measured \
width — it never reads a source vector, so the contradiction cannot propagate.",
),
}
}
#[must_use]
pub fn runs(self) -> bool {
!matches!(self, Self::Refuse { .. })
}
}
#[must_use]
pub fn resolve(requested: Strategy, compatibility: Compatibility) -> Resolution {
if requested != Strategy::Reembed && compatibility.permits_reuse() {
return Resolution::Reuse;
}
let unearned_reuse = requested == Strategy::Reuse;
let unreadable_store = requested == Strategy::Auto
&& compatibility == Compatibility::ProvenanceContradictsDimension;
if unearned_reuse || unreadable_store {
return Resolution::Refuse {
because: compatibility,
requested,
};
}
Resolution::Reembed {
because: compatibility,
}
}