§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
@@ -1285,8 +1285,8 @@ fn render_row_list_with_search_bar(
fn render_docs_footer(buf: &mut Buffer, area: Rect, theme: &Theme) {
const LONG: &str =
"Tip · Ask Grok: \"change theme to grokday\" or \"what does compact mode do?\"";
const SHORT: &str = "Tip · Ask Grok to change a setting";
"Tip · Ask Kigi: \"change theme to kigiday\" or \"what does compact mode do?\"";
const SHORT: &str = "Tip · Ask Kigi to change a setting";
let text = modal_window::fit_tip_line(&[LONG, SHORT], area.width as usize);
modal_window::render_centered_tip_footer(buf, area, theme, text.as_ref());
}
@@ -1743,7 +1743,7 @@ const PICKER_MARKER_W: u16 = 1;
/// The chooser already scrolls within the viewport when the focused choice
/// falls off-screen (`picker_scroll_offset`); this limit exists so catalogs
/// stay intentionally curated rather than unbounded. Sized to fit the full
/// Grok STT language list (25 codes + client-only `auto` = 26) with headroom.
/// Kigi STT language list (25 codes + client-only `auto` = 26) with headroom.
pub(crate) const MAX_PICKER_CHOICES: usize = 32;
/// Render the shared sub-pane header (bold title row + word-wrapped description)
@@ -6572,8 +6572,8 @@ mod tests {
let registry = SettingsRegistry::from_entries(vec![synthetic_meta]);
let snapshot = PagerLocalSnapshot {
available_models: vec![(
"Grok Test".to_string(),
acp::ModelId::new(Arc::from("grok-test")),
"Kigi Test".to_string(),
acp::ModelId::new(Arc::from("kigi-test")),
)],
..PagerLocalSnapshot::default()
};
@@ -6596,7 +6596,7 @@ mod tests {
/// buffers that fit entirely within the visible window.
#[test]
fn render_editing_value_cursor_at_logical_position_when_buffer_fits() {
let mut s = editor_render_fixture("Grok Test", 4); // cursor between "Grok" and " Test"
let mut s = editor_render_fixture("Kigi Test", 4); // cursor between "Kigi" and " Test"
let area = Rect {
x: 0,
y: 0,
@@ -7280,9 +7280,9 @@ mod tests {
#[test]
fn picking_enum_esc_dispatches_preview_revert_for_each_key() {
let cases: &[(&str, &str)] = &[
("theme", "groknight"),
("auto_dark_theme", "groknight"),
("auto_light_theme", "grokday"),
("theme", "kiginight"),
("auto_dark_theme", "kiginight"),
("auto_light_theme", "kigiday"),
];
for &(key, original) in cases {
let mut s = make_state();
@@ -7331,18 +7331,18 @@ mod tests {
s.mode = SettingsModalMode::PickingEnum {
key: "theme",
choices_idx: 0,
original_value: SettingValue::Enum("groknight"),
original_value: SettingValue::Enum("kiginight"),
supports_preview: true,
};
let outcome = handle_settings_key(&mut s, &KeyEvent::new(KeyCode::Esc, KeyModifiers::NONE));
match outcome {
SettingsKeyOutcome::Action(Action::PreviewTheme(name)) => {
assert_eq!(
name, "groknight",
name, "kiginight",
"Esc revert must dispatch the original canonical"
);
}
other => panic!("expected Action::PreviewTheme(\"groknight\") on Esc, got {other:?}"),
other => panic!("expected Action::PreviewTheme(\"kiginight\") on Esc, got {other:?}"),
}
assert!(matches!(s.mode, SettingsModalMode::Browse));
}
@@ -9000,14 +9000,14 @@ mod tests {
assert!(
validation_error.is_some(),
"validation_error must be Some for unknown model 'a' \
(catalog has 'Grok 4 Fast' only)",
(catalog has 'Kigi 4 Fast' only)",
);
}
_ => panic!("mode must remain EditingValue after char input"),
}
// Enter on a buffer that fails the KnownModel validator
// (catalog has 'Grok 4 Fast'; "a" doesn't match) is
// (catalog has 'Kigi 4 Fast'; "a" doesn't match) is
// Unchanged — commit refused.
let outcome =
handle_settings_key(&mut s, &KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE));
@@ -9053,8 +9053,8 @@ mod tests {
let mut s = make_state();
s.mode = SettingsModalMode::EditingValue {
key: "default_model",
buffer: "grok-4".to_string(),
cursor_byte: "grok-4".len(),
buffer: "kigi-4".to_string(),
cursor_byte: "kigi-4".len(),
validation_error: None,
};
let outcome = handle_settings_key(&mut s, &KeyEvent::new(KeyCode::Esc, KeyModifiers::NONE));
@@ -9880,7 +9880,7 @@ mod tests {
}
// -- User-feedback follow-up: always reserve a blank line between
// the "Tip · Ask Grok…" docs footer and the keybindings hints.
// the "Tip · Ask Kigi…" docs footer and the keybindings hints.
//
// Before this fix, when the hints wrapped to 2 lines (narrow modal
// widths) the chrome's 2-row footer was fully consumed by hint
@@ -10683,7 +10683,7 @@ mod tests {
);
// SHORT path: width that fits SHORT but not LONG.
// SHORT = "Tip · Ask Grok to change a setting" (34 cells);
// SHORT = "Tip · Ask Kigi to change a setting" (34 cells);
// LONG ≈ 73 cells. width=40 lands in the SHORT band.
let (row_short, tip_start_short, trailing_short) = render(40);
assert!(
@@ -10691,8 +10691,8 @@ mod tests {
"width=40 must render SHORT path (contains `change a setting`): {row_short:?}",
);
assert!(
!row_short.contains("grokday"),
"width=40 must NOT render LONG path (no `grokday`): {row_short:?}",
!row_short.contains("kigiday"),
"width=40 must NOT render LONG path (no `kigiday`): {row_short:?}",
);
assert!(
tip_start_short.abs_diff(trailing_short) <= 1,
@@ -10736,7 +10736,7 @@ mod tests {
let mut tip_y: Option<u16> = None;
for y in 0..area.height {
let txt = buf_row_text(&buf, y, area.x, area.width);
if txt.contains("Tip") && txt.contains("Ask Grok") {
if txt.contains("Tip") && txt.contains("Ask Kigi") {
tip_y = Some(y);
break;
}
@@ -11044,17 +11044,17 @@ mod tests {
// For preview-supporting enums (theme), the breadcrumb-
// click revert dispatches `Action::PreviewTheme(original)`.
// The original canonical for the default theme is
// `"groknight"`. Tightened from the previous `Action(_) |
// `"kiginight"`. Tightened from the previous `Action(_) |
// Changed` to lock in the revert contract.
match outcome {
SettingsKeyOutcome::Action(Action::PreviewTheme(orig)) => {
assert_eq!(
orig, "groknight",
orig, "kiginight",
"breadcrumb-click revert must carry the original canonical",
);
}
other => panic!(
"expected Action(PreviewTheme(\"groknight\")) — the keyboard \
"expected Action(PreviewTheme(\"kiginight\")) — the keyboard \
Esc-equivalent revert got {other:?}",
),
}
@@ -11098,7 +11098,7 @@ mod tests {
}
other => panic!("expected PickingEnum, got {other:?}"),
};
// Pick a different index. The default theme is `groknight`
// Pick a different index. The default theme is `kiginight`
// (index 1 per the registry); advance to index 0 to ensure
// we're navigating to a different value.
let target_idx = if advanced_idx == 0 { 1 } else { 0 };
@@ -11158,11 +11158,11 @@ mod tests {
key, "theme",
"OpenResetConfirm key must be the active picker setting",
);
// Default theme is `groknight`; entering the picker
// captures `original_value = current value = groknight`,
// Default theme is `kiginight`; entering the picker
// captures `original_value = current value = kiginight`,
// so the revert dispatches with that canonical.
assert_eq!(
orig, "groknight",
orig, "kiginight",
"PreviewTheme revert must carry the original canonical",
);
}
@@ -11628,9 +11628,9 @@ mod tests {
/// regardless of how much the bg tokens differ in luma.
///
/// The previous name `_title_bg_is_darker_than_content_bg` was
/// misleading: on dark themes (GrokNight, TokyoNight, RosePine
/// misleading: on dark themes (KigiNight, TokyoNight, RosePine
/// Moon) `bg_visual` is actually *lighter* than `bg_highlight`;
/// only on the GrokDay light theme is title darker. The
/// only on the KigiDay light theme is title darker. The
/// contract that the rendering code actually relies on is "title
/// uses the heavier / more-saturated `bg_visual` token, content
/// uses `bg_highlight`, plus an UNDERLINED title modifier for
@@ -11686,14 +11686,14 @@ mod tests {
// raw theme directly so this assertion survives `NO_COLOR`
// / 256-color quantization.
let raw_theme = match crate::theme::Theme::current_kind() {
crate::theme::ThemeKind::GrokNight => crate::theme::Theme::groknight(),
crate::theme::ThemeKind::KigiNight => crate::theme::Theme::kiginight(),
crate::theme::ThemeKind::TokyoNight => crate::theme::Theme::tokyonight(),
crate::theme::ThemeKind::GrokDay => crate::theme::Theme::grokday(),
crate::theme::ThemeKind::KigiDay => crate::theme::Theme::kigiday(),
crate::theme::ThemeKind::RosePineMoon => crate::theme::Theme::rosepine_moon(),
// Resolved via `Theme::current()` rather than a constructor
// because `theme::oscura` is a private module.
crate::theme::ThemeKind::OscuraMidnight => crate::theme::Theme::current(),
crate::theme::ThemeKind::Auto => crate::theme::Theme::groknight(),
crate::theme::ThemeKind::Auto => crate::theme::Theme::kiginight(),
};
assert_ne!(
raw_theme.bg_visual, raw_theme.bg_highlight,