§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:
2026-07-18 02:48:46 -04:00
parent 86e3724310
commit 6f31415ed6
1056 changed files with 8410 additions and 18307 deletions
@@ -778,7 +778,7 @@ fn collect_diff_stats(
}
DiffStatsResult { stats, paths }
}
/// Payload for the `x.ai/git_head_changed` ACP extension notification.
/// Payload for the `kigi/git_head_changed` ACP extension notification.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct GitHeadChanged {
@@ -1790,7 +1790,7 @@ pub async fn stash_before_destructive_op(
return StashOutcome::Skipped(reason);
}
let message = format!(
"grok: pre-{label} {} {}",
"kigi: pre-{label} {} {}",
session_id,
chrono::Utc::now().format("%Y-%m-%dT%H:%M:%SZ")
);
@@ -1908,7 +1908,7 @@ pub async fn checkout_session_commit(
/// The restore-code path runs `git fetch origin` + `git checkout <sha>`,
/// which *detaches HEAD*. That is only acceptable in two situations:
///
/// 1. `supplied_cwd` is a grok-managed worktree (`~/.kigi/worktrees/...`).
/// 1. `supplied_cwd` is a kigi-managed worktree (`~/.kigi/worktrees/...`).
/// These are disposable snapshots that exist precisely to carry a
/// detached session HEAD.
/// 2. `supplied_cwd` is exactly the cwd the session was persisted with
@@ -3522,7 +3522,7 @@ mod restore_code_tests {
assert!(porcelain.trim().is_empty(), "got: {porcelain:?}");
let list = git_cli(tmp.path(), &["stash", "list"]).await.unwrap();
assert!(
list.contains("grok: pre-test sess-2"),
list.contains("kigi: pre-test sess-2"),
"stash list missing session id: {list}"
);
}
@@ -448,7 +448,7 @@ pub struct WorkspaceShared {
/// `discovery` module.
pub(crate) plugin_discovery_config: crate::discovery::PluginDiscoveryConfig,
/// Sink for workspace-originated ext-notifications to the client (e.g.
/// `x.ai/search/fuzzy/status`). Mode-agnostic: the shell wires it to the
/// `kigi/search/fuzzy/status`). Mode-agnostic: the shell wires it to the
/// agent gateway in local mode, and to the server in proxy mode. `None` until
/// set via [`WorkspaceHandle::set_client_ext_sink`](crate::handle::WorkspaceHandle::set_client_ext_sink).
pub(crate) client_ext_sink: arc_swap::ArcSwap<Option<ClientExtSink>>,
@@ -13,7 +13,7 @@ use crate::session::WorkspaceSession;
pub(crate) static WORKSPACE_TOOLSET_SWAP_TOTAL: std::sync::LazyLock<IntCounterVec> =
std::sync::LazyLock::new(|| {
register_int_counter_vec!(
"grok_workspace_toolset_swap_total",
"kigi_workspace_toolset_swap_total",
"Session toolset installs and swaps, by trigger and guard state",
&["trigger", "turn_active", "in_flight"]
)
@@ -26,7 +26,7 @@ pub(crate) static WORKSPACE_TOOLSET_SWAP_TOTAL: std::sync::LazyLock<IntCounterVe
pub(crate) static WORKSPACE_TOOLSET_SWAP_REJECTED_TOTAL: std::sync::LazyLock<IntCounterVec> =
std::sync::LazyLock::new(|| {
register_int_counter_vec!(
"grok_workspace_toolset_swap_rejected_total",
"kigi_workspace_toolset_swap_rejected_total",
"Session toolset swaps rejected by the turn-safety guards, by reason and trigger",
&["reason", "trigger"]
)
@@ -39,7 +39,7 @@ pub(crate) static WORKSPACE_TOOLSET_SWAP_REJECTED_TOTAL: std::sync::LazyLock<Int
static WORKSPACE_BIND_REBIND_RERESOLVE_TOTAL: std::sync::LazyLock<IntCounterVec> =
std::sync::LazyLock::new(|| {
register_int_counter_vec!(
"grok_workspace_bind_rebind_reresolve_total",
"kigi_workspace_bind_rebind_reresolve_total",
"session.bind rebinds that re-resolved a changed explicit toolset, by result",
&["result"]
)
@@ -295,7 +295,7 @@ impl SessionContextFactory for WorkspaceSessionContextFactory {
web_fetch_config: build_web_fetch_config(),
lsp: None,
app_builder_deployer_config:
kigi_tools::implementations::grok_build::deploy_app::AppBuilderDeployerConfig::default(),
kigi_tools::implementations::kigi::deploy_app::AppBuilderDeployerConfig::default(),
api_key_provider: None,
attribution_callback: None,
system_reminder_tag: kigi_tools::reminders::DEFAULT_REMINDER_TAG,
@@ -317,8 +317,8 @@ impl SessionContextFactory for WorkspaceSessionContextFactory {
}
/// Build web fetch config. Enabled with default params unless
/// `KIGI_DISABLE_WEB_FETCH=1` is set.
fn build_web_fetch_config() -> kigi_tools::implementations::grok_build::web_fetch::WebFetchConfig {
use kigi_tools::implementations::grok_build::web_fetch::{WebFetchConfig, WebFetchParams};
fn build_web_fetch_config() -> kigi_tools::implementations::kigi::web_fetch::WebFetchConfig {
use kigi_tools::implementations::kigi::web_fetch::{WebFetchConfig, WebFetchParams};
if std::env::var("KIGI_DISABLE_WEB_FETCH").is_ok_and(|v| v == "1" || v == "true") {
return WebFetchConfig::Disabled;
}
@@ -414,10 +414,10 @@ pub mod test_support {
pub fn baseline_config() -> ToolServerConfig {
ToolServerConfig {
tools: vec![
tc("GrokBuild:read_file", Some(ToolKind::Read)),
tc("GrokBuild:search_replace", Some(ToolKind::Edit)),
tc("GrokBuild:grep", Some(ToolKind::Search)),
tc("GrokBuild:list_dir", Some(ToolKind::ListDir)),
tc("Kigi:read_file", Some(ToolKind::Read)),
tc("Kigi:search_replace", Some(ToolKind::Edit)),
tc("Kigi:grep", Some(ToolKind::Search)),
tc("Kigi:list_dir", Some(ToolKind::ListDir)),
],
behavior_preset: None,
}
@@ -470,13 +470,10 @@ mod tests {
async fn resolve_session_toolset_mcp_merge_dedup_by_id_baseline_wins() {
let factory = factory_for_test();
let baseline = ToolServerConfig {
tools: vec![test_support::tc(
"GrokBuild:read_file",
Some(ToolKind::Read),
)],
tools: vec![test_support::tc("Kigi:read_file", Some(ToolKind::Read))],
behavior_preset: None,
};
let mut mcp_dup = test_support::tc("GrokBuild:read_file", Some(ToolKind::Read));
let mut mcp_dup = test_support::tc("Kigi:read_file", Some(ToolKind::Read));
mcp_dup.name_override = Some("mcp_read".into());
let snapshot = vec![mcp_dup];
let (_eff, ts, _backend) = resolve_session_toolset(
@@ -507,14 +504,14 @@ mod tests {
#[test]
fn backfill_tool_kinds_fills_known_kindless_ids_only() {
let kinds = HashMap::from([
("GrokBuild:search_replace".to_owned(), ToolKind::Edit),
("GrokBuild:read_file".to_owned(), ToolKind::Read),
("Kigi:search_replace".to_owned(), ToolKind::Edit),
("Kigi:read_file".to_owned(), ToolKind::Read),
]);
let config = ToolServerConfig {
tools: vec![
test_support::tc("GrokBuild:search_replace", None),
test_support::tc("Kigi:search_replace", None),
test_support::tc("adhoc.opaque", None),
test_support::tc("GrokBuild:read_file", Some(ToolKind::Search)),
test_support::tc("Kigi:read_file", Some(ToolKind::Search)),
],
behavior_preset: Some("current".to_owned()),
};
@@ -527,14 +524,14 @@ mod tests {
.expect("tool present")
.kind
};
assert_eq!(kind_of("GrokBuild:search_replace"), Some(ToolKind::Edit));
assert_eq!(kind_of("Kigi:search_replace"), Some(ToolKind::Edit));
assert_eq!(
kind_of("adhoc.opaque"),
None,
"ids unknown to the registry stay kind-less"
);
assert_eq!(
kind_of("GrokBuild:read_file"),
kind_of("Kigi:read_file"),
Some(ToolKind::Search),
"an explicit kind wins over the registry's"
);
@@ -550,11 +547,11 @@ mod tests {
let factory = factory_for_test();
let baseline = ToolServerConfig {
tools: vec![
test_support::tc("GrokBuild:read_file", None),
test_support::tc("GrokBuild:grep", None),
test_support::tc("GrokBuild:list_dir", None),
test_support::tc("GrokBuild:search_replace", None),
test_support::tc("GrokBuild:run_terminal_cmd", None),
test_support::tc("Kigi:read_file", None),
test_support::tc("Kigi:grep", None),
test_support::tc("Kigi:list_dir", None),
test_support::tc("Kigi:search_replace", None),
test_support::tc("Kigi:run_terminal_cmd", None),
],
behavior_preset: None,
};
@@ -594,10 +591,7 @@ mod tests {
#[test]
fn resolve_session_toolset_mcp_edit_dropped_under_readonly() {
let baseline = ToolServerConfig {
tools: vec![test_support::tc(
"GrokBuild:read_file",
Some(ToolKind::Read),
)],
tools: vec![test_support::tc("Kigi:read_file", Some(ToolKind::Read))],
behavior_preset: None,
};
let mcp_edit = test_support::tc("mcp.editor", Some(ToolKind::Edit));
@@ -609,7 +603,7 @@ mod tests {
let factory = factory_for_test();
let baseline = ToolServerConfig {
tools: vec![
test_support::tc("GrokBuild:read_file", Some(ToolKind::Read)),
test_support::tc("Kigi:read_file", Some(ToolKind::Read)),
test_support::tc("baseline.opaque", None),
],
behavior_preset: None,
@@ -626,7 +620,7 @@ mod tests {
"MCP kind: None MUST be dropped under ReadOnly: {kept_ids:?}"
);
assert!(
kept_ids.contains(&"GrokBuild:read_file"),
kept_ids.contains(&"Kigi:read_file"),
"baseline Read kind must survive ReadOnly: {kept_ids:?}"
);
let _ = factory;