§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
@@ -77,7 +77,7 @@ impl ChatStateActor {
});
}
/// Out-of-band history repair (`x.ai/session/repair`): run
/// Out-of-band history repair (`kigi/session/repair`): run
/// [`crate::compaction_utils::repair_history`] and persist changes via
/// [`Self::replace_conversation`]. Unlike
/// [`Self::ensure_conversation_integrity`], this also removes orphaned
@@ -134,13 +134,13 @@ impl ChatStateActor {
temperature: self.state.sampling_config.temperature,
max_output_tokens: self.state.sampling_config.max_completion_tokens,
top_p: self.state.sampling_config.top_p,
x_grok_conv_id: Some(conv_id),
x_grok_req_id: Some(req_id),
x_grok_session_id: None,
x_grok_turn_idx: None,
x_grok_agent_id: None,
x_grok_deployment_id: None,
x_grok_user_id: None,
x_kigi_conv_id: Some(conv_id),
x_kigi_req_id: Some(req_id),
x_kigi_session_id: None,
x_kigi_turn_idx: None,
x_kigi_agent_id: None,
x_kigi_deployment_id: None,
x_kigi_user_id: None,
trace,
reasoning_effort: self.state.sampling_config.reasoning_effort,
json_schema: None,
@@ -84,13 +84,13 @@ pub fn estimate_conversation_tokens(items: &[ConversationItem]) -> u64 {
items.iter().map(estimate_item_tokens).sum()
}
/// grok-build's [`ItemTokenCounter`](kigi_compaction::ItemTokenCounter)
/// for the shared compaction engine: the bytes/4 estimate grok-build already
/// kigi's [`ItemTokenCounter`](kigi_compaction::ItemTokenCounter)
/// for the shared compaction engine: the bytes/4 estimate kigi already
/// uses to drive its compaction triggers, exposed through the seam so the
/// shared budgeting math gets the *same* trusted count.
///
/// Where another host plugs a real BPE tokenizer into the same seam,
/// grok-build estimates instead, reusing [`estimate_item_tokens`] so the
/// kigi estimates instead, reusing [`estimate_item_tokens`] so the
/// per-variant arithmetic (images, reasoning blobs, tool-call args) stays in
/// one place.
pub struct EstimatedItemTokenCounter;
@@ -908,7 +908,7 @@ async fn update_sampling_config_is_queryable() {
let h = TestHarness::new();
let new_config = SamplingConfig {
base_url: "https://new.example.com".to_string(),
model: "grok-3".to_string(),
model: "kigi-3".to_string(),
max_completion_tokens: Some(4096),
temperature: Some(0.5),
top_p: None,
@@ -921,7 +921,7 @@ async fn update_sampling_config_is_queryable() {
h.handle.update_sampling_config(new_config.clone());
let config = h.handle.get_sampling_config().await.unwrap();
assert_eq!(config.model, "grok-3");
assert_eq!(config.model, "kigi-3");
assert_eq!(config.context_window, NonZeroU64::new(200_000).unwrap());
}
@@ -1155,8 +1155,8 @@ async fn build_request_includes_all_messages() {
.await
.unwrap();
assert_eq!(request.items.len(), 2);
assert_eq!(request.x_grok_conv_id, Some("conv-1".to_string()));
assert_eq!(request.x_grok_req_id, Some("req-1".to_string()));
assert_eq!(request.x_kigi_conv_id, Some("conv-1".to_string()));
assert_eq!(request.x_kigi_req_id, Some("req-1".to_string()));
}
#[tokio::test]
@@ -1293,7 +1293,7 @@ async fn build_request_with_tool_definitions() {
async fn build_request_uses_sampling_config() {
let config = SamplingConfig {
base_url: "https://api.example.com".to_string(),
model: "grok-3".to_string(),
model: "kigi-3".to_string(),
max_completion_tokens: Some(8192),
temperature: Some(0.7),
top_p: Some(0.9),
@@ -1311,7 +1311,7 @@ async fn build_request_uses_sampling_config() {
.await
.unwrap();
assert_eq!(request.model, Some("grok-3".to_string()));
assert_eq!(request.model, Some("kigi-3".to_string()));
assert_eq!(request.temperature, Some(0.7));
assert_eq!(request.max_output_tokens, Some(8192));
assert_eq!(request.top_p, Some(0.9));
@@ -1484,7 +1484,7 @@ async fn parallel_tool_calls_accept_first_reject_second_skip_third() {
arguments: r#"{"command":"cargo test"}"#.into(),
},
],
model_id: Some("grok-3".to_string()),
model_id: Some("kigi-3".to_string()),
model_fingerprint: None,
reasoning_effort: None,
});
@@ -1770,7 +1770,7 @@ async fn dangling_tool_calls_after_crash_are_repaired_on_load() {
arguments: r#"{"command":"cargo test"}"#.into(),
},
],
model_id: Some("grok-3".to_string()),
model_id: Some("kigi-3".to_string()),
model_fingerprint: None,
reasoning_effort: None,
}),
@@ -3365,13 +3365,13 @@ async fn get_last_model_metadata_returns_both_fields() {
ConversationItem::Assistant(kigi_sampling_types::AssistantItem {
content: "hello".into(),
tool_calls: vec![],
model_id: Some("grok-4.5".into()),
model_id: Some("kigi-4.5".into()),
model_fingerprint: Some("fp_abc123".into()),
reasoning_effort: None,
}),
]);
let meta = h.handle.get_last_model_metadata().await;
assert_eq!(meta.resolved_model_id.as_deref(), Some("grok-4.5"));
assert_eq!(meta.resolved_model_id.as_deref(), Some("kigi-4.5"));
assert_eq!(meta.model_fingerprint.as_deref(), Some("fp_abc123"));
}
@@ -3396,7 +3396,7 @@ async fn sampling_config_survives_compaction_replacement() {
let config = SamplingConfig {
base_url: "https://api.example.com".to_string(),
model: "grok-build".to_string(),
model: "kigi".to_string(),
max_completion_tokens: None,
temperature: Some(0.7),
top_p: Some(0.95),
@@ -3414,7 +3414,7 @@ async fn sampling_config_survives_compaction_replacement() {
ConversationItem::Assistant(kigi_sampling_types::AssistantItem {
content: "I'll fix it.".into(),
tool_calls: vec![],
model_id: Some("grok-4.5".into()),
model_id: Some("kigi-4.5".into()),
model_fingerprint: Some("fp_abc123".into()),
reasoning_effort: None,
}),
@@ -3424,12 +3424,12 @@ async fn sampling_config_survives_compaction_replacement() {
// Pre-compaction: everything correct.
let pre = h.handle.get_sampling_config().await.unwrap();
assert_eq!(pre.model, "grok-build");
assert_eq!(pre.model, "kigi");
assert_eq!(pre.context_window.get(), 500_000);
assert_eq!(pre.api_backend, ApiBackend::Responses);
let pre_meta = h.handle.get_last_model_metadata().await;
assert_eq!(pre_meta.resolved_model_id.as_deref(), Some("grok-4.5"));
assert_eq!(pre_meta.resolved_model_id.as_deref(), Some("kigi-4.5"));
assert_eq!(pre_meta.model_fingerprint.as_deref(), Some("fp_abc123"));
// Simulate compaction: replace conversation with compacted history.
@@ -3441,10 +3441,7 @@ async fn sampling_config_survives_compaction_replacement() {
// Post-compaction: SamplingConfig MUST be preserved.
let post = h.handle.get_sampling_config().await.unwrap();
assert_eq!(
post.model, "grok-build",
"BUG: model changed after compaction"
);
assert_eq!(post.model, "kigi", "BUG: model changed after compaction");
assert_eq!(
post.context_window.get(),
500_000,
@@ -3471,7 +3468,7 @@ async fn sampling_config_survives_compaction_replacement() {
/// After compaction, the `build_session_info` display path uses
/// `get_sampling_config().model` as the source-of-truth model slug.
/// If that model slug is e.g. "grok-build" and not in the ModelState
/// If that model slug is e.g. "kigi" and not in the ModelState
/// catalog with a display name, the pager shows the raw slug. This
/// test verifies the pager's `current_model_name()` behavior when the
/// model ID doesn't match any catalog entry.
@@ -3479,7 +3476,7 @@ async fn sampling_config_survives_compaction_replacement() {
async fn model_metadata_lost_after_compaction_then_recovered_on_next_turn() {
let config = SamplingConfig {
base_url: "https://api.example.com".to_string(),
model: "grok-build".to_string(),
model: "kigi".to_string(),
max_completion_tokens: None,
temperature: Some(0.7),
top_p: Some(0.95),
@@ -3497,7 +3494,7 @@ async fn model_metadata_lost_after_compaction_then_recovered_on_next_turn() {
ConversationItem::Assistant(kigi_sampling_types::AssistantItem {
content: "done".into(),
tool_calls: vec![],
model_id: Some("grok-4.5".into()),
model_id: Some("kigi-4.5".into()),
model_fingerprint: Some("fp_acd3142484d3ad6f".into()),
reasoning_effort: None,
}),
@@ -3507,7 +3504,7 @@ async fn model_metadata_lost_after_compaction_then_recovered_on_next_turn() {
// Before compaction: metadata present.
let meta = h.handle.get_last_model_metadata().await;
assert_eq!(meta.resolved_model_id.as_deref(), Some("grok-4.5"));
assert_eq!(meta.resolved_model_id.as_deref(), Some("kigi-4.5"));
assert_eq!(
meta.model_fingerprint.as_deref(),
Some("fp_acd3142484d3ad6f")
@@ -3532,7 +3529,7 @@ async fn model_metadata_lost_after_compaction_then_recovered_on_next_turn() {
kigi_sampling_types::AssistantItem {
content: "working on it".into(),
tool_calls: vec![],
model_id: Some("grok-4.5".into()),
model_id: Some("kigi-4.5".into()),
model_fingerprint: Some("fp_acd3142484d3ad6f".into()),
reasoning_effort: None,
},
@@ -3540,7 +3537,7 @@ async fn model_metadata_lost_after_compaction_then_recovered_on_next_turn() {
// Metadata recovered.
let meta = h.handle.get_last_model_metadata().await;
assert_eq!(meta.resolved_model_id.as_deref(), Some("grok-4.5"));
assert_eq!(meta.resolved_model_id.as_deref(), Some("kigi-4.5"));
assert_eq!(
meta.model_fingerprint.as_deref(),
Some("fp_acd3142484d3ad6f")
@@ -3564,10 +3561,10 @@ async fn model_metadata_lost_after_compaction_then_recovered_on_next_turn() {
async fn context_window_downgrade_triggers_auto_compact() {
use kigi_sampling_types::ApiBackend;
// Initial config: 500k context, Responses backend (matches grok-4.5)
// Initial config: 500k context, Responses backend (matches kigi-4.5)
let config = SamplingConfig {
base_url: "https://api.x.ai/v1".to_string(),
model: "grok-4.5".to_string(),
base_url: "https://byok.example/v1".to_string(),
model: "kigi-4.5".to_string(),
max_completion_tokens: None,
temperature: Some(0.7),
top_p: Some(0.95),
@@ -3606,7 +3603,7 @@ async fn context_window_downgrade_triggers_auto_compact() {
128_000,
"context_window should be overwritten by update_sampling_config"
);
assert_eq!(post.model, "grok-4.5", "model slug must not change");
assert_eq!(post.model, "kigi-4.5", "model slug must not change");
assert_eq!(
post.api_backend,
ApiBackend::Responses,
@@ -3934,7 +3931,7 @@ async fn prefix_stable_after_model_switch() {
.push_user_message(ConversationItem::user("continue"));
let new_config = SamplingConfig {
model: "grok-3-mini".to_string(),
model: "kigi-3-mini".to_string(),
..test_config()
};
h.handle.update_sampling_config(new_config);
@@ -4317,7 +4314,7 @@ async fn prefix_stable_after_session_resume() {
}
// ============================================================================
// Out-of-band history repair (x.ai/session/repair)
// Out-of-band history repair (kigi/session/repair)
// ============================================================================
/// Bricked-session shape: an orphaned tool result survives load (the eager
@@ -111,7 +111,7 @@ pub enum ChatStateCommand {
is_compaction: bool,
},
/// Out-of-band history repair (`x.ai/session/repair`): run
/// Out-of-band history repair (`kigi/session/repair`): run
/// [`crate::compaction_utils::repair_history`] and persist when changed;
/// `dry_run` only reports.
///
@@ -598,7 +598,7 @@ impl CompactionStateContext {
/// For a sub-agent with
/// a single real user turn, `recent_messages` is the ENTIRE working
/// transcript, and keeping it frees almost nothing while re-cueing the
/// model to re-read the same files. grok-build retains
/// model to re-read the same files. kigi retains
/// `recent_messages` so the model keeps verbatim tool context.
pub fn for_compaction(&self) -> Self {
Self {
@@ -803,17 +803,17 @@ pub struct CompactedHistoryInput<'a> {
/// summary. `None` means no state reminder is appended.
pub system_reminder: Option<String>,
/// When `true`, emit the compaction summary *before* recent messages.
/// When `false` (the default), recent messages come first (grok-build
/// When `false` (the default), recent messages come first (kigi
/// ordering).
pub summary_before_recent: bool,
/// Pre-built transcript hint appended to the summary (caller builds it via
/// [`crate::CompactionMode::transcript_hint`] or
/// [`format_transcript_location`]). `None` to omit. Appended to BOTH the
/// carrier and the grok-build summary.
/// carrier and the kigi summary.
pub transcript_hint: Option<String>,
/// Number of summaries generated so far for this user query, *including*
/// the one being built. Rendered verbatim into the carrier's
/// "Total summaries generated so far …" footer. Ignored by the grok-build
/// "Total summaries generated so far …" footer. Ignored by the kigi
/// (`summary_before_recent == false`) path. Callers that don't track a
/// counter pass `1`.
pub summary_count: u64,
@@ -2679,7 +2679,7 @@ actual user question";
arguments: r#"{"target_file":"src/lib.rs"}"#.into(),
},
],
model_id: Some("grok-3".to_string()),
model_id: Some("kigi-3".to_string()),
model_fingerprint: None,
reasoning_effort: None,
}),
@@ -2712,7 +2712,7 @@ actual user question";
arguments: r#"{"command":"cargo test"}"#.into(),
},
],
model_id: Some("grok-3".to_string()),
model_id: Some("kigi-3".to_string()),
model_fingerprint: None,
reasoning_effort: None,
}),
@@ -3390,7 +3390,7 @@ The user asked to read main.rs and lib.rs. main.rs prints hello world, lib.rs ha
assert!(
kept.iter()
.any(|i| matches!(i, ConversationItem::Reasoning(_))),
"reasoning must be kept when strip_reasoning = false (Grok backends)"
"reasoning must be kept when strip_reasoning = false (Kigi backends)"
);
let stripped = prepare_conversation_for_verbatim_summarization(mk(), true);
assert!(
+1 -1
View File
@@ -186,7 +186,7 @@ impl ChatStateHandle {
});
}
/// Out-of-band history repair (`x.ai/session/repair`); see
/// Out-of-band history repair (`kigi/session/repair`); see
/// [`ChatStateCommand::RepairHistory`]. Returns `None` if the actor is
/// dead, `Some(Err(_))` if a turn was in flight at processing time.
pub async fn repair_history(
+1 -1
View File
@@ -216,7 +216,7 @@ mod tests {
],
sampling_config: SamplingConfig {
base_url: "https://api.example.com".to_string(),
model: "grok-3".to_string(),
model: "kigi-3".to_string(),
max_completion_tokens: Some(4096),
temperature: Some(0.7),
top_p: None,