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:
@@ -60,6 +60,16 @@ impl Home {
|
|||||||
|
|
||||||
/// One call on `brokerd`'s socket and its answer, within 20 s; how long it took.
|
/// 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) {
|
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 started = Instant::now();
|
||||||
let mut stream = UnixStream::connect(socket).unwrap();
|
let mut stream = UnixStream::connect(socket).unwrap();
|
||||||
stream
|
stream
|
||||||
@@ -76,7 +86,7 @@ fn call(socket: &Path, tool: &str, arguments: &str) -> (ToolResponse, Duration)
|
|||||||
tool: tool.to_string(),
|
tool: tool.to_string(),
|
||||||
arguments: arguments.to_string(),
|
arguments: arguments.to_string(),
|
||||||
},
|
},
|
||||||
taint: DataClass::Private,
|
taint,
|
||||||
untrusted: false,
|
untrusted: false,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
@@ -230,3 +240,29 @@ fn an_unknown_tool_is_refused() {
|
|||||||
"memoryd runs only recall, memory and ask_memory"
|
"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));
|
||||||
|
}
|
||||||
|
|||||||
@@ -71,6 +71,16 @@ impl Home {
|
|||||||
|
|
||||||
/// One call on `brokerd`'s socket and its answer, within 20 s; how long it took.
|
/// 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) {
|
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 started = Instant::now();
|
||||||
let mut stream = UnixStream::connect(socket).unwrap();
|
let mut stream = UnixStream::connect(socket).unwrap();
|
||||||
stream
|
stream
|
||||||
@@ -87,7 +97,7 @@ fn call(socket: &Path, tool: &str, arguments: &str) -> (ToolResponse, Duration)
|
|||||||
tool: tool.to_string(),
|
tool: tool.to_string(),
|
||||||
arguments: arguments.to_string(),
|
arguments: arguments.to_string(),
|
||||||
},
|
},
|
||||||
taint: DataClass::Private,
|
taint,
|
||||||
untrusted: false,
|
untrusted: false,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
@@ -239,3 +249,24 @@ fn without_honcho_recall_answers_as_before() {
|
|||||||
lines.lock().unwrap()
|
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));
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user