memoryd: memory writes decided into the Honcho ledger as they are journalled

Co-Authored-By: ornith-1.5-35b-a3b <agent@wntrmute.dev>
This commit is contained in:
2026-09-28 12:46:18 -07:00
co-authored by ornith-1.5-35b-a3b
parent b37eaef390
commit 4ebfc36c1a
8 changed files with 862 additions and 23 deletions
+20 -3
View File
@@ -17,6 +17,7 @@ use crate::config::Config;
use crate::edit::{self, Context};
use crate::files::Store;
use crate::honcho::ledger::{self, LedgerError};
use crate::honcho::mirror::Mirror;
use crate::honcho::state;
use crate::honcho::turns::TurnSync;
use crate::honcho::worker::{self, Wake};
@@ -43,6 +44,8 @@ pub struct Memoryd {
honcho: Option<Arc<Mutex<TurnSync>>>,
/// Wakes the Honcho worker when a turn has been decided.
wake: Arc<Wake>,
/// With `[honcho]`: decides memory writes into the ledger, under the ledger's own lock.
mirror: Option<Mirror>,
log: Log,
}
@@ -112,13 +115,14 @@ pub fn start(config: Config, log: Log) -> Result<Running, StartError> {
(admin_listener, Which::Admin),
];
let wake = Arc::new(Wake::default());
let honcho = match opened {
let (honcho, mirror) = match opened {
Some(opened) => {
let sync = Arc::clone(&opened.sync);
let mirror = opened.mirror();
worker::spawn(opened, &config, Arc::clone(&wake), Arc::clone(&log))?;
Some(sync)
(Some(sync), Some(mirror))
}
None => None,
None => (None, None),
};
Ok(Running {
memoryd: Arc::new(Memoryd {
@@ -127,6 +131,7 @@ pub fn start(config: Config, log: Log) -> Result<Running, StartError> {
state: Mutex::new(State { index }),
honcho,
wake,
mirror,
log,
}),
listeners,
@@ -217,6 +222,14 @@ impl Memoryd {
}
}
/// With `[honcho]`: decide journalled edit `id` (the latest when `None`) into the ledger. Called
/// under the index lock, so edits are decided in the journal's order (M5c spec, section 4).
fn mirror(&self, id: Option<&str>) {
if let Some(mirror) = &self.mirror {
mirror.journalled(&self.store, id, Timestamp::now(), &*self.log);
}
}
/// With `[honcho]`: decide the reported turn, and every other that waits (`TurnSync`).
fn decide_turns(&self, update: &SessionUpdated) {
let Some(honcho) = &self.honcho else {
@@ -359,6 +372,7 @@ impl Memoryd {
} else {
let outcome = edit::apply(&self.store, &args, &ctx)?;
let id = journal::record(&self.store, &ctx, &outcome)?;
self.mirror(Some(&id));
if let Some(rule) = outcome.flag {
(self.log)(
format!(
@@ -441,6 +455,9 @@ impl Memoryd {
MemoryCommand::Accept => review::accept(&self.store, arg, now),
MemoryCommand::Reject => review::reject(&self.store, arg, now),
};
if result.is_ok() && matches!(command, MemoryCommand::Undo | MemoryCommand::Accept) {
self.mirror(None);
}
self.index_notes(&state);
match result {
Ok(text) => Message::MemoryAdminReply(MemoryAdminReply { text }),