made_core/ports/memory_writer.rs
1use async_trait::async_trait;
2
3use crate::error::DomainError;
4use crate::ports::MemoryWriteOutcome;
5use crate::value_objects::{MemoryCapabilities, MemoryScope, MemoryWrite};
6
7/// Writing what a working session decided into memory that outlives it.
8///
9/// The engine already keeps an audit journal, and this is not that. A
10/// journal proves what happened in one session; memory is what a later
11/// session can navigate. One is evidence, the other is experience.
12///
13/// A write carries entries **and the reasons between them**, because
14/// the reasons are not decoration on the entries — they are the part a
15/// later session follows. What was decided can be listed; how one
16/// thing led to another can only be walked.
17#[async_trait]
18pub trait MemoryWriterPort: Send + Sync {
19 /// Record a write about `scope`.
20 ///
21 /// `idempotency_key` names the write, not the moment: the same key
22 /// twice is the same write twice, whatever the clock says.
23 ///
24 /// A backend that does not keep reasons still accepts a write that
25 /// carries them, and keeps what it can. Refusing would make a
26 /// caller choose between explaining itself and being stored, and
27 /// the honest place to learn what survives is the capabilities.
28 async fn remember(
29 &self,
30 scope: &MemoryScope,
31 write: MemoryWrite,
32 idempotency_key: &str,
33 ) -> Result<MemoryWriteOutcome, DomainError>;
34
35 /// What this backend can do. A caller may ask before it acts, and
36 /// the conformance suite checks the answer against behaviour: a
37 /// backend that claims to remember and then does not is worse than
38 /// one that claims nothing.
39 fn capabilities(&self) -> MemoryCapabilities;
40}