§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:
@@ -968,7 +968,7 @@ fn try_btrfs_remove(
|
||||
// Known residual TOCTOU: validation `lstat`s/canonicalizes then we
|
||||
// delete by path (the `btrfs subvolume delete` CLI takes a path, not
|
||||
// an fd, so there is no `unlinkat` to close the window). Bounded by:
|
||||
// `btrfs` refuses non-subvolumes, the snapshot dir is grok-owned, and
|
||||
// `btrfs` refuses non-subvolumes, the snapshot dir is kigi-owned, and
|
||||
// `..`/symlink targets are already rejected. Accepted as-is.
|
||||
if let Some(report) = delete_snapshot_with_delegate_fallback(
|
||||
&resolved,
|
||||
@@ -2186,7 +2186,7 @@ mod tests {
|
||||
use kigi_test_utils::git::{git_commit_all, init_git_repo};
|
||||
// Isolate KIGI_SHARE_DIR so the post-removal unregister writes to a private DB.
|
||||
#[cfg(feature = "metadata")]
|
||||
let _fx = crate::db::GrokHomeFixture::new();
|
||||
let _fx = crate::db::KigiHomeFixture::new();
|
||||
|
||||
let tmp = tempfile::TempDir::new().unwrap();
|
||||
let repo = tmp.path().join("repo");
|
||||
@@ -2837,7 +2837,7 @@ mod tests {
|
||||
fn register_worktree_writes_correct_fields() {
|
||||
// Isolate KIGI_SHARE_DIR so register_worktree's open_default write lands
|
||||
// in our own DB (lock + private tmp + restore via the fixture).
|
||||
let fx = crate::db::GrokHomeFixture::new();
|
||||
let fx = crate::db::KigiHomeFixture::new();
|
||||
|
||||
// Unique basename → unique id, so a concurrent open_default writer
|
||||
// (KIGI_SHARE_DIR is process-global) can't INSERT-OR-REPLACE our row.
|
||||
@@ -3411,7 +3411,7 @@ mod tests {
|
||||
// remove_worktree must keep the DB record when the on-disk removal
|
||||
// fails, so the worktree isn't lost from tracking while leaking on
|
||||
// disk (unregister only after a successful removal).
|
||||
let fx = crate::db::GrokHomeFixture::new();
|
||||
let fx = crate::db::KigiHomeFixture::new();
|
||||
|
||||
// A regular file makes remove_dir_all fail (ENOTDIR) deterministically.
|
||||
let wt_path = fx.home.join("doomed-wt");
|
||||
@@ -3454,7 +3454,7 @@ mod tests {
|
||||
kigi_test_utils::require_git!();
|
||||
use kigi_test_utils::git::{git_commit_all, init_git_repo};
|
||||
|
||||
let fx = crate::db::GrokHomeFixture::new();
|
||||
let fx = crate::db::KigiHomeFixture::new();
|
||||
|
||||
// A real repo + a real worktree so remove_worktree succeeds on disk.
|
||||
let repo = fx.home.join("repo");
|
||||
@@ -3504,7 +3504,7 @@ mod tests {
|
||||
|
||||
// KIGI_SHARE_DIR == the gc DB dir so remove_worktree's open_default
|
||||
// unregister hits the same DB the gc record lives in.
|
||||
let fx = crate::db::GrokHomeFixture::new();
|
||||
let fx = crate::db::KigiHomeFixture::new();
|
||||
let db = WorktreeDb::open(&fx.home).unwrap();
|
||||
|
||||
let dir = fx.home.join("expired-wt");
|
||||
|
||||
@@ -141,7 +141,7 @@ pub fn create_snapshot_with_symlink(btrfs_info: &BtrfsInfo, dest: &Path) -> Resu
|
||||
})?;
|
||||
} else if !is_safe_snapshot_delete_target(&snapshot_path) {
|
||||
bail!(
|
||||
"refusing to delete pre-existing snapshot {}: outside grok-managed \
|
||||
"refusing to delete pre-existing snapshot {}: outside kigi-managed \
|
||||
btrfs storage",
|
||||
snapshot_path.display()
|
||||
);
|
||||
@@ -251,7 +251,7 @@ pub fn snapshot_dest_path(btrfs_mount: &Path, subvolume_root: &Path, dest: &Path
|
||||
///
|
||||
/// Symlinks cross mount namespaces and persist across process exits, so the
|
||||
/// worktree at `dest` stays visible to the user's other shells and survives a
|
||||
/// grok restart.
|
||||
/// kigi restart.
|
||||
///
|
||||
/// Destructive contract: a pre-existing **stale symlink** at `dest` is unlinked;
|
||||
/// a pre-existing **directory** is removed only if empty (`remove_dir`). A
|
||||
@@ -351,7 +351,7 @@ pub fn delete_snapshot(path: &Path) -> Result<()> {
|
||||
/// canonicalized parent's final component is one of [`BTRFS_SNAPSHOT_SUBDIRS`]
|
||||
/// (`worktrees` or `.kigi-snapshots`),
|
||||
/// - and that directory sits **directly under a real btrfs mount point** (from
|
||||
/// the live mount table), anchoring the delete to grok-managed storage rather
|
||||
/// the live mount table), anchoring the delete to kigi-managed storage rather
|
||||
/// than any directory that merely happens to be named `worktrees`.
|
||||
///
|
||||
/// Treat all symlink targets and metadata paths as untrusted input and pass
|
||||
|
||||
@@ -500,7 +500,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_copy_git_dir_preserves_worktree_source_marker() {
|
||||
// A worktree-from-worktree (standalone) must inherit the source's
|
||||
// `grok-worktree-source` marker so it still points at the ultimate
|
||||
// `kigi-worktree-source` marker so it still points at the ultimate
|
||||
// main repo rather than the intermediate worktree.
|
||||
let temp = TempDir::new().unwrap();
|
||||
let source_git = temp.path().join("source/.git");
|
||||
@@ -508,12 +508,12 @@ mod tests {
|
||||
|
||||
std::fs::create_dir_all(&source_git).unwrap();
|
||||
std::fs::write(source_git.join("HEAD"), "ref: refs/heads/main\n").unwrap();
|
||||
std::fs::write(source_git.join("grok-worktree-source"), "/main/repo").unwrap();
|
||||
std::fs::write(source_git.join("kigi-worktree-source"), "/main/repo").unwrap();
|
||||
|
||||
copy_git_dir(&source_git, &dest_git).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
std::fs::read_to_string(dest_git.join("grok-worktree-source")).unwrap(),
|
||||
std::fs::read_to_string(dest_git.join("kigi-worktree-source")).unwrap(),
|
||||
"/main/repo"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ impl WorktreeDb {
|
||||
|
||||
/// Open the default DB at `~/.kigi/worktrees.db`.
|
||||
///
|
||||
/// Discovers grok home via `$KIGI_SHARE_DIR`, falling back to the canonicalized
|
||||
/// Discovers kigi home via `$KIGI_SHARE_DIR`, falling back to the canonicalized
|
||||
/// `$HOME/.kigi` (matching `kigi_config::kigi_home`).
|
||||
/// Path is resolved fresh each call (~1µs env var read) to support
|
||||
/// test overrides. Each call opens its own connection — callers in hot
|
||||
@@ -365,23 +365,23 @@ static KIGI_SHARE_DIR_ENV_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(())
|
||||
/// `Drop` restores `KIGI_SHARE_DIR` before `_lock` releases, so the env is correct
|
||||
/// before another waiting setter proceeds.
|
||||
#[cfg(test)]
|
||||
pub(crate) struct GrokHomeFixture {
|
||||
pub(crate) struct KigiHomeFixture {
|
||||
_lock: std::sync::MutexGuard<'static, ()>,
|
||||
prev: Option<std::ffi::OsString>,
|
||||
/// The isolated grok home; pass to `WorktreeDb::open` to read the same DB
|
||||
/// The isolated kigi home; pass to `WorktreeDb::open` to read the same DB
|
||||
/// `open_default()` writes to.
|
||||
pub home: PathBuf,
|
||||
_tmp: tempfile::TempDir,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
impl GrokHomeFixture {
|
||||
impl KigiHomeFixture {
|
||||
pub(crate) fn new() -> Self {
|
||||
let lock = KIGI_SHARE_DIR_ENV_LOCK
|
||||
.lock()
|
||||
.unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = tempfile::TempDir::new().unwrap();
|
||||
let home = tmp.path().join("grok-home");
|
||||
let home = tmp.path().join("kigi-home");
|
||||
std::fs::create_dir_all(&home).unwrap();
|
||||
// Warm up the DB (journal-mode conversion + schema) before exposing it
|
||||
// via KIGI_SHARE_DIR, sparing the test hot loop set_journal_mode's retry
|
||||
@@ -401,7 +401,7 @@ impl GrokHomeFixture {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
impl Drop for GrokHomeFixture {
|
||||
impl Drop for KigiHomeFixture {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
match self.prev.take() {
|
||||
|
||||
@@ -247,7 +247,7 @@ fn scratch_index_path() -> PathBuf {
|
||||
.unwrap_or(0);
|
||||
let seq = COUNTER.fetch_add(1, Ordering::Relaxed);
|
||||
std::env::temp_dir().join(format!(
|
||||
"grok-snapshot-index-{}-{nanos}-{seq}",
|
||||
"kigi-snapshot-index-{}-{nanos}-{seq}",
|
||||
std::process::id()
|
||||
))
|
||||
}
|
||||
@@ -259,7 +259,7 @@ fn scratch_index_path() -> PathBuf {
|
||||
/// (even if they also match a `.gitignore` rule); only *untracked* files
|
||||
/// matching `.gitignore` are excluded.
|
||||
///
|
||||
/// `ref_name` must be a fully-qualified ref (e.g. `refs/grok/subagents/<id>`);
|
||||
/// `ref_name` must be a fully-qualified ref (e.g. `refs/kigi/subagents/<id>`);
|
||||
/// it is overwritten unconditionally. The worktree must have a valid `HEAD`
|
||||
/// (subagent worktrees are detached at their base commit), which becomes the
|
||||
/// snapshot commit's parent (provenance only).
|
||||
@@ -301,8 +301,8 @@ fn snapshot_worktree_to_ref_inner(
|
||||
message: &str,
|
||||
) -> Result<String> {
|
||||
// Synthetic identity scoped to this call so it is never written to git config.
|
||||
const NAME: &str = "Grok Snapshot";
|
||||
const EMAIL: &str = "grok-snapshot@example.com";
|
||||
const NAME: &str = "Kigi Snapshot";
|
||||
const EMAIL: &str = "kigi-snapshot@example.com";
|
||||
|
||||
// Stage against a throwaway index so the worktree's real index is untouched.
|
||||
let scratch = ScratchIndexGuard {
|
||||
@@ -690,7 +690,7 @@ mod tests {
|
||||
std::fs::write(wt.join("tracked.txt"), "edited").unwrap();
|
||||
std::fs::write(wt.join("untracked.txt"), "brand new").unwrap();
|
||||
|
||||
let ref_name = "refs/grok/snapshots/test";
|
||||
let ref_name = "refs/kigi/snapshots/test";
|
||||
let snap = snapshot_worktree_to_ref(&wt, ref_name, "snapshot test").unwrap();
|
||||
assert!(!snap.is_empty());
|
||||
|
||||
@@ -738,7 +738,7 @@ mod tests {
|
||||
std::fs::write(wt.join("ignored.txt"), "secret").unwrap();
|
||||
std::fs::write(wt.join("kept.txt"), "keep me").unwrap();
|
||||
|
||||
let ref_name = "refs/grok/snapshots/ignored";
|
||||
let ref_name = "refs/kigi/snapshots/ignored";
|
||||
snapshot_worktree_to_ref(&wt, ref_name, "ignore test").unwrap();
|
||||
|
||||
let listing =
|
||||
@@ -776,7 +776,7 @@ mod tests {
|
||||
// Edit the tracked-but-ignored file in the worktree.
|
||||
std::fs::write(wt.join("config.env"), "v2").unwrap();
|
||||
|
||||
let ref_name = "refs/grok/snapshots/tracked-ignored";
|
||||
let ref_name = "refs/kigi/snapshots/tracked-ignored";
|
||||
let snap = snapshot_worktree_to_ref(&wt, ref_name, "tracked-then-ignored").unwrap();
|
||||
|
||||
// A file tracked in HEAD must survive even though it matches .gitignore,
|
||||
@@ -806,7 +806,7 @@ mod tests {
|
||||
std::fs::write(repo_path.join("tracked.txt"), "original").unwrap();
|
||||
git_commit_all(&repo_path, "initial");
|
||||
|
||||
let ref_name = "refs/grok/snapshots/clean";
|
||||
let ref_name = "refs/kigi/snapshots/clean";
|
||||
let snap = snapshot_worktree_to_ref(&repo_path, ref_name, "clean snapshot").unwrap();
|
||||
|
||||
let snap_tree =
|
||||
@@ -823,7 +823,7 @@ mod tests {
|
||||
kigi_test_utils::require_git!();
|
||||
let temp = TempDir::new().unwrap();
|
||||
let (_repo, wt) = repo_with_worktree(&temp);
|
||||
let ref_name = "refs/grok/snapshots/overwrite";
|
||||
let ref_name = "refs/kigi/snapshots/overwrite";
|
||||
|
||||
std::fs::write(wt.join("tracked.txt"), "first").unwrap();
|
||||
let snap1 = snapshot_worktree_to_ref(&wt, ref_name, "first").unwrap();
|
||||
@@ -851,7 +851,7 @@ mod tests {
|
||||
|
||||
std::fs::write(wt.join("tracked.txt"), "edited").unwrap();
|
||||
std::fs::write(wt.join("untracked.txt"), "brand new").unwrap();
|
||||
let ref_name = "refs/grok/snapshots/survives";
|
||||
let ref_name = "refs/kigi/snapshots/survives";
|
||||
let snap = snapshot_worktree_to_ref(&wt, ref_name, "pre-removal").unwrap();
|
||||
|
||||
// Delete the worktree dir; the snapshot lives in the shared object/ref store.
|
||||
@@ -895,7 +895,7 @@ mod tests {
|
||||
!before.is_empty(),
|
||||
"precondition: there are pending changes"
|
||||
);
|
||||
snapshot_worktree_to_ref(&wt, "refs/grok/snapshots/noindex", "no mutate").unwrap();
|
||||
snapshot_worktree_to_ref(&wt, "refs/kigi/snapshots/noindex", "no mutate").unwrap();
|
||||
let after = git_capture_in(&wt, &["status", "--porcelain"], &[]).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
@@ -916,7 +916,7 @@ mod tests {
|
||||
// A tracked file whose working-tree content has CRLF line endings.
|
||||
std::fs::write(wt.join("tracked.txt"), "line1\r\nline2\r\n").unwrap();
|
||||
|
||||
let ref_name = "refs/grok/snapshots/crlf";
|
||||
let ref_name = "refs/kigi/snapshots/crlf";
|
||||
let snap = snapshot_worktree_to_ref(&wt, ref_name, "crlf").unwrap();
|
||||
|
||||
// The snapshot blob must keep the raw CRLF bytes: our `-c
|
||||
@@ -946,7 +946,7 @@ mod tests {
|
||||
let name = "λ space.txt";
|
||||
std::fs::write(wt.join(name), "x").unwrap();
|
||||
|
||||
let ref_name = "refs/grok/snapshots/unicode";
|
||||
let ref_name = "refs/kigi/snapshots/unicode";
|
||||
snapshot_worktree_to_ref(&wt, ref_name, "unicode path").unwrap();
|
||||
|
||||
// Read the tree with the same hardening (`core.quotepath=false`) so the
|
||||
@@ -992,7 +992,7 @@ mod tests {
|
||||
std::fs::write(wt.join("lf.txt"), "a\nb\n").unwrap();
|
||||
|
||||
let snap =
|
||||
snapshot_worktree_to_ref(&wt, "refs/grok/snapshots/roundtrip", "round trip").unwrap();
|
||||
snapshot_worktree_to_ref(&wt, "refs/kigi/snapshots/roundtrip", "round trip").unwrap();
|
||||
let base = git_capture_in(&repo_path, &["rev-parse", &format!("{snap}^")], &[]).unwrap();
|
||||
|
||||
// Dispose of the worktree dir; only the ref/objects survive.
|
||||
@@ -1054,7 +1054,7 @@ mod tests {
|
||||
// Build a PARENTLESS commit holding the same working state, so its `^`
|
||||
// never resolves — exercising the base-unreachable fallback without
|
||||
// depending on gc to prune a real base.
|
||||
let snap = snapshot_worktree_to_ref(&wt, "refs/grok/snapshots/orphan-src", "src").unwrap();
|
||||
let snap = snapshot_worktree_to_ref(&wt, "refs/kigi/snapshots/orphan-src", "src").unwrap();
|
||||
let tree = git_capture_in(&wt, &["rev-parse", &format!("{snap}^{{tree}}")], &[]).unwrap();
|
||||
let ident = [
|
||||
("GIT_AUTHOR_NAME", "T"),
|
||||
@@ -1100,7 +1100,7 @@ mod tests {
|
||||
|
||||
std::fs::write(wt.join("tracked.txt"), "edited").unwrap();
|
||||
std::fs::write(wt.join("untracked.txt"), "brand new").unwrap();
|
||||
let snap = snapshot_worktree_to_ref(&wt, "refs/grok/snapshots/idem", "idem").unwrap();
|
||||
let snap = snapshot_worktree_to_ref(&wt, "refs/kigi/snapshots/idem", "idem").unwrap();
|
||||
crate::remove_worktree(&wt).unwrap();
|
||||
|
||||
// First rehydrate recreates the dest dir.
|
||||
@@ -1141,7 +1141,7 @@ mod tests {
|
||||
std::fs::write(wt.join("tracked.txt"), "edited").unwrap();
|
||||
std::fs::write(wt.join("untracked.txt"), "brand new").unwrap();
|
||||
|
||||
let ref_name = "refs/grok/subagents/standalone";
|
||||
let ref_name = "refs/kigi/subagents/standalone";
|
||||
let snap = snapshot_worktree_to_ref(&wt, ref_name, "standalone snapshot").unwrap();
|
||||
|
||||
// The snapshot lives only in the standalone's own `.git`, NOT in source.
|
||||
@@ -1192,11 +1192,11 @@ mod tests {
|
||||
let temp = TempDir::new().unwrap();
|
||||
|
||||
// Isolate the worktree DB (lock + KIGI_SHARE_DIR → private tmp + restore).
|
||||
let fx = crate::db::GrokHomeFixture::new();
|
||||
let fx = crate::db::KigiHomeFixture::new();
|
||||
|
||||
let (repo_path, wt) = repo_with_worktree(&temp);
|
||||
std::fs::write(wt.join("tracked.txt"), "edited").unwrap();
|
||||
let snap = snapshot_worktree_to_ref(&wt, "refs/grok/snapshots/db", "db test").unwrap();
|
||||
let snap = snapshot_worktree_to_ref(&wt, "refs/kigi/snapshots/db", "db test").unwrap();
|
||||
crate::remove_worktree(&wt).unwrap();
|
||||
|
||||
// Rehydrate into a UNIQUE-basename dest so its DB id can't collide with
|
||||
|
||||
@@ -226,7 +226,7 @@ fn log_unknown_mount_ns_once() {
|
||||
if !LOGGED.swap(true, Ordering::Relaxed) {
|
||||
tracing::info!(
|
||||
"cannot read /proc/1/ns/mnt (likely non-root); treating mount namespace as \
|
||||
non-private — overlay/bind strategies stay enabled. If grok is in a private \
|
||||
non-private — overlay/bind strategies stay enabled. If kigi is in a private \
|
||||
namespace as non-root, worktrees may be ephemeral."
|
||||
);
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ pub(crate) fn execute_create_worktree(plan: WorktreePlan) -> Result<CreateWorktr
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Record the source repo root in `<worktree>/.git/grok-worktree-source`.
|
||||
/// Record the source repo root in `<worktree>/.git/kigi-worktree-source`.
|
||||
///
|
||||
/// A standalone worktree is an independent repo whose `.git` is a directory:
|
||||
/// nothing inside it points back to the source, so consumers like `.envrc`
|
||||
@@ -234,7 +234,7 @@ fn record_main_repo_marker(source: &Path, worktree: &Path) {
|
||||
if !git_dir.is_dir() {
|
||||
return;
|
||||
}
|
||||
let marker = git_dir.join("grok-worktree-source");
|
||||
let marker = git_dir.join("kigi-worktree-source");
|
||||
if marker.exists() {
|
||||
return;
|
||||
}
|
||||
@@ -1685,7 +1685,7 @@ mod tests {
|
||||
|
||||
record_main_repo_marker(&source, &dest);
|
||||
|
||||
let marker = dest.join(".git/grok-worktree-source");
|
||||
let marker = dest.join(".git/kigi-worktree-source");
|
||||
let recorded = std::fs::read_to_string(&marker).expect("marker should be written");
|
||||
assert!(
|
||||
Path::new(recorded.trim()).join(".git").is_dir(),
|
||||
@@ -1704,7 +1704,7 @@ mod tests {
|
||||
|
||||
record_main_repo_marker(&source, &dest);
|
||||
|
||||
assert!(!dest.join(".git/grok-worktree-source").exists());
|
||||
assert!(!dest.join(".git/kigi-worktree-source").exists());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1717,7 +1717,7 @@ mod tests {
|
||||
|
||||
let dest = tmp.path().join("dest");
|
||||
std::fs::create_dir_all(dest.join(".git")).unwrap();
|
||||
let marker = dest.join(".git/grok-worktree-source");
|
||||
let marker = dest.join(".git/kigi-worktree-source");
|
||||
std::fs::write(&marker, "/the/ultimate/main/repo").unwrap();
|
||||
|
||||
record_main_repo_marker(&source, &dest);
|
||||
|
||||
Reference in New Issue
Block a user