review: a secret session's recall and ask_memory still query Honcho

Spec 13 requires that a secret session's query is sent unless the query
itself holds a known-prefix secret. serve.rs already ignores MemoryCall
taint on both read tools; the serve tests always sent Private. A skip of
Honcho for Secret would not have failed. Each suite now has one call at
class secret that asserts the fake received the search or chat.

Co-Authored-By: Grok 4.6 <noreply@x.ai>
This commit is contained in:
2026-10-02 20:11:01 -07:00
co-authored by Grok 4.6
parent e0f0057ac8
commit f80842640c
2 changed files with 69 additions and 2 deletions
+37 -1
View File
@@ -60,6 +60,16 @@ impl Home {
/// One call on `brokerd`'s socket and its answer, within 20 s; how long it took.
fn call(socket: &Path, tool: &str, arguments: &str) -> (ToolResponse, Duration) {
call_at(socket, tool, arguments, DataClass::Private)
}
/// `call`, with the session's class on the `MemoryCall`.
fn call_at(
socket: &Path,
tool: &str,
arguments: &str,
taint: DataClass,
) -> (ToolResponse, Duration) {
let started = Instant::now();
let mut stream = UnixStream::connect(socket).unwrap();
stream
@@ -76,7 +86,7 @@ fn call(socket: &Path, tool: &str, arguments: &str) -> (ToolResponse, Duration)
tool: tool.to_string(),
arguments: arguments.to_string(),
},
taint: DataClass::Private,
taint,
untrusted: false,
}),
};
@@ -230,3 +240,29 @@ fn an_unknown_tool_is_refused() {
"memoryd runs only recall, memory and ask_memory"
);
}
/// Spec 13: a `secret` session's question still reaches Honcho; only a question holding a secret
/// is refused.
#[test]
fn a_secret_session_still_asks_honcho() {
let fake = FakeHoncho::start();
let home = Home::serve("ask-serve-secret", Some(&fake.url));
let (content, class, untrusted) = result(
call_at(
&home.config.broker_socket(),
"ask_memory",
QUESTION,
DataClass::Secret,
)
.0,
);
assert!(
fake.requests().iter().any(|r| r.path.ends_with("/chat")),
"Honcho was not asked: {content}"
);
assert!(
content.starts_with("[1] memory · own · private\n Based on what I found in memory, "),
"{content}"
);
assert_eq!((class, untrusted), (DataClass::Private, false));
}
+32 -1
View File
@@ -71,6 +71,16 @@ impl Home {
/// One call on `brokerd`'s socket and its answer, within 20 s; how long it took.
fn call(socket: &Path, tool: &str, arguments: &str) -> (ToolResponse, Duration) {
call_at(socket, tool, arguments, DataClass::Private)
}
/// `call`, with the session's class on the `MemoryCall`.
fn call_at(
socket: &Path,
tool: &str,
arguments: &str,
taint: DataClass,
) -> (ToolResponse, Duration) {
let started = Instant::now();
let mut stream = UnixStream::connect(socket).unwrap();
stream
@@ -87,7 +97,7 @@ fn call(socket: &Path, tool: &str, arguments: &str) -> (ToolResponse, Duration)
tool: tool.to_string(),
arguments: arguments.to_string(),
},
taint: DataClass::Private,
taint,
untrusted: false,
}),
};
@@ -239,3 +249,24 @@ fn without_honcho_recall_answers_as_before() {
lines.lock().unwrap()
);
}
/// Spec 13: a `secret` session's query still reaches Honcho; only a query holding a secret is
/// refused.
#[test]
fn a_secret_session_still_asks_honcho() {
let fake = FakeHoncho::start();
let home = Home::new("recall-serve-secret", Some(&fake.url));
let _lines = home.serve();
let (content, class, untrusted) = result(
call_at(
&home.config.broker_socket(),
"recall",
r#"{"query":"tea","k":10}"#,
DataClass::Secret,
)
.0,
);
assert!(!reads(&fake).is_empty(), "Honcho was not asked: {content}");
assert!(content.contains("tea"), "{content}");
assert_eq!((class, untrusted), (DataClass::Private, true));
}