Skip to main content

hippmem_engine/
feedback_api.rs

1//! Engine::feedback — usage feedback API.
2//!
3//! Corresponds to 05#feedback, 09 §4.6. Records usage signals to activation_log,
4//! driving Hebbian reinforcement/decay (consumed by the consolidate worker).
5
6use crate::{Engine, EngineError, EngineResult, FeedbackInput};
7use hippmem_core::time::{Clock, SystemClock};
8use hippmem_store::activation_log::{ActivationLogger, ActivationRecord};
9
10impl Engine {
11    /// Records a usage feedback signal.
12    ///
13    /// The signal is persisted to activation_log for consumption by the
14    /// background Hebbian/decay worker.
15    pub fn feedback(&self, input: FeedbackInput) -> EngineResult<()> {
16        let clock = SystemClock;
17        let now = clock.now();
18
19        let logger = ActivationLogger::new(self.store.db_arc());
20        let rec = ActivationRecord {
21            retrieval_id: input.retrieval_id,
22            used_memory_ids: input.used_memory_ids.iter().map(|id| id.0 as u64).collect(),
23            signal: signal_to_string(&input.signal),
24            recorded_at_ms: now.as_i64(),
25        };
26        logger
27            .record(&rec)
28            .map_err(|e| EngineError::Internal(format!("activation_log: {}", e)))?;
29        Ok(())
30    }
31}
32
33fn signal_to_string(s: &crate::UsageSignal) -> String {
34    match s {
35        crate::UsageSignal::Referenced => "Referenced".into(),
36        crate::UsageSignal::UserConfirmedCorrect => "UserConfirmedCorrect".into(),
37        crate::UsageSignal::TaskSucceeded => "TaskSucceeded".into(),
38        crate::UsageSignal::UserRejected => "UserRejected".into(),
39    }
40}