diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cea198..f10bf85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Hybrid retrieval now combines vector ranks with BM25 lexical ranks using Reciprocal Rank Fusion when `SearchOptions::hybrid(...)` or the CLI `search --hybrid` flag is enabled. +- `PriorConsultationPolicy` under `mnemos::agentic`, re-exported at the crate + root, so host runtimes can declare whether relevant prior episodes are + required, advisory, or explicitly ignored. ### Fixed diff --git a/crates/mnemos/src/agentic/mod.rs b/crates/mnemos/src/agentic/mod.rs index 66c8bc0..57568c2 100644 --- a/crates/mnemos/src/agentic/mod.rs +++ b/crates/mnemos/src/agentic/mod.rs @@ -17,6 +17,7 @@ mod causal; mod meta; mod online; +mod policy; mod reflexion; mod sessions; mod skills; @@ -25,6 +26,7 @@ mod temporal; pub use causal::{CausalEdge, CausalMemory, CausalNode, Hyperedge}; pub use meta::{FewShotLearner, LearningStrategy, MetaLearner, TaskFeatures}; pub use online::{DriftDetector, Experience, ExperienceWindow, OnlineLearner, ParameterSnapshot}; +pub use policy::PriorConsultationPolicy; pub use reflexion::{Critique, CritiqueType, ReflexionEpisode, ReflexionMemory}; pub use sessions::{LearningSession, Reward, SessionTurn}; pub use skills::{Skill, SkillLibrary, SkillPattern}; diff --git a/crates/mnemos/src/agentic/policy.rs b/crates/mnemos/src/agentic/policy.rs new file mode 100644 index 0000000..96f8873 --- /dev/null +++ b/crates/mnemos/src/agentic/policy.rs @@ -0,0 +1,75 @@ +//! Agentic memory consultation policy. +//! +//! The policy answers whether a host must consult prior episodes before +//! promoting load-bearing reasoning. Mnemos owns this vocabulary because it +//! owns agentic memory and recall; host runtimes decide how to enforce it. + +use serde::{Deserialize, Serialize}; + +/// How strongly a run should depend on relevant prior episodes. +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "snake_case")] +pub enum PriorConsultationPolicy { + /// Consult priors whenever available; continue without them when the + /// episodic store is unavailable. + #[default] + RequireWhenAvailable, + /// Block promotion of load-bearing claims if relevant priors cannot be + /// consulted. + RequireForLoadBearingClaims, + /// Surface priors when recalled, but never block if recall is unavailable. + OptionalAdvisory, + /// Explicitly do not consult prior episodes for this run. + IgnorePriors, +} + +impl PriorConsultationPolicy { + /// Returns whether missing prior recall should block load-bearing claims. + #[must_use] + pub const fn blocks_without_priors(self) -> bool { + matches!(self, Self::RequireForLoadBearingClaims) + } + + /// Returns whether the policy permits prior recall. + #[must_use] + pub const fn consults_priors(self) -> bool { + !matches!(self, Self::IgnorePriors) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn default_requires_priors_when_available() { + assert_eq!( + PriorConsultationPolicy::default(), + PriorConsultationPolicy::RequireWhenAvailable + ); + } + + #[test] + fn only_load_bearing_policy_blocks_when_priors_are_missing() { + assert!(PriorConsultationPolicy::RequireForLoadBearingClaims.blocks_without_priors()); + assert!(!PriorConsultationPolicy::RequireWhenAvailable.blocks_without_priors()); + assert!(!PriorConsultationPolicy::OptionalAdvisory.blocks_without_priors()); + assert!(!PriorConsultationPolicy::IgnorePriors.blocks_without_priors()); + } + + #[test] + fn ignore_priors_disables_recall() { + assert!(!PriorConsultationPolicy::IgnorePriors.consults_priors()); + assert!(PriorConsultationPolicy::OptionalAdvisory.consults_priors()); + } + + #[test] + fn policy_serializes_as_snake_case() { + let json = + serde_json::to_string(&PriorConsultationPolicy::RequireForLoadBearingClaims).unwrap(); + assert_eq!(json, "\"require_for_load_bearing_claims\""); + + let back: PriorConsultationPolicy = serde_json::from_str(&json).unwrap(); + assert_eq!(back, PriorConsultationPolicy::RequireForLoadBearingClaims); + } +} diff --git a/crates/mnemos/src/lib.rs b/crates/mnemos/src/lib.rs index 8dbf1c1..657e0b9 100644 --- a/crates/mnemos/src/lib.rs +++ b/crates/mnemos/src/lib.rs @@ -107,6 +107,7 @@ pub use crate::agentic::{ // Online/continual learning OnlineLearner, ParameterSnapshot, + PriorConsultationPolicy, // Reflexion (self-critique) ReflexionEpisode, ReflexionMemory, diff --git a/kb/Architecture/Surface.md b/kb/Architecture/Surface.md index 5228e42..59abf45 100644 --- a/kb/Architecture/Surface.md +++ b/kb/Architecture/Surface.md @@ -14,6 +14,8 @@ whose Rust library name is `mnemos`. - `ProvenanceSource` and `MNEMOS_PROVENANCE` for typed proposal provenance before crossing into `converge-pack::ProposedFact`. - `mnemos.suggestor.execute` tracing spans on knowledge suggestor execution. +- `PriorConsultationPolicy` for host runtimes that need to declare whether + relevant prior episodes are required, advisory, or ignored. ## Contract dependencies