Skip to main content

Module affinity

Module affinity 

Source

Structs§

Affinity
AffinityDeltas
AffinityTuning
Tuning knobs for the 4.0 pipeline, env-driven server-side.
AxisGrades
Signed judge grades, one per line axis, −4..=4 (out-of-range input is clamped). 0 = nothing happened, the overwhelmingly common verdict. warmth and patience are absent by construction: they are absolute levels on the derived channel (EndpointLevelReads), not graded deltas.
CrossPenaltyAssessed
Per-axis cross-line penalty assessed in one turn (always ≥ 0).
EndpointLevelReads
The judge’s absolute endpoint levels for one turn. None = the judge omitted the field or the eval was skipped → hold the stored level.
GradeTurnOutcome
One turn through the 4.0 pipeline. raw = grade conversion + rule deltas, pre-decay — what the event row records as deltas. committed = what actually applies to the axes this turn (zero while the gate holds). pending = the gate’s new balance. The warmth/patience fields of raw and committed are always 0.0: the endpoints left the graded pipeline (see refresh_endpoints).
LabelTransition
One line’s tier transition this turn, as serialised keys.
PendingDeltas
Per-axis balance the threshold gate is still holding back. Persisted as JSONB on the affinity row; absent column reads as all-zero. A stale "warmth" key from pre-4.0 rows is ignored by serde and drains naturally.
TurnLabelChanges
Per-turn tier transition across the two lines. Serde skips None fields, so a JSON object only carries the line(s) that actually moved.

Enums§

BondLabel
Friendship-line tier (pure function of bond_score). Serialised snake_case key is the frontend’s lookup; Chinese display lives in the frontend.
ChemistryLabel
Romance-line tier (pure function of chemistry_score).
PatienceBand
Patience band for the PDE judge. Three bands, not five: the judge prompt prescribes one interaction register per band (how curt the tone runs, whether irritation shows), and the engine states which band applies.
RelationshipLabel

Constants§

ENDPOINT_BOOST_MAX
Boost at a counterpart score of 1.0. With base(3) = 2/3, a full judge level times a full counterpart line lands exactly at 1.0 — a structural commitment, so a code constant rather than a knob (the pivot below is TIER2_HI for the same reason: the boost turns positive the moment the counterpart line enters tier 3).

Functions§

diff_labels
Tier transition over a delta-only span (before = post-decay/pre-delta, after = post-delta). None when neither line crossed a tier.
endpoint_boost
B(x) = 1 + λ·(x − TIER2_HI), λ = (B_MAX − 1)/(1 − TIER2_HI) = 10/13. Below the pivot the endpoint is damped under its base; above it, boosted.
endpoint_time_decay
Multiplicative absence decay: 1 − rate·days, floored. Linear like the line-axis drift; the floor keeps long absence from zeroing a relationship.
endpoint_value
One endpoint’s real value. The φ·x floor only ever acts on level 1 (φ·x ≤ φ < 1/3·B(0) for φ ≤ 0.2): a cold verdict decays to a relationship-scaled ember instead of an absolute zero, and it can never overwrite a non-cold verdict. clamp01 is float insurance, not mechanism.
grade_turn
Run one judge verdict through conversion, tier decay, cross-line penalty and the threshold gate. Pure: reads the pre-turn affinity snapshot (all axes use the same tier lookup, so ordering inside a turn cannot matter) and returns what to apply; the caller owns clamping and persistence.