Skip to main content

made_core/ports/
memory_reader.rs

1use async_trait::async_trait;
2
3use crate::error::DomainError;
4use crate::ports::MemoryRecollection;
5use crate::value_objects::{
6    MemoryCapabilities, MemoryEntryId, MemoryMoment, MemoryQuestion, MemoryScope,
7};
8
9/// Reading what earlier sessions learned, and why.
10///
11/// Three ways of asking, because three different questions get asked:
12/// what is known about this at all, what does memory say about one
13/// thing in particular, and what was known at a moment. The third is
14/// not the first two filtered by date — it excludes what was learned
15/// later about earlier events, which is the whole point of asking it.
16#[async_trait]
17pub trait MemoryReaderPort: Send + Sync {
18    /// Everything memory holds about `scope`.
19    async fn recall(&self, scope: &MemoryScope) -> Result<MemoryRecollection, DomainError>;
20
21    /// What memory says in answer to a question put in words.
22    async fn ask(
23        &self,
24        scope: &MemoryScope,
25        question: &MemoryQuestion,
26    ) -> Result<MemoryRecollection, DomainError>;
27
28    /// What was known about `scope` at `moment`.
29    async fn as_known_at(
30        &self,
31        scope: &MemoryScope,
32        moment: MemoryMoment,
33    ) -> Result<MemoryRecollection, DomainError>;
34
35    /// The chain of reasons leading from `from` back to `to`.
36    ///
37    /// The question the whole contract exists to answer, and the only
38    /// one whose failure means the memory has stopped being worth
39    /// keeping: everything else can be reconstructed by reading, and
40    /// this cannot.
41    ///
42    /// It answers with the reasons and not with the prose — the edges
43    /// on the path, in the order they connect. What each end says is
44    /// what `recall` is for, and a backend that padded the chain with
45    /// text would make two contracts out of one.
46    ///
47    /// An empty chain is a real answer: the two are not connected by
48    /// anything anyone wrote down.
49    async fn follow(
50        &self,
51        scope: &MemoryScope,
52        from: &MemoryEntryId,
53        to: &MemoryEntryId,
54    ) -> Result<MemoryRecollection, DomainError>;
55
56    fn capabilities(&self) -> MemoryCapabilities;
57}