Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
29 KiB
M5c-1 task 13: the Honcho worker sends memory writes
Branch: m5c1 (run git switch m5c1; git status --short must be empty, otherwise stop)
Commit subject: memoryd: the Honcho worker sends conclusions, their deletions and fleet notes
Log row: the Task cell is M5c1/13-memoryd-honcho-edits.
Goal
Task 12 decides each memory write into the ledger; task 11's worker sends only turns. This task makes the worker send the rest (M5c spec, sections 4 and 5): one outbox, oldest first, across every kind of item.
Conclude: the conclusion is made in the item's workspace (trusted), about itspeer(observer and observed are both that peer), stamped with the Boxmaker session's memory session,<id>_memory. That Honcho session holds the agent's peer and the owner's and is made on first use, whether or not any turn of the session is synced (spec section 4, as of 2026-09-28). Neither peer observes in it: it holds conclusions, not messages, and the spec gives no flags for it, so both get the agent's (observe_me: false,observe_others: false). The text is neutralised as it leaves.Sentrecords the one id Honcho gives.Unconclude: the id to delete isledger.conclusion(workspace, text)(task 07): the latest sentConcludeof that text not yet undone. It is deleted (delete_conclusion, task 10: 204 or 404 is done), andSentrecords the deleted id, which pops it fromconclusion's stack. With none (never sent, itsConcludefailed, or already undone) nothing is asked:Sentwith no ids, and no log line. AConcludestill waiting cannot be behind itsUnconclude: it was decided first, and the outbox keeps that order.Fleet: the untrusted note is added to the fleet workspace (made with task 10's settings) as messages from the agent's peer, neutralised, in parts of 25,000 characters, in one batch, to the Honcho session named after the Boxmaker session,<id>, holding only the agent's peer (spec section 3).Sentrecords the ids.Retract: nothing decides one any more (a note cannot be undone), so it waits in the outbox, untouched.- Errors, as for turns (task 11): unreachable waits and tries the same item again; refused
marks it failed, logged once; a refused key stops that workspace. Log lines name an edit's item
part <n> of edit <id>.
To stay under 500 lines, worker.rs's start code (Opened, open, spawn) moves, unchanged
but for its imports, to a new file honcho/start.rs; worker.rs re-exports them, so serve.rs
does not change.
Interfaces
In crates/memoryd/src/honcho/edits.rs (the module memoryd::honcho::edits):
pub const MEMORY_SUFFIX: &str = "_memory";
pub fn memory_session(session: &SessionId) -> String;
pub fn conclude(clients: &mut Clients, workspace: Workspace, peer: &str, session: &SessionId,
text: &str) -> Result<Vec<String>, HonchoError>;
pub fn unconclude(clients: &Clients, workspace: Workspace, id: Option<&str>)
-> Result<Vec<String>, HonchoError>;
pub fn fleet_batch(text: &str, agent: &str, session: &SessionId, edit: &str) -> Vec<MessageCreate>;
pub fn fleet(clients: &mut Clients, session: &SessionId, messages: &[MessageCreate])
-> Result<Vec<String>, HonchoError>;
In client.rs: Clients keeps [honcho] owner, and gains
ensure_memory_session(&mut self, workspace: Workspace, name: &str) -> Result<(), HonchoError>
(edits C1 to C3). In worker.rs, the private Next holds a Job (Turn, Conclude,
Unconclude, Fleet), next builds it for any kind of item, and send dispatches on it
(edits W1 to W7).
The requests
Fixture 11 is the conclusion's shape:
| Item | Requests |
|---|---|
Conclude |
make sure of the workspace, the agent's peer, the owner's peer and <id>_memory ({"id":"<id>_memory","peers":{"<agent>":{"observe_me":false,"observe_others":false},"<owner>":{"observe_me":false,"observe_others":false}}}), then POST /v3/workspaces/<trusted>/conclusions with {"conclusions":[{"content":"<text>","observer_id":"<peer>","observed_id":"<peer>","session_id":"<id>_memory"}]} |
Unconclude |
DELETE /v3/workspaces/<trusted>/conclusions/<id>, or none |
Fleet |
make sure of the fleet workspace, the agent's peer and <id> ({"id":"<id>","peers":{"<agent>":{"observe_me":false,"observe_others":false}}}), then POST /v3/workspaces/<fleet>/sessions/<id>/messages with each part {"content":"<part>","peer_id":"<agent>","metadata":{"agent":"<agent>","boxmaker_session":"<id>","edit":"<edit id>"}} |
What was made sure of is remembered for the run (task 10), so a second conclusion in the same session asks only for the conclusion.
Every place that changes
This is the complete list.
| Place | What happens there |
|---|---|
crates/memoryd/src/honcho/mod.rs |
pub mod edits; and pub mod start; (edits H1, H2) |
crates/memoryd/src/honcho/client.rs |
owner, ensure_memory_session (edits C1 to C3) |
crates/memoryd/src/honcho/edits.rs |
new: a skeleton you copy, then fill 5 bodies |
crates/memoryd/src/honcho/start.rs |
new, given whole: the start code from worker.rs |
crates/memoryd/src/honcho/worker.rs |
imports, Job and Next, label, the two log lines, next/send/send_turn, the start code removed (edits W1 to W7) |
crates/memoryd/tests/support/honcho.rs |
a new version, given: the fake answers a conclusion batch (fixture 11), and a batch with as many items as it asked for |
crates/memoryd/tests/honcho_worker_more.rs |
a new version, given: its "later actions wait" test is now about a retraction |
| everything else | no change |
Files
- Copy, from
docs/plans/M5c1/files/(the same path under it):- the new test
crates/memoryd/tests/honcho_edits.rs - new versions (they replace the files in the tree) of
crates/memoryd/tests/support/honcho.rsandcrates/memoryd/tests/honcho_worker_more.rs; do not copyhoncho.rs-task10orhoncho_worker_more.rs-task11, the older ones - the skeleton
crates/memoryd/src/honcho/edits.rsand the filecrates/memoryd/src/honcho/start.rs(given whole: nothing to fill)
- the new test
- Modify: the files of edits H1 to W7,
docs/implementer-log.md. - Do not touch: any other source file (
serve.rsin particular), any other test or support file, the fixtures, anyCargo.toml, and in the skeleton anything but the 5todo!()bodies.
Facts you need
roncho's conclusion call (roncho::blocking::Client):create_conclusions(&ConclusionBatchCreate) -> Result<Vec<roncho::Conclusion>, Error>(POST .../conclusions; a batch of 1 to 100, checked before sending).ConclusionCreate::new(content, observer_id, observed_id),.with_session_id(name);ConclusionBatchCreate::new(vec![..]).Conclusion.idis the id. Honcho'ssrc/schemas/api.pycaps a conclusion batch at 100, as it does messages.- Task 07's
conclusionreplays theSentrecords in order: a sentConcludeof a workspace and text pushes(item, ids[0]); a sentUnconcludeof the same pops. So anUnconclude'sSentpops whether it carries the deleted id or none; the id is kept for the record. - Session names.
_is allowed in Honcho names and in no Boxmaker session id, so<id>_memoryis never a turn session (<id>,<id>-2, …) or another session's id. - The given code of the worker, after W6:
nextmatches(item, action)pairs; anUnconclude's id is looked up there, under the ledger's lock, when the item is picked;sendcallssend_turn(task 11's turn code, unchanged but for its arguments) oredits. - The given tests.
honcho_edits.rs(10 tests): the memory session's name; a conclusion's five requests, exactly, its id, andconclusion; a replace and its undo (the requests in order, the deleted ids, each thing made sure of once); anUnconcludewith nothing to delete (never sent, or itsConcludefailed); a 404 on delete; a fleet note's four requests, exactly, and a long note in parts; a note too long for one batch; neutralising; one outbox across a turn, an edit and a turn, and a restart that sends nothing; errors (an outage, a 422, a refused fleet key that leaves the trusted workspace going), with no text in a log line.honcho_worker_more.rs(10 tests): task 11's, with its "later actions" test about a retraction, which waits.
- The calls the bodies use:
Call Signature, and what it gives Clients::ensure_memory_sessionedit C3: (&mut self, workspace, name: &str) -> Result<(), HonchoError>Clients::ensure_session,delete_conclusion,clienttask 10 ConclusionCreate,ConclusionBatchCreateabove Client::create_conclusions,add_messagesabove; task 11 neutralisebxcore::sanitize::neutralise(text) -> Cow<'_, str>;ConclusionCreate::newtakes it asimpl Into<String>worker::partstask 11: parts of at most 25,000 characters classifytask 10: roncho's error as aHonchoError
The edits, exactly
Nothing else in these files changes. Each quoted "before" block occurs exactly once in its file.
Edit W6 replaces next and send as they are after task 12 (next's body is yours from task
11, with task 12's W5); edit W7 removes the start code, which moves to start.rs. If either
"before" block differs from your file, stop and report.
crates/memoryd/src/honcho/worker.rs
W1. The lines
use crate::config::Config;
use crate::honcho::client::{Clients, HonchoError, Timeouts, classify};
use crate::honcho::config::HonchoConfig;
use crate::honcho::decide::{final_reply, turn_records, user_text};
use crate::honcho::ledger::{self, Action, Item, Ledger, Record, Workspace};
use crate::honcho::mirror::Mirror;
use crate::honcho::naming::{HonchoSession, honcho_session};
use crate::honcho::state;
use crate::honcho::turns::{LEDGER, TurnSync, log_path, read_log};
use crate::serve::{Log, StartError};
become
use crate::honcho::client::{Clients, HonchoError, classify};
use crate::honcho::decide::{final_reply, turn_records, user_text};
use crate::honcho::edits;
use crate::honcho::ledger::{self, Action, Item, Ledger, Record, Workspace};
use crate::honcho::naming::{HonchoSession, honcho_session};
use crate::honcho::turns::{TurnSync, log_path, read_log};
use crate::serve::Log;
pub use crate::honcho::start::{Opened, open, spawn};
W2. The lines
/// A turn to send: its item, workspace, speaker and Honcho session.
struct Next {
item: Item,
session: SessionId,
turn: u64,
workspace: Workspace,
speaker: String,
honcho: Option<HonchoSession>,
}
become
/// What to send for one waiting item (M5c spec, section 5).
enum Job {
/// A turn: its session and number, its speaker, and its Honcho session.
Turn {
session: SessionId,
turn: u64,
speaker: String,
honcho: Option<HonchoSession>,
},
/// A conclusion about `peer`, stamped with `session`'s memory session.
Conclude {
peer: String,
session: SessionId,
text: String,
},
/// Delete the conclusion with this id; `None` when no sent conclusion is live.
Unconclude { id: Option<String> },
/// An untrusted note: a fleet message from the agent.
Fleet {
session: SessionId,
edit: String,
text: String,
},
}
/// The oldest waiting item: what it is, where it goes, and what to send.
struct Next {
item: Item,
workspace: Workspace,
job: Job,
}
W3. The line
/// The ids of the messages Honcho made, in order.
becomes
/// An item as the log lines name it: `turn 3 of session mm-a`, `part 0 of edit 2026-09-28-0001`.
fn label(item: &Item) -> String {
match item {
Item::Turn { session, turn } => format!("turn {turn} of session {}", session.as_str()),
Item::Edit { id, part } => format!("part {part} of edit {id}"),
}
}
/// The ids of the messages Honcho made, in order.
W4. In step, in the arm Err(Unsent::Honcho(e)), the lines
"memoryd: turn {} of session {} was not sent: {e}; it is marked failed; {SEND_REFUSED}",
next.turn,
next.session.as_str()
become
"memoryd: {} was not sent: {e}; it is marked failed; {SEND_REFUSED}",
label(&next.item)
W5. In step, in the arm Err(Unsent::Local(kind)), the lines
"memoryd: turn {} of session {} cannot be sent ({kind}); it is marked failed; {pointer}",
next.turn,
next.session.as_str()
become
"memoryd: {} cannot be sent ({kind}); it is marked failed; {pointer}",
label(&next.item)
W6. The lines (the whole of next and send, from next's doc comment to the line before unreachable's)
/// The oldest waiting turn whose workspace's key was not refused. Other actions wait.
fn next(&self) -> Option<Next> {
let ledger = self.ledger.lock().unwrap_or_else(|p| p.into_inner());
ledger.outbox().into_iter().find_map(|(item, action)| {
let Item::Turn { session, turn } = &item else {
return None;
};
let Action::Turn { workspace, speaker } = action else {
return None;
};
if self.refused.contains(&workspace) {
return None;
}
Some(Next {
honcho: honcho_session(ledger.decisions(), session, *turn),
session: session.clone(),
turn: *turn,
item: item.clone(),
workspace,
speaker,
})
})
}
/// Read the turn again, make sure of its Honcho session, and add its messages as one batch.
fn send(&mut self, next: &Next) -> Result<Vec<String>, Unsent> {
let (text, reply) = read_turn(&log_path(&self.sessions, &next.session), next.turn)
.ok_or(Unsent::Local("log"))?;
let honcho = next.honcho.as_ref().ok_or(Unsent::Local("log"))?;
let messages = batch(
&text,
&reply,
&next.speaker,
&self.agent,
&next.session,
next.turn,
);
if messages.len() > MAX_BATCH {
return Err(Unsent::Local("too-long"));
}
self.clients
.ensure_session(next.workspace, honcho)
.map_err(Unsent::Honcho)?;
let client = self.clients.client(next.workspace);
match client.add_messages(&honcho.name, &messages) {
Ok(made) => Ok(ids(&made)),
Err(e) => Err(Unsent::Honcho(classify(&e))),
}
}
become
/// The oldest waiting item whose workspace's key was not refused. A retraction, which
/// nothing decides any more, waits.
fn next(&self) -> Option<Next> {
let ledger = self.ledger.lock().unwrap_or_else(|p| p.into_inner());
ledger.outbox().into_iter().find_map(|(item, action)| {
let (workspace, job) = match (&item, action) {
(Item::Turn { session, turn }, Action::Turn { workspace, speaker }) => (
workspace,
Job::Turn {
honcho: honcho_session(ledger.decisions(), session, *turn),
session: session.clone(),
turn: *turn,
speaker,
},
),
(
Item::Edit { .. },
Action::Conclude {
workspace,
peer,
session,
text,
},
) => (
workspace,
Job::Conclude {
peer,
session,
text,
},
),
(Item::Edit { .. }, Action::Unconclude { workspace, text }) => (
workspace,
Job::Unconclude {
id: ledger.conclusion(workspace, &text).map(|(_, id)| id),
},
),
(Item::Edit { id, .. }, Action::Fleet { session, text }) => (
Workspace::Fleet,
Job::Fleet {
session,
edit: id.clone(),
text,
},
),
_ => return None,
};
if self.refused.contains(&workspace) {
return None;
}
Some(Next {
item: item.clone(),
workspace,
job,
})
})
}
/// Send one item, by what it is.
fn send(&mut self, next: &Next) -> Result<Vec<String>, Unsent> {
let honcho = |e| Unsent::Honcho(e);
match &next.job {
Job::Turn {
session,
turn,
speaker,
honcho: name,
} => self.send_turn(next.workspace, session, *turn, speaker, name.as_ref()),
Job::Conclude {
peer,
session,
text,
} => edits::conclude(&mut self.clients, next.workspace, peer, session, text)
.map_err(honcho),
Job::Unconclude { id } => {
edits::unconclude(&self.clients, next.workspace, id.as_deref()).map_err(honcho)
}
Job::Fleet {
session,
edit,
text,
} => {
let messages = edits::fleet_batch(text, &self.agent, session, edit);
if messages.len() > MAX_BATCH {
return Err(Unsent::Local("too-long"));
}
edits::fleet(&mut self.clients, session, &messages).map_err(honcho)
}
}
}
/// Read the turn again, make sure of its Honcho session, and add its messages as one batch.
fn send_turn(
&mut self,
workspace: Workspace,
session: &SessionId,
turn: u64,
speaker: &str,
honcho: Option<&HonchoSession>,
) -> Result<Vec<String>, Unsent> {
let (text, reply) =
read_turn(&log_path(&self.sessions, session), turn).ok_or(Unsent::Local("log"))?;
let honcho = honcho.ok_or(Unsent::Local("log"))?;
let messages = batch(&text, &reply, speaker, &self.agent, session, turn);
if messages.len() > MAX_BATCH {
return Err(Unsent::Local("too-long"));
}
self.clients
.ensure_session(workspace, honcho)
.map_err(Unsent::Honcho)?;
let client = self.clients.client(workspace);
match client.add_messages(&honcho.name, &messages) {
Ok(made) => Ok(ids(&made)),
Err(e) => Err(Unsent::Honcho(classify(&e))),
}
}
W7. At the end of the file, the lines (the end of impl Worker, then the start code)
}
/// With `[honcho]`, at start: the ledger read through, the sessions that wait again, and the
/// clients with their keys read. Nothing is bound or started yet.
pub struct Opened {
pub sync: Arc<Mutex<TurnSync>>,
clients: Clients,
agent: String,
owner: String,
}
impl Opened {
/// The memory writes' side of the ledger (task 12).
pub fn mirror(&self) -> Mirror {
let ledger = self
.sync
.lock()
.unwrap_or_else(|p| p.into_inner())
.shared_ledger();
Mirror::new(ledger, &self.agent, &self.owner)
}
}
/// Open the ledger (a cut-off last line is logged), resume the waiting sessions, and build the
/// clients (their key files' warnings are logged). A key that cannot be read is `Secret`.
pub fn open(config: &Config, honcho: &HonchoConfig, log: &Log) -> Result<Opened, StartError> {
let path = config.memory_dir().join(LEDGER);
let ledger = Ledger::open(&path).map_err(StartError::Ledger)?;
if ledger.repaired() {
(log)(&format!(
"memoryd: {}: a last line cut off by a crash was dropped",
path.display()
));
}
let mut sync = TurnSync::new(ledger, &honcho.agent, &config.sessions_dir());
sync.resume();
let env = |name: &str| std::env::var_os(name);
let (clients, warnings) =
Clients::new(honcho, &env, Timeouts::WRITES).map_err(StartError::Secret)?;
for warning in warnings {
(log)(&warning);
}
Ok(Opened {
sync: Arc::new(Mutex::new(sync)),
clients,
agent: honcho.agent.clone(),
owner: honcho.owner.clone(),
})
}
/// Start the worker's thread, asking `brokerd` on `config`'s state socket.
pub fn spawn(opened: Opened, config: &Config, wake: Arc<Wake>, log: Log) -> Result<(), String> {
let socket = config.state_socket();
let ask: AskBox =
Box::new(move |session: &SessionId| state::ask(&socket, session, state::WAIT));
let worker = Worker::new(
opened.sync,
opened.clients,
wake,
ask,
log,
Tuning::DEFAULT,
&opened.agent,
);
std::thread::Builder::new()
.name("honcho".to_string())
.spawn(move || worker.run())
.map(|_| ())
.map_err(|e| format!("cannot start the Honcho worker: {e}"))
}
become
}
crates/memoryd/src/honcho/client.rs
C1. In pub struct Clients, the lines
fleet: Client,
agent: String,
become
fleet: Client,
agent: String,
owner: String,
C2. In Clients::new, the lines
agent: config.agent.clone(),
ensured: HashSet::new(),
become
agent: config.agent.clone(),
owner: config.owner.clone(),
ensured: HashSet::new(),
C3. The line
/// Delete conclusion `id` in `workspace`. Gone already (404) counts as done.
becomes
/// Make sure memory session `name` (a Boxmaker session's `<id>_memory`) exists in
/// `workspace`, after the workspace, the agent's peer and the owner's. It holds conclusions,
/// no messages, so neither peer observes (M5c spec, section 4).
pub fn ensure_memory_session(
&mut self,
workspace: Workspace,
name: &str,
) -> Result<(), HonchoError> {
self.ensure_workspace(workspace)?;
let (agent, owner) = (self.agent.clone(), self.owner.clone());
self.ensure_peer(workspace, &agent)?;
self.ensure_peer(workspace, &owner)?;
let key = (workspace, Ensured::Session(name.to_string()));
if self.ensured.contains(&key) {
return Ok(());
}
let unobserved = || {
SessionPeerConfig::new()
.observe_me(false)
.observe_others(false)
};
let mut peers = HashMap::new();
peers.insert(agent, unobserved());
peers.insert(owner, unobserved());
let create = SessionCreate::new(name).with_peers(peers);
created(self.client(workspace).session(&create))?;
self.ensured.insert(key);
Ok(())
}
/// Delete conclusion `id` in `workspace`. Gone already (404) counts as done.
crates/memoryd/src/honcho/mod.rs
H1. The line
pub mod decide;
becomes
pub mod decide;
pub mod edits;
H2. The line
pub mod naming;
becomes
pub mod naming;
pub mod start;
Steps
-
1. Copy the given tests. From the repository root, three commands:
cp docs/plans/M5c1/files/crates/memoryd/tests/honcho_edits.rs crates/memoryd/tests/ cp docs/plans/M5c1/files/crates/memoryd/tests/honcho_worker_more.rs crates/memoryd/tests/ cp docs/plans/M5c1/files/crates/memoryd/tests/support/honcho.rs crates/memoryd/tests/support/ -
2. See them fail. With a shell timeout of 600000 ms:
cargo build --tests --keep-going -p memoryd: one test target does not compile,honcho_edits, with one error,E0432(unresolved import `memoryd::honcho::edits`). Every other target compiles.cargo test -p memoryd --test honcho_worker_more --test honcho_client --test honcho_workerpasses (10, 13, 12): the new fake and the retraction test agree with the code as it is.
-
3. The new files. Make edits H1, H2 and C1 to C3, then copy:
cp docs/plans/M5c1/files/crates/memoryd/src/honcho/edits.rs crates/memoryd/src/honcho/ cp docs/plans/M5c1/files/crates/memoryd/src/honcho/start.rs crates/memoryd/src/honcho/cargo check -p memoryd: no error, and 22 warnings, all from the unfilled bodies: sixunused importlines (bxcore::sanitize::neutralise;classify;crate::honcho::naming::HonchoSession;crate::honcho::worker::parts;ConclusionBatchCreateandConclusionCreate;Mapandjson), and sixteenunused variable(sessionfour times,clientsthree times,textandworkspacetwice each, andagent,edit,id,messages,peeronce each). -
4. Fill the five bodies of
edits.rs, one at a time, in the order of the file, each from its comment, and runcargo check -p memorydafter each:memory_session,conclude,unconclude,fleet_batch,fleet. When a body is filled, delete its instruction comment (the//lines inside the body) and keep the function's doc comment (///) as it is. After the fifth,cargo check -p memorydprints no warning. -
5. The worker. Make edits W1 to W7.
cargo check -p memoryd: no error and no warning.wc -l crates/memoryd/src/honcho/worker.rsprints a number under 500. -
6. The tests. With a shell timeout of 600000 ms, and every test passes (10, 10, 12, and the earlier ones unchanged):
cargo test -p memoryd --test honcho_edits --test honcho_worker_more --test honcho_worker \ --test honcho_client --test honcho_keys --test honcho_mirror_serve --test honcho_serve -
7. Check. Three commands:
grep -n 'fn open\|fn spawn' crates/memoryd/src/honcho/worker.rs crates/memoryd/src/honcho/start.rsprints two lines, both instart.rs.grep -n 'Action::Retract' crates/memoryd/src/honcho/worker.rsprints nothing: a retraction waits.git diff --stat -- crates/bxcore crates/loopd crates/brokerd crates/gatewayd crates/bxctl Cargo.toml Cargo.lock crates/memoryd/Cargo.toml crates/memoryd/src/serve.rs crates/memoryd/src/honcho/ledger.rs crates/memoryd/src/honcho/mirror.rsprints nothing.
-
8. Run the gate.
cargo fmt --all, thenmake gate, with a shell timeout of 600000 ms. Expected last line:gate: ok, with 1324 tests: 1314 before this task, plus 10 new ones inhoncho_edits.rs. -
9. Log and commit. Add your row to
docs/implementer-log.md; its Task cell isM5c1/13-memoryd-honcho-edits.git status --shortlistshoncho/mod.rs,client.rs,worker.rs,tests/support/honcho.rs,tests/honcho_worker_more.rsand your log as modified, andedits.rs,start.rsandtests/honcho_edits.rsas new. Stage withgit add crates/memoryd docs/implementer-log.md Cargo.lock, then commit asAGENTS.mdsays.Cargo.lockdoes not change in this task; thegit addis harmless.
Done when
make gateprintsgate: okwith 1324 tests.git diff HEAD~1 --statlists only the files of step 9.
Stop and report if
- A "before" block of H1, H2, C1 to C3 or W1 to W7 is not in its file exactly as shown, or is there more than once.
- Step 2 or 3 shows a different result: other test targets, errors of another kind, other warnings, or other tests failing.
cargo checkreports an error after a body you filled or an edit you made, and the comment or the edit does not tell you how to fix it. Quote the error, and stop.- A comment in the skeleton does not fit the code under it, or disagrees with this task's tables. Quote both and stop.
- After step 4 or 6 a test fails although each body follows its comment and each edit is as shown. Do not change a test, the fake or the given code: stop, and give the failing tests' names and their messages.
- A test seems to need a real Honcho or a new fixture. It does not; stop and say why.
- The fix seems to need a change anywhere else:
serve.rs,ledger.rs,mirror.rs, another crate. It does not; stop and say why you think so. - A test outside the new files fails in the gate: check once whether it fails without your
change, then stop and report both results. (
gatewayd'sgateway_socktestbrokerd_closing_first_ends_it_as_no_longer_pendingfails now and then on a loaded machine, without this task's change; if it is the one, run the gate once more.) - The gate passes with a count other than 1324.
What the given tests pin
Each of these changes to the finished code makes at least one given test fail (23 tried): the
suffix; a conclusion not neutralised, observed by the agent, not stamped, or without its memory
session made first; its id dropped; an Unconclude recording no id, or deleting something when
there is nothing; a fleet note not neutralised, from the speaker, without its edit in the
metadata, its session with a speaker or not made first, or over the batch limit; the memory
session's owner observed, left out, or not remembered; edits left waiting; an Unconclude
looked up in another workspace; a fleet note sent to the trusted workspace; a retraction sent;
an edit's log label; a refused workspace ignored for edits.
After this task
- Task 14:
bxctl memory syncshows the ledger's counts and its failed items. - Task 15: the cutoff, turns from before Honcho was turned on skipped.