pub struct Affinity {Show 18 fields
pub id: Uuid,
pub session_id: Uuid,
pub user_id: Uuid,
pub instance_id: Uuid,
pub warmth: f64,
pub trust: f64,
pub intrigue: f64,
pub intimacy: f64,
pub patience: f64,
pub tension: f64,
pub warmth_grade: i16,
pub patience_grade: i16,
pub ghost_streak: i32,
pub last_ghost_at: Option<DateTime<Utc>>,
pub total_ghosts: i32,
pub relationship_label: Option<RelationshipLabel>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}Fields§
§id: Uuid§session_id: Uuid§user_id: Uuid§instance_id: Uuid§warmth: f64§trust: f64§intrigue: f64§intimacy: f64§patience: f64§tension: f64§warmth_grade: i16Judge’s last absolute warmth level (1..=3). Authoritative; warmth is
a materialized cache of endpoint_value over it.
patience_grade: i16Judge’s last absolute patience level (1..=3).
ghost_streak: i32§last_ghost_at: Option<DateTime<Utc>>§total_ghosts: i32§relationship_label: Option<RelationshipLabel>§created_at: DateTime<Utc>§updated_at: DateTime<Utc>Implementations§
Source§impl Affinity
impl Affinity
Sourcepub fn apply_deltas(&mut self, d: &AffinityDeltas)
pub fn apply_deltas(&mut self, d: &AffinityDeltas)
Apply committed deltas directly, clamping each axis to its range.
Damping lives in grade_turn’s tier decay, so a committed delta means
exactly what it says.
Sourcepub fn apply_time_decay(&mut self)
pub fn apply_time_decay(&mut self)
Per-day drift on the line axes only (intrigue cools, tension softens).
The old patience up-drift is retired: absence handling for the two
endpoints lives in refresh_endpoints’ multiplicative decay, which
cools rather than heals — an old friend’s resilience comes from
B(bond), not from a drift patch.
Sourcepub fn refresh_endpoints(&mut self, t: &AffinityTuning)
pub fn refresh_endpoints(&mut self, t: &AffinityTuning)
Recompute the two derived endpoints from the authoritative facts
(judge levels + line scores + time since last update). Runs wherever
apply_time_decay runs: the row-locked persist and the in-memory
read paths. Line scores no longer contain warmth, so there is no
circularity.
Sourcepub fn legacy_relationship_label(&self) -> RelationshipLabel
pub fn legacy_relationship_label(&self) -> RelationshipLabel
Legacy 5-name relationship label (back-compat), derived purely from the
two line scores — replaces the old multi-axis infer_label heuristic.
New consumers should read bond_label/chemistry_label. frenemy is
retired from emission (kept in the enum for parse compat).
Source§impl Affinity
impl Affinity
Sourcepub fn bond_score(&self) -> f64
pub fn bond_score(&self) -> f64
0..1 friendship composite. Mirrors the bond generated column in
migration 0048.
Sourcepub fn chemistry_score(&self) -> f64
pub fn chemistry_score(&self) -> f64
0..1 romance composite. Mirrors the chemistry generated column in
migration 0048.
Sourcepub fn bond_label(&self) -> BondLabel
pub fn bond_label(&self) -> BondLabel
Friendship-line tier label.
Sourcepub fn chemistry_label(&self) -> ChemistryLabel
pub fn chemistry_label(&self) -> ChemistryLabel
Romance-line tier label.
Sourcepub fn intimacy_rung(&self) -> u8
pub fn intimacy_rung(&self) -> u8
Coarse 1..=3 intimacy rung for the PDE image gate, taken over whichever
line is further along. Rung 1 = both lines still tier 1; rung 3 = at or
above INTIMACY_RUNG3_LO; rung 2 = everything between. max rather than
a sum so a purely romantic track and a purely companionable one can each
unlock on their own.
The bottom cut folds TIER1_HI and so cannot drift away from the
Acquaintance / Spark labels the rest of the system shows. The top cut
is deliberately its own constant, set below the tier-5 apex — see
INTIMACY_RUNG3_LO.
Sourcepub fn patience_band(&self) -> PatienceBand
pub fn patience_band(&self) -> PatienceBand
Patience band. Reads the raw axis, not a composite — patience is
rule-owned and stays outside both folds.