diff --git a/crates/cli/tests/agent_target.rs b/crates/cli/tests/agent_target.rs
index c59ae02c0..5a9cc7b43 100644
--- a/crates/cli/tests/agent_target.rs
+++ b/crates/cli/tests/agent_target.rs
@@ -687,3 +687,221 @@ fn agent_target_result_is_honored_only_from_the_lease_holder() {
assert_eq!(verdict["sessionId"], serde_json::json!("aabbccdd"), "{verdict}");
let _ = &mut b;
}
+
+/// The generate verb as the agent runs it, against this helper's dir.
+fn spawn_cli(s: &Server, args: &[&str]) -> std::process::Child {
+ std::process::Command::new(env!("CARGO_BIN_EXE_impeccable"))
+ .args(args)
+ .current_dir(&s.dir)
+ .env("IMPECCABLE_LIVE_COPY_AGENT", "off")
+ .stdout(std::process::Stdio::piped())
+ .stderr(std::process::Stdio::piped())
+ .spawn()
+ .expect("spawn cli")
+}
+
+fn cli_json(child: std::process::Child) -> (i32, serde_json::Value, String) {
+ let out = child.wait_with_output().expect("cli output");
+ let stdout = String::from_utf8_lossy(&out.stdout).into_owned();
+ let stderr = String::from_utf8_lossy(&out.stderr).into_owned();
+ // live-generate prints one pretty object; live-poll prints one line.
+ let v: serde_json::Value = serde_json::from_str(stdout.trim())
+ .or_else(|_| serde_json::from_str(stdout.trim().lines().last().unwrap_or("")))
+ .unwrap_or_else(|e| panic!("{e}\nstdout: {stdout}\nstderr: {stderr}"));
+ (out.status.code().unwrap_or(-1), v, stderr)
+}
+
+#[test]
+fn live_generate_collects_its_own_generate_event_and_reply_then_poll_returns_the_next_one() {
+ let s = Server::start("collect");
+ let mut a = Overlay::connect(s.port, &s.token, "tab-a");
+ a.next(|m| m["type"] == "connected");
+ let child = spawn_cli(&s, &["live-generate", "--selector", "h1", "--action", "bolder", "--count", "3"]);
+ let target_id = a.next(|m| m["type"] == "agent_target")["targetId"].as_str().unwrap().to_string();
+ assert_eq!(s.claim(&target_id, "tab-a", true)["granted"], serde_json::json!(true));
+ let (status, ack) = post_json(s.port, "/events", generate_event_for(&s, &target_id, "c0ffee11", "tab-a"));
+ assert_eq!(status, 200, "{ack}");
+ let (code, verdict, stderr) = cli_json(child);
+ assert_eq!(code, 0, "{verdict}\n{stderr}");
+ assert_eq!(verdict["ok"], serde_json::json!(true), "{verdict}");
+ assert_eq!(verdict["sessionId"], serde_json::json!("c0ffee11"));
+ // B: the session's generate event rides along, leased, with the fast path.
+ assert_eq!(verdict["event"]["type"], serde_json::json!("generate"), "{verdict}");
+ assert_eq!(verdict["event"]["id"], serde_json::json!("c0ffee11"));
+ assert_eq!(verdict["event"]["origin"], serde_json::json!("agent"));
+ assert!(verdict["event"]["_instructions"].as_str().unwrap().contains("Fast path"), "{verdict}");
+ assert!(verdict["_instructions"].as_str().unwrap().contains("--reply c0ffee11 done --file t
").unwrap();
+ std::fs::write(dir.join(".impeccable/live/config.json"), "{\"files\":[\"index.html\"],\"insertBefore\":\"