review: bxctl memory sync shows what the Honcho side waits on

A shared status, kept by the worker and the walk and read by the report under
its own leaf lock, holds the workspaces whose key was refused, when an outage
of Honcho began, and when brokerd stopped answering. The report adds a line
for each while it lasts, and is unchanged when all is well. The runbook's
Honcho entries and broker-state-unavailable now say what sync shows.

Tuning and Wake move to honcho/wake.rs (re-exported from worker) to keep
worker.rs under 500 lines. honcho_sync.rs's serve test now allows the outage
line: the write wakes the worker, which finds Honcho unreachable.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-28 14:11:31 -07:00
co-authored by Claude Opus 5.5
parent 3dd95c5791
commit 3d266df9de
12 changed files with 439 additions and 81 deletions
+16 -2
View File
@@ -9,6 +9,7 @@ use bxcore::{DataClass, SessionId, Timestamp};
use crate::files::Store;
use crate::honcho::ledger::{self, Action, Item, Ledger, Record, Workspace};
use crate::honcho::report;
use crate::honcho::status::{self, Shared};
use crate::journal;
use crate::notes::{self, Kind};
@@ -204,6 +205,8 @@ fn brought_back(ledger: &Ledger, action: &Action) -> bool {
/// With `[honcho]`: decides each journalled edit into the ledger.
pub struct Mirror {
ledger: Arc<Mutex<Ledger>>,
/// What the worker and the walk wait on, for the report; empty unless `with_status` is given.
status: Shared,
agent: String,
owner: String,
}
@@ -212,14 +215,25 @@ impl Mirror {
pub fn new(ledger: Arc<Mutex<Ledger>>, agent: &str, owner: &str) -> Mirror {
Mirror {
ledger,
status: Shared::default(),
agent: agent.to_string(),
owner: owner.to_string(),
}
}
/// `bxctl memory sync`'s report of the ledger, under the ledger's lock alone.
/// The same, reporting `status` too.
pub fn with_status(self, status: Shared) -> Mirror {
Mirror { status, ..self }
}
/// `bxctl memory sync`'s report: the status copied under its lock alone, then the ledger
/// under its own.
pub fn report(&self) -> String {
report::report(&self.ledger.lock().unwrap_or_else(|p| p.into_inner()))
let status = status::read(&self.status);
report::with_status(
&self.ledger.lock().unwrap_or_else(|p| p.into_inner()),
&status,
)
}
/// Decide the journalled edit `id` (the latest when `None`), called under the index lock