§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
@@ -89,7 +89,7 @@ impl TitleManager {
if !has_parts {
self.composed.clear();
self.composed.push_str("grok");
self.composed.push_str("kigi");
}
let result = if self.composed != self.last_title {
@@ -113,9 +113,9 @@ impl TitleManager {
}
pub fn reset(&mut self) -> String {
let esc = build_title_escape("grok");
let esc = build_title_escape("kigi");
self.last_title.clear();
self.last_title.push_str("grok");
self.last_title.push_str("kigi");
self.spinner_frame = 0;
self.tick_count = 0;
esc
@@ -132,9 +132,9 @@ fn write_item(
tick_count: u64,
) -> bool {
match item {
TitleItem::Grok => {
TitleItem::Kigi => {
push_separator(buf, has_parts);
buf.push_str("grok");
buf.push_str("kigi");
}
TitleItem::Spinner => {
if !state.is_busy && state.activity.is_none() {
@@ -267,7 +267,7 @@ fn write_truncated(buf: &mut String, s: &str, max: usize) {
/// the frame pipeline.
///
/// Control characters are stripped here: title parts include remote-sourced
/// strings (e.g. grok.com conversation titles), which must not terminate the
/// strings (e.g. kimi.com conversation titles), which must not terminate the
/// OSC sequence early or inject escapes into the terminal.
fn build_title_escape(title: &str) -> String {
let sanitized: String = title.chars().filter(|c| !c.is_control()).collect();
@@ -307,55 +307,55 @@ mod tests {
// --- Title composition tests ---
#[test]
fn grok_only_produces_just_grok() {
let cfg = config_with_items(vec![TitleItem::Grok]);
fn kigi_only_produces_just_kigi() {
let cfg = config_with_items(vec![TitleItem::Kigi]);
let mut mgr = TitleManager::new(&cfg);
let state = idle_state();
mgr.update(&state);
assert_eq!(mgr.last_title, "grok");
assert_eq!(mgr.last_title, "kigi");
}
#[test]
fn session_name_and_grok_joined_with_separator() {
let cfg = config_with_items(vec![TitleItem::SessionName, TitleItem::Grok]);
fn session_name_and_kigi_joined_with_separator() {
let cfg = config_with_items(vec![TitleItem::SessionName, TitleItem::Kigi]);
let mut mgr = TitleManager::new(&cfg);
let state = TitleState {
session_name: Some("my project"),
..idle_state()
};
mgr.update(&state);
assert_eq!(mgr.last_title, "my project - grok");
assert_eq!(mgr.last_title, "my project - kigi");
}
#[test]
fn missing_session_name_skipped() {
let cfg = config_with_items(vec![TitleItem::SessionName, TitleItem::Grok]);
let cfg = config_with_items(vec![TitleItem::SessionName, TitleItem::Kigi]);
let mut mgr = TitleManager::new(&cfg);
let state = idle_state();
mgr.update(&state);
assert_eq!(mgr.last_title, "grok");
assert_eq!(mgr.last_title, "kigi");
}
#[test]
fn empty_session_name_skipped() {
let cfg = config_with_items(vec![TitleItem::SessionName, TitleItem::Grok]);
let cfg = config_with_items(vec![TitleItem::SessionName, TitleItem::Kigi]);
let mut mgr = TitleManager::new(&cfg);
let state = TitleState {
session_name: Some(""),
..idle_state()
};
mgr.update(&state);
assert_eq!(mgr.last_title, "grok");
assert_eq!(mgr.last_title, "kigi");
}
#[test]
fn spinner_only_shown_when_active() {
let cfg = config_with_items(vec![TitleItem::Spinner, TitleItem::Grok]);
let cfg = config_with_items(vec![TitleItem::Spinner, TitleItem::Kigi]);
let mut mgr = TitleManager::new(&cfg);
// Idle: spinner absent
mgr.update(&idle_state());
assert_eq!(mgr.last_title, "grok");
assert_eq!(mgr.last_title, "kigi");
// Active: spinner present
let activity = TurnActivity::Thinking;
@@ -364,7 +364,7 @@ mod tests {
..idle_state()
};
mgr.update(&state);
assert!(mgr.last_title.contains(" - grok"));
assert!(mgr.last_title.contains(" - kigi"));
let spinner_part: String = mgr.last_title.chars().take(1).collect();
assert!(
TITLE_SPINNER.contains(&spinner_part.chars().next().unwrap()),
@@ -522,22 +522,22 @@ mod tests {
#[test]
fn activity_hidden_when_idle() {
let cfg = config_with_items(vec![TitleItem::Activity, TitleItem::Grok]);
let cfg = config_with_items(vec![TitleItem::Activity, TitleItem::Kigi]);
let mut mgr = TitleManager::new(&cfg);
mgr.update(&idle_state());
assert_eq!(mgr.last_title, "grok");
assert_eq!(mgr.last_title, "kigi");
}
#[test]
fn spinner_shown_when_busy_without_activity() {
let cfg = config_with_items(vec![TitleItem::Spinner, TitleItem::Grok]);
let cfg = config_with_items(vec![TitleItem::Spinner, TitleItem::Kigi]);
let mut mgr = TitleManager::new(&cfg);
let state = TitleState {
is_busy: true,
..idle_state()
};
mgr.update(&state);
assert!(mgr.last_title.contains(" - grok"));
assert!(mgr.last_title.contains(" - kigi"));
let spinner_part: String = mgr.last_title.chars().take(1).collect();
assert!(
TITLE_SPINNER.contains(&spinner_part.chars().next().unwrap()),
@@ -548,19 +548,19 @@ mod tests {
#[test]
fn activity_shows_waiting_when_busy_without_activity() {
let cfg = config_with_items(vec![TitleItem::Activity, TitleItem::Grok]);
let cfg = config_with_items(vec![TitleItem::Activity, TitleItem::Kigi]);
let mut mgr = TitleManager::new(&cfg);
let state = TitleState {
is_busy: true,
..idle_state()
};
mgr.update(&state);
assert_eq!(mgr.last_title, "Waiting - grok");
assert_eq!(mgr.last_title, "Waiting - kigi");
}
#[test]
fn activity_prefers_specific_activity_over_waiting() {
let cfg = config_with_items(vec![TitleItem::Activity, TitleItem::Grok]);
let cfg = config_with_items(vec![TitleItem::Activity, TitleItem::Kigi]);
let mut mgr = TitleManager::new(&cfg);
let activity = TurnActivity::Thinking;
let state = TitleState {
@@ -569,14 +569,14 @@ mod tests {
..idle_state()
};
mgr.update(&state);
assert_eq!(mgr.last_title, "Thinking - grok");
assert_eq!(mgr.last_title, "Thinking - kigi");
}
// --- Action Required blinking ---
#[test]
fn action_required_visible_on_first_tick() {
let cfg = config_with_items(vec![TitleItem::ActionRequired, TitleItem::Grok]);
let cfg = config_with_items(vec![TitleItem::ActionRequired, TitleItem::Kigi]);
let mut mgr = TitleManager::new(&cfg);
let state = TitleState {
has_pending_permissions: true,
@@ -594,7 +594,7 @@ mod tests {
#[test]
fn action_required_blinks_across_ticks() {
let cfg = config_with_items(vec![TitleItem::ActionRequired, TitleItem::Grok]);
let cfg = config_with_items(vec![TitleItem::ActionRequired, TitleItem::Kigi]);
let mut mgr = TitleManager::new(&cfg);
let state = TitleState {
has_pending_permissions: true,
@@ -626,28 +626,28 @@ mod tests {
#[test]
fn action_required_hidden_when_no_permissions() {
let cfg = config_with_items(vec![TitleItem::ActionRequired, TitleItem::Grok]);
let cfg = config_with_items(vec![TitleItem::ActionRequired, TitleItem::Kigi]);
let mut mgr = TitleManager::new(&cfg);
let state = TitleState {
has_pending_permissions: false,
..idle_state()
};
mgr.update(&state);
assert_eq!(mgr.last_title, "grok");
assert_eq!(mgr.last_title, "kigi");
mgr.update(&state);
assert_eq!(mgr.last_title, "grok");
assert_eq!(mgr.last_title, "kigi");
}
// --- Dedup (no-op when unchanged) ---
#[test]
fn dedup_skips_emission_when_unchanged() {
let cfg = config_with_items(vec![TitleItem::Grok]);
let cfg = config_with_items(vec![TitleItem::Kigi]);
let mut mgr = TitleManager::new(&cfg);
let state = idle_state();
mgr.update(&state);
assert_eq!(mgr.last_title, "grok");
assert_eq!(mgr.last_title, "kigi");
// Second update: title is identical, last_title stays the same (no re-emit).
let title_before = mgr.last_title.clone();
@@ -658,73 +658,73 @@ mod tests {
// --- Empty items list ---
#[test]
fn empty_items_produces_grok_fallback() {
fn empty_items_produces_kigi_fallback() {
let cfg = config_with_items(vec![]);
let mut mgr = TitleManager::new(&cfg);
mgr.update(&idle_state());
assert_eq!(mgr.last_title, "grok");
assert_eq!(mgr.last_title, "kigi");
}
// --- Model item ---
#[test]
fn model_item_shown_when_present() {
let cfg = config_with_items(vec![TitleItem::Model, TitleItem::Grok]);
let cfg = config_with_items(vec![TitleItem::Model, TitleItem::Kigi]);
let mut mgr = TitleManager::new(&cfg);
let state = TitleState {
model: Some("grok-3"),
model: Some("kigi-3"),
..idle_state()
};
mgr.update(&state);
assert_eq!(mgr.last_title, "grok-3 - grok");
assert_eq!(mgr.last_title, "kigi-3 - kigi");
}
#[test]
fn model_item_hidden_when_none() {
let cfg = config_with_items(vec![TitleItem::Model, TitleItem::Grok]);
let cfg = config_with_items(vec![TitleItem::Model, TitleItem::Kigi]);
let mut mgr = TitleManager::new(&cfg);
mgr.update(&idle_state());
assert_eq!(mgr.last_title, "grok");
assert_eq!(mgr.last_title, "kigi");
}
// --- Cwd item ---
#[test]
fn cwd_shows_last_component() {
let cfg = config_with_items(vec![TitleItem::Cwd, TitleItem::Grok]);
let cfg = config_with_items(vec![TitleItem::Cwd, TitleItem::Kigi]);
let mut mgr = TitleManager::new(&cfg);
let state = TitleState {
cwd: Some("/home/user/my-project"),
..idle_state()
};
mgr.update(&state);
assert_eq!(mgr.last_title, "my-project - grok");
assert_eq!(mgr.last_title, "my-project - kigi");
}
// --- TurnTimer item ---
#[test]
fn turn_timer_shown_when_above_one_second() {
let cfg = config_with_items(vec![TitleItem::TurnTimer, TitleItem::Grok]);
let cfg = config_with_items(vec![TitleItem::TurnTimer, TitleItem::Kigi]);
let mut mgr = TitleManager::new(&cfg);
let state = TitleState {
turn_elapsed: Some(std::time::Duration::from_secs(42)),
..idle_state()
};
mgr.update(&state);
assert_eq!(mgr.last_title, "42s - grok");
assert_eq!(mgr.last_title, "42s - kigi");
}
#[test]
fn turn_timer_hidden_when_under_one_second() {
let cfg = config_with_items(vec![TitleItem::TurnTimer, TitleItem::Grok]);
let cfg = config_with_items(vec![TitleItem::TurnTimer, TitleItem::Kigi]);
let mut mgr = TitleManager::new(&cfg);
let state = TitleState {
turn_elapsed: Some(std::time::Duration::from_millis(500)),
..idle_state()
};
mgr.update(&state);
assert_eq!(mgr.last_title, "grok");
assert_eq!(mgr.last_title, "kigi");
}
// --- Truncation ---
@@ -759,8 +759,8 @@ mod tests {
// --- Reset ---
#[test]
fn reset_clears_state_and_emits_grok() {
let cfg = config_with_items(vec![TitleItem::SessionName, TitleItem::Grok]);
fn reset_clears_state_and_emits_kigi() {
let cfg = config_with_items(vec![TitleItem::SessionName, TitleItem::Kigi]);
let mut mgr = TitleManager::new(&cfg);
let activity = TurnActivity::Thinking;
let state = TitleState {
@@ -769,10 +769,10 @@ mod tests {
..idle_state()
};
mgr.update(&state);
assert_ne!(mgr.last_title, "grok");
assert_ne!(mgr.last_title, "kigi");
mgr.reset();
assert_eq!(mgr.last_title, "grok");
assert_eq!(mgr.last_title, "kigi");
assert_eq!(mgr.spinner_frame, 0);
assert_eq!(mgr.tick_count, 0);
}
@@ -805,7 +805,7 @@ mod tests {
// Both should contain the persistent parts.
for t in [&t1, &t2] {
assert!(t.contains("grok"), "title missing 'grok': {t}");
assert!(t.contains("kigi"), "title missing 'kigi': {t}");
assert!(t.contains("Responding"), "title missing 'Responding': {t}");
assert!(t.contains("my-session"), "title missing session name: {t}");
}
@@ -820,7 +820,7 @@ mod tests {
let cfg = default_config();
let mut mgr = TitleManager::new(&cfg);
mgr.update(&idle_state());
assert_eq!(mgr.last_title, "grok");
assert_eq!(mgr.last_title, "kigi");
}
// --- Multi-item combinations ---
@@ -832,13 +832,13 @@ mod tests {
TitleItem::SessionName,
TitleItem::Model,
TitleItem::Cwd,
TitleItem::Grok,
TitleItem::Kigi,
]);
let mut mgr = TitleManager::new(&cfg);
let activity = TurnActivity::Thinking;
let state = TitleState {
session_name: Some("proj"),
model: Some("grok-3"),
model: Some("kigi-3"),
activity: Some(&activity),
cwd: Some("/home/user/workspace"),
..idle_state()
@@ -846,7 +846,7 @@ mod tests {
mgr.update(&state);
assert_eq!(
mgr.last_title,
"Thinking - proj - grok-3 - workspace - grok"
"Thinking - proj - kigi-3 - workspace - kigi"
);
}