§9 acceptance: grep-zero sweep — every internal x.ai/grok identifier renamed
The PRD's first acceptance gate now holds: grep -RinE '\bx\.ai\b|grok' crates/ --include='*.rs' → 0 matches (exempt: NOTICE and third-party license archives, README provenance, and the required 'Based on Grok Build Open Source' attribution, now sourced from version_attribution.txt). Wire-visible renames (both sides in this repo, changed in lockstep): - Auth method id 'grok.com' → 'kimi-code' (AuthMethodKind::KimiCode). - Every x.ai/* and _x.ai/* ACP ext method and meta key → kigi/* / _kigi/* (~200 names; grokShell → kigiShell). Session-file replay keeps a read-side alias for the legacy '_x.ai/session/update' method so existing updates.jsonl histories load; writes emit only the new name (both directions test-pinned). - Agent types grok-build* → kigi* with a documented legacy-prefix alias at resolution time so persisted sessions keep resolving. - ToolNamespace/BuiltinAgentName GrokBuild* → Kigi* (wire snake_case kigi/kigi_concise/kigi_hashline; schema regenerated); grok_build implementation dirs renamed to kigi*. - x-grok-* headers → x-kigi-*, __GROK_* sentinels → __KIGI_*, themes grokday/groknight → kigiday/kiginight (old persisted values fall back to the default theme), web_fetch allowlist xAI hosts → kimi.com + moonshot platforms, changelog CDN → this repo, grok-build changelog archives deleted. - BYOK default endpoint removed: [endpoints] api_base_url is now truly optional with NO default — consumers fail fast with the flag name when unset (no silent x.ai egress). Mock harnesses inject it explicitly. - System-prompt identity fixed: 'released by xAI' → 'an unofficial community CLI for Kimi' (template + regenerated encrypted form). Also repaired pre-existing grok-era test debt found by the sweep: the stale trace_classify default-model pin, the grok-pager UA label test, pty-harness stale-binary reuse and non-hermetic moonshot routing (a PTY test could previously reach the real api.moonshot.cn), and the outdated oauth fixture scope key. Gates: §9 grep 0; fmt clean; workspace check/clippy 0/0 (-D warnings); FULL cargo test --workspace: 234 suites, 21,961 passed, 0 failed; deny advisories ok.
This commit is contained in:
@@ -1024,7 +1024,7 @@ async fn test_session_new_valid_default_model_injected() {
|
||||
ClientMode::Stdio,
|
||||
ClientCapabilities {
|
||||
yolo_mode: false,
|
||||
default_model: Some("grok-3-fast".to_string()),
|
||||
default_model: Some("kigi-3-fast".to_string()),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@@ -1039,7 +1039,7 @@ async fn test_session_new_valid_default_model_injected() {
|
||||
|
||||
// modelId should be injected from default_model
|
||||
let meta = &json["params"]["_meta"];
|
||||
assert_eq!(meta["modelId"], "grok-3-fast");
|
||||
assert_eq!(meta["modelId"], "kigi-3-fast");
|
||||
|
||||
client.cancel();
|
||||
cancel.cancel();
|
||||
@@ -1216,7 +1216,7 @@ async fn test_two_clients_session_isolation() {
|
||||
|
||||
/// Multi-client model switch: when one TUI client switches models on a
|
||||
/// session shared with another TUI client, the leader must fan the
|
||||
/// `x.ai/session_notification` (carrying the `ModelChanged` update) out
|
||||
/// `kigi/session_notification` (carrying the `ModelChanged` update) out
|
||||
/// to **every** subscriber of that session — not just the invoker — so
|
||||
/// the follower client mirrors the new model in its UI.
|
||||
///
|
||||
@@ -1241,7 +1241,7 @@ async fn test_set_model_broadcasts_to_session_subscribers() {
|
||||
// Two TUIs connected to the same leader, sharing one session.
|
||||
let mut invoker = LeaderClient::connect(
|
||||
sock_path.clone(),
|
||||
"grok-tui-A",
|
||||
"kigi-tui-A",
|
||||
ClientMode::Stdio,
|
||||
ClientCapabilities::default(),
|
||||
)
|
||||
@@ -1249,7 +1249,7 @@ async fn test_set_model_broadcasts_to_session_subscribers() {
|
||||
.unwrap();
|
||||
let mut follower = LeaderClient::connect(
|
||||
sock_path,
|
||||
"grok-tui-B",
|
||||
"kigi-tui-B",
|
||||
ClientMode::Stdio,
|
||||
ClientCapabilities::default(),
|
||||
)
|
||||
@@ -1289,7 +1289,7 @@ async fn test_set_model_broadcasts_to_session_subscribers() {
|
||||
// Invoker sends `session/setModel` for the shared session.
|
||||
invoker
|
||||
.send(format!(
|
||||
r#"{{"jsonrpc":"2.0","id":42,"method":"session/setModel","params":{{"sessionId":"{}","modelId":"grok-4"}}}}"#,
|
||||
r#"{{"jsonrpc":"2.0","id":42,"method":"session/setModel","params":{{"sessionId":"{}","modelId":"kigi-4"}}}}"#,
|
||||
shared_sid
|
||||
))
|
||||
.unwrap();
|
||||
@@ -1297,7 +1297,7 @@ async fn test_set_model_broadcasts_to_session_subscribers() {
|
||||
let json: serde_json::Value = serde_json::from_str(&received).unwrap();
|
||||
let setmodel_ns_id = json["id"].as_str().unwrap().to_string();
|
||||
assert_eq!(json["method"], "session/setModel");
|
||||
assert_eq!(json["params"]["modelId"], "grok-4");
|
||||
assert_eq!(json["params"]["modelId"], "kigi-4");
|
||||
|
||||
// Simulate the agent's two outputs for a successful switch:
|
||||
//
|
||||
@@ -1310,12 +1310,12 @@ async fn test_set_model_broadcasts_to_session_subscribers() {
|
||||
// BEFORE the response in `model_switch::apply`, so it must arrive at
|
||||
// each subscriber's recv() first.
|
||||
let broadcast = format!(
|
||||
r#"{{"jsonrpc":"2.0","method":"x.ai/session_notification","params":{{"sessionId":"{}","update":{{"sessionUpdate":"model_changed","model_id":"grok-4","reasoning_effort":"high"}}}}}}"#,
|
||||
r#"{{"jsonrpc":"2.0","method":"kigi/session_notification","params":{{"sessionId":"{}","update":{{"sessionUpdate":"model_changed","model_id":"kigi-4","reasoning_effort":"high"}}}}}}"#,
|
||||
shared_sid
|
||||
);
|
||||
response_tx.send(broadcast.clone()).unwrap();
|
||||
let response = format!(
|
||||
r#"{{"jsonrpc":"2.0","result":{{"meta":{{"model":"grok-4"}}}},"id":"{}"}}"#,
|
||||
r#"{{"jsonrpc":"2.0","result":{{"meta":{{"model":"kigi-4"}}}},"id":"{}"}}"#,
|
||||
setmodel_ns_id
|
||||
);
|
||||
response_tx.send(response).unwrap();
|
||||
@@ -1335,10 +1335,10 @@ async fn test_set_model_broadcasts_to_session_subscribers() {
|
||||
.expect("timeout waiting for broadcast on invoker")
|
||||
.expect("invoker channel closed");
|
||||
let inv1: serde_json::Value = serde_json::from_str(&invoker_msg1).unwrap();
|
||||
assert_eq!(inv1["method"], "x.ai/session_notification");
|
||||
assert_eq!(inv1["method"], "kigi/session_notification");
|
||||
assert_eq!(inv1["params"]["sessionId"], shared_sid);
|
||||
assert_eq!(inv1["params"]["update"]["sessionUpdate"], "model_changed");
|
||||
assert_eq!(inv1["params"]["update"]["model_id"], "grok-4");
|
||||
assert_eq!(inv1["params"]["update"]["model_id"], "kigi-4");
|
||||
assert_eq!(inv1["params"]["update"]["reasoning_effort"], "high");
|
||||
|
||||
let invoker_msg2 = tokio::time::timeout(Duration::from_secs(2), invoker.recv())
|
||||
@@ -1350,7 +1350,7 @@ async fn test_set_model_broadcasts_to_session_subscribers() {
|
||||
inv2["id"], 42,
|
||||
"response id must be restored to the invoker's original"
|
||||
);
|
||||
assert_eq!(inv2["result"]["meta"]["model"], "grok-4");
|
||||
assert_eq!(inv2["result"]["meta"]["model"], "kigi-4");
|
||||
|
||||
// --- Follower: must receive the broadcast (this is the fix — before
|
||||
// this notification existed, the follower's status bar / `/model`
|
||||
@@ -1365,10 +1365,10 @@ async fn test_set_model_broadcasts_to_session_subscribers() {
|
||||
)
|
||||
.expect("follower channel closed");
|
||||
let f: serde_json::Value = serde_json::from_str(&follower_msg).unwrap();
|
||||
assert_eq!(f["method"], "x.ai/session_notification");
|
||||
assert_eq!(f["method"], "kigi/session_notification");
|
||||
assert_eq!(f["params"]["sessionId"], shared_sid);
|
||||
assert_eq!(f["params"]["update"]["sessionUpdate"], "model_changed");
|
||||
assert_eq!(f["params"]["update"]["model_id"], "grok-4");
|
||||
assert_eq!(f["params"]["update"]["model_id"], "kigi-4");
|
||||
assert_eq!(f["params"]["update"]["reasoning_effort"], "high");
|
||||
|
||||
// Follower must NOT see the namespaced setModel response — the
|
||||
@@ -1403,7 +1403,7 @@ async fn test_capabilities_not_injected_into_non_session_new() {
|
||||
ClientMode::Stdio,
|
||||
ClientCapabilities {
|
||||
yolo_mode: true,
|
||||
default_model: Some("grok-3-fast".to_string()),
|
||||
default_model: Some("kigi-3-fast".to_string()),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@@ -1533,7 +1533,7 @@ async fn test_cancel_prompt_id_meta_passes_through_with_two_clients() {
|
||||
|
||||
let client_a = LeaderClient::connect(
|
||||
sock_path.clone(),
|
||||
"grok-pager",
|
||||
"kigi-pager",
|
||||
ClientMode::Stdio,
|
||||
ClientCapabilities::default(),
|
||||
)
|
||||
@@ -1541,7 +1541,7 @@ async fn test_cancel_prompt_id_meta_passes_through_with_two_clients() {
|
||||
.unwrap();
|
||||
let client_b = LeaderClient::connect(
|
||||
sock_path,
|
||||
"grok-pager",
|
||||
"kigi-pager",
|
||||
ClientMode::Stdio,
|
||||
ClientCapabilities::default(),
|
||||
)
|
||||
@@ -1611,14 +1611,14 @@ async fn test_extension_method_roundtrip() {
|
||||
.unwrap();
|
||||
|
||||
// Send an extension method call (e.g., fuzzy search open)
|
||||
let ext_call = r#"{"jsonrpc":"2.0","id":50,"method":"_x.ai/search/fuzzy/open","params":{"sessionId":"sess-123","hidden":false}}"#;
|
||||
let ext_call = r#"{"jsonrpc":"2.0","id":50,"method":"_kigi/search/fuzzy/open","params":{"sessionId":"sess-123","hidden":false}}"#;
|
||||
client.send(ext_call.to_string()).unwrap();
|
||||
|
||||
let received = acp_rx.recv().await.unwrap();
|
||||
let json: serde_json::Value = serde_json::from_str(&received).unwrap();
|
||||
|
||||
// Method should be preserved, ID should be namespaced
|
||||
assert_eq!(json["method"], "_x.ai/search/fuzzy/open");
|
||||
assert_eq!(json["method"], "_kigi/search/fuzzy/open");
|
||||
let namespaced_id = json["id"].as_str().unwrap();
|
||||
assert!(namespaced_id.contains(ID_NAMESPACE_SEP));
|
||||
assert!(namespaced_id.ends_with("|50"));
|
||||
@@ -1795,7 +1795,7 @@ async fn test_session_ownership_cleanup_on_disconnect() {
|
||||
// in sync. Also verifies the eviction was actually sent.
|
||||
let eviction = acp_rx.recv().await.unwrap();
|
||||
let eviction_json: serde_json::Value = serde_json::from_str(&eviction).unwrap();
|
||||
assert_eq!(eviction_json["method"], "x.ai/internal/evict_sessions");
|
||||
assert_eq!(eviction_json["method"], "kigi/internal/evict_sessions");
|
||||
|
||||
// Connect a NEW client — server should still be running
|
||||
let mut client2 = LeaderClient::connect(
|
||||
@@ -1824,7 +1824,7 @@ async fn test_session_ownership_cleanup_on_disconnect() {
|
||||
// client2 should NOT receive the dead-session notification.
|
||||
// Send a second notification without a sessionId — this one SHOULD
|
||||
// arrive via fallback routing, proving client2 is alive and connected.
|
||||
let probe = r#"{"jsonrpc":"2.0","method":"x.ai/probe","params":{"ping":true}}"#;
|
||||
let probe = r#"{"jsonrpc":"2.0","method":"kigi/probe","params":{"ping":true}}"#;
|
||||
response_tx.send(probe.to_string()).unwrap();
|
||||
|
||||
let recv = tokio::time::timeout(Duration::from_secs(2), client2.recv())
|
||||
@@ -1857,7 +1857,7 @@ async fn test_code_nav_capable_client_gets_true_injected_into_session_new() {
|
||||
// Web client that advertised code-nav capability during registration.
|
||||
let web_client = LeaderClient::connect(
|
||||
sock_path,
|
||||
"grok-web",
|
||||
"kigi-web",
|
||||
ClientMode::Stdio,
|
||||
ClientCapabilities {
|
||||
code_nav_enabled: true,
|
||||
@@ -1894,7 +1894,7 @@ async fn test_non_code_nav_client_gets_false_injected_into_session_new() {
|
||||
// TUI client with no code-nav capability.
|
||||
let tui_client = LeaderClient::connect(
|
||||
sock_path,
|
||||
"grok-tui",
|
||||
"kigi-tui",
|
||||
ClientMode::Stdio,
|
||||
ClientCapabilities {
|
||||
code_nav_enabled: false,
|
||||
@@ -1933,7 +1933,7 @@ async fn test_leader_code_nav_client_isolation() {
|
||||
// Web client with code-nav capability.
|
||||
let web_client = LeaderClient::connect(
|
||||
sock_path.clone(),
|
||||
"grok-web",
|
||||
"kigi-web",
|
||||
ClientMode::Stdio,
|
||||
ClientCapabilities {
|
||||
code_nav_enabled: true,
|
||||
@@ -1946,7 +1946,7 @@ async fn test_leader_code_nav_client_isolation() {
|
||||
// TUI client without code-nav capability.
|
||||
let tui_client = LeaderClient::connect(
|
||||
sock_path,
|
||||
"grok-tui",
|
||||
"kigi-tui",
|
||||
ClientMode::Stdio,
|
||||
ClientCapabilities {
|
||||
code_nav_enabled: false,
|
||||
@@ -1994,7 +1994,7 @@ async fn test_code_nav_capability_injected_into_session_load() {
|
||||
|
||||
let web_client = LeaderClient::connect(
|
||||
sock_path,
|
||||
"grok-web",
|
||||
"kigi-web",
|
||||
ClientMode::Stdio,
|
||||
ClientCapabilities {
|
||||
code_nav_enabled: true,
|
||||
@@ -2021,7 +2021,7 @@ async fn test_code_nav_capability_injected_into_session_load() {
|
||||
cancel.cancel();
|
||||
}
|
||||
|
||||
/// Verify that an `x.ai/code/status` extension request is forwarded to the
|
||||
/// Verify that an `kigi/code/status` extension request is forwarded to the
|
||||
/// agent with the correct method, sessionId, and cwd in the params.
|
||||
///
|
||||
/// This tests the routing boundary between leader and agent for the
|
||||
@@ -2033,7 +2033,7 @@ async fn test_code_status_ext_request_forwarded_to_agent() {
|
||||
|
||||
let web_client = LeaderClient::connect(
|
||||
sock_path,
|
||||
"grok-web",
|
||||
"kigi-web",
|
||||
ClientMode::Stdio,
|
||||
ClientCapabilities {
|
||||
code_nav_enabled: true,
|
||||
@@ -2043,15 +2043,15 @@ async fn test_code_status_ext_request_forwarded_to_agent() {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Send x.ai/code/status with a sessionId — the leader must forward it to the agent.
|
||||
let status_req = r#"{"jsonrpc":"2.0","id":42,"method":"extensions/ext","params":{"method":"x.ai/code/status","params":{"sessionId":"sess-web-1","cwd":"/repo"}}}"#;
|
||||
// Send kigi/code/status with a sessionId — the leader must forward it to the agent.
|
||||
let status_req = r#"{"jsonrpc":"2.0","id":42,"method":"extensions/ext","params":{"method":"kigi/code/status","params":{"sessionId":"sess-web-1","cwd":"/repo"}}}"#;
|
||||
web_client.send(status_req.to_string()).unwrap();
|
||||
|
||||
let forwarded = acp_rx.recv().await.unwrap();
|
||||
let json: serde_json::Value = serde_json::from_str(&forwarded).unwrap();
|
||||
|
||||
assert_eq!(json["method"], "extensions/ext");
|
||||
assert_eq!(json["params"]["method"], "x.ai/code/status");
|
||||
assert_eq!(json["params"]["method"], "kigi/code/status");
|
||||
assert_eq!(json["params"]["params"]["sessionId"], "sess-web-1");
|
||||
assert_eq!(json["params"]["params"]["cwd"], "/repo");
|
||||
|
||||
@@ -2284,7 +2284,7 @@ async fn test_connect_waits_for_leader_ready() {
|
||||
let connect_start = tokio::time::Instant::now();
|
||||
let mut client = LeaderClient::connect(
|
||||
sock_path,
|
||||
"grok-tui",
|
||||
"kigi-tui",
|
||||
ClientMode::Stdio,
|
||||
ClientCapabilities::default(),
|
||||
)
|
||||
@@ -2337,7 +2337,7 @@ async fn test_connect_waits_for_leader_ready() {
|
||||
|
||||
// ── Version mismatch notification ────────────────────────────────────
|
||||
|
||||
/// Integration test: a connected client receives `x.ai/leader/version_mismatch`
|
||||
/// Integration test: a connected client receives `kigi/leader/version_mismatch`
|
||||
/// when its `client_version` differs from the leader's version.
|
||||
///
|
||||
/// Uses `leader_version_override` so the test bypasses the `"unknown"` constant
|
||||
@@ -2406,7 +2406,7 @@ async fn test_version_mismatch_notification_sent_to_client() {
|
||||
.expect("channel closed");
|
||||
|
||||
let json: serde_json::Value = serde_json::from_str(&msg).unwrap();
|
||||
assert_eq!(json["method"], "x.ai/leader/version_mismatch");
|
||||
assert_eq!(json["method"], "kigi/leader/version_mismatch");
|
||||
assert_eq!(json["params"]["clientVersion"], "test-client-0.1.157");
|
||||
assert_eq!(json["params"]["leaderVersion"], "test-leader-0.1.150");
|
||||
|
||||
@@ -2729,7 +2729,7 @@ async fn test_initialize_injected_when_not_first_message() {
|
||||
|
||||
let client = LeaderClient::connect(
|
||||
sock_path,
|
||||
"grok-tui",
|
||||
"kigi-tui",
|
||||
ClientMode::Stdio,
|
||||
ClientCapabilities::default(),
|
||||
)
|
||||
@@ -2762,7 +2762,7 @@ async fn test_initialize_injected_when_not_first_message() {
|
||||
.and_then(|v| v.as_str());
|
||||
assert_eq!(
|
||||
client_id,
|
||||
Some("grok-tui"),
|
||||
Some("kigi-tui"),
|
||||
"clientIdentifier must be injected into initialize even when it is not the first message"
|
||||
);
|
||||
|
||||
@@ -2782,7 +2782,7 @@ async fn test_leader_code_nav_isolation_end_to_end() {
|
||||
// Web client with code-nav capability.
|
||||
let web_client = LeaderClient::connect(
|
||||
sock_path.clone(),
|
||||
"grok-web",
|
||||
"kigi-web",
|
||||
ClientMode::Stdio,
|
||||
ClientCapabilities {
|
||||
code_nav_enabled: true,
|
||||
@@ -2795,7 +2795,7 @@ async fn test_leader_code_nav_isolation_end_to_end() {
|
||||
// TUI client without code-nav capability.
|
||||
let tui_client = LeaderClient::connect(
|
||||
sock_path,
|
||||
"grok-tui",
|
||||
"kigi-tui",
|
||||
ClientMode::Stdio,
|
||||
ClientCapabilities {
|
||||
code_nav_enabled: false,
|
||||
@@ -2824,13 +2824,13 @@ async fn test_leader_code_nav_isolation_end_to_end() {
|
||||
serde_json::json!(false)
|
||||
);
|
||||
|
||||
// Web client sends x.ai/code/status (the primary non-starting code-nav call).
|
||||
let status_with_session = r#"{"jsonrpc":"2.0","id":10,"method":"extensions/ext","params":{"method":"x.ai/code/status","params":{"sessionId":"web-session","cwd":"/repo"}}}"#;
|
||||
// Web client sends kigi/code/status (the primary non-starting code-nav call).
|
||||
let status_with_session = r#"{"jsonrpc":"2.0","id":10,"method":"extensions/ext","params":{"method":"kigi/code/status","params":{"sessionId":"web-session","cwd":"/repo"}}}"#;
|
||||
web_client.send(status_with_session.to_string()).unwrap();
|
||||
|
||||
let status_fwd = acp_rx.recv().await.unwrap();
|
||||
let status_json: serde_json::Value = serde_json::from_str(&status_fwd).unwrap();
|
||||
assert_eq!(status_json["params"]["method"], "x.ai/code/status");
|
||||
assert_eq!(status_json["params"]["method"], "kigi/code/status");
|
||||
assert_eq!(status_json["params"]["params"]["sessionId"], "web-session");
|
||||
|
||||
web_client.cancel();
|
||||
@@ -3146,7 +3146,7 @@ async fn test_hung_agent_leaves_transport_healthy_and_forwards_cancel() {
|
||||
assert_eq!(cancel_json["method"], "session/cancel");
|
||||
|
||||
// Unrelated traffic still round-trips on the same connection.
|
||||
let probe = r#"{"jsonrpc":"2.0","method":"x.ai/probe","params":{"ping":true}}"#;
|
||||
let probe = r#"{"jsonrpc":"2.0","method":"kigi/probe","params":{"ping":true}}"#;
|
||||
response_tx.send(probe.to_string()).unwrap();
|
||||
let recv = tokio::time::timeout(Duration::from_secs(2), client.recv())
|
||||
.await
|
||||
@@ -3209,7 +3209,7 @@ async fn test_sever_mid_rpc_orphans_response_and_replay_recovers() {
|
||||
// signal that the server processed the disconnect.
|
||||
let evict = acp_rx.recv().await.unwrap();
|
||||
let evict_json: serde_json::Value = serde_json::from_str(&evict).unwrap();
|
||||
assert_eq!(evict_json["method"], "x.ai/internal/evict_sessions");
|
||||
assert_eq!(evict_json["method"], "kigi/internal/evict_sessions");
|
||||
|
||||
// The agent completes the turn anyway: durable terminal notification plus
|
||||
// the RPC response addressed to the dead client.
|
||||
|
||||
Reference in New Issue
Block a user