M0: compilable skeleton — Kigi 0.1.0 fork surgery
Hard fork of xai-org/grok-build (Apache-2.0) re-targeted as Kigi, an
unofficial Kimi Code CLI community build.
Rename & identity
- 72 xai-*/xai-grok-* crates -> kigi-* (explicit: xai-grok-pager-bin ->
kigi-bin [binary `kigi`], xai-grok-pager -> kigi-tui; rest mechanical);
ptyctl, ptyctl-cli, third_party/ unchanged; proto package
xai.grok.tools.v1 -> kigi.tools.v1
- Config home ~/.kigi (KIGI_SHARE_DIR override), env prefix GROK_* ->
KIGI_*, `kigi --version` carries the unofficial-community-build notice
- clap identity, help text, startup banner, prompt templates rebranded
(templates re-encrypted)
Deletions (PRD removal list #5/#6/#7/#9/#10)
- voice input (xai-grok-voice) and all TUI wiring
- telemetry: Mixpanel client, external OTel stream, Sentry, OTLP layers,
trace/GCS/S3 upload queues (kigi-file-utils halved), workspace upload
module & dc_log, heap-profile uploader, auth-diagnostics uploader,
session-analytics halves of feedback; local zero-egress observability
preserved in new kigi-log crate (unified log, --debug firehose,
subsystem file logs, opt-in instrumentation)
- announcements (crate, remote-settings fields, TUI surfaces)
- plugin marketplace (crate, sources/browse/CTA/extensions-modal tab);
direct plugin install/uninstall/update via kigi-agent git_install kept
- relay/gateway/assets endpoints and features (agent relay, headless
relay transport, gateway bridge, LeaderEnvUrls); leader IPC socket now
~/.kigi/leader.sock + KIGI_LEADER_SOCKET, no ws-url derivation
- functional types rehomed instead of deleted: PermissionMode ->
kigi-config-types, McpInitStrategy -> kigi-mcp, PrCreationSource ->
session signals, TerminalDiagnostics -> kigi-pager-render, agent_id ->
shell util
Endpoints
- kigi-env rewritten: single production KigiEndpoints {coding_api_base_url
https://api.kimi.com/coding/v1 (KIGI_CODE_BASE_URL), oauth_host
https://auth.kimi.com (KIGI_OAUTH_HOST), update_base_url (GitHub
Releases API), upgrade_page_url}; GrokBuildEnvironment enum deleted
Toolchain & workspace hygiene
- Rust 1.97.0 pinned; edition 2024; full cargo update; git2 hoisted to
workspace at 0.21 (Option->Result API migration), quick-xml 0.41
- Root Cargo.toml hand-maintained (PRD §8.1): version 0.1.0 inherited by
all members, members sorted, unused deps pruned
- cargo-deny advisories gate (deny.toml with documented transitive
exceptions); CI workflow (check/clippy/fmt/deny/test, macOS+Linux)
- cross-crate test seams re-gated behind `test-support` cargo feature;
insta snapshot baselines renamed to the kigi_tui prefix
- clippy --workspace --all-targets: zero warnings; fmt clean
Fixes surfaced by the port
- updater probe/installer divergence (bin/kigi vs bin/grok symlink set)
- idle model-metadata refresh dead under KIGI_CODE_BASE_URL override
(new is_effective_coding_endpoint_url, loopback+override aware)
- macOS symlinked-TMPDIR fixture canonicalization (foreign_sessions,
fast-worktree); RSS measurement tests serialized via serial_test
Docs & legal (Apache §4)
- NOTICE added (upstream attribution + change statement); THIRD-PARTY
notices sustained; kigi-tools ported-code notices extended; README,
CONTRIBUTING, SECURITY, AGENTS.md rewritten
Out of scope for M0 (tracked): Kimi auth/inference (M1), search/fetch,
command parity, config import (M2), Computer Hub excision & final
brand-token sweep (M2), distribution & self-update rewrite (M3).
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
//! Isolated RSS test for incremental reindexing.
|
||||
//!
|
||||
//! This test lives in its own integration-test file (and therefore its own
|
||||
//! Bazel `rust_test` target / process) so that its whole-process RSS samples
|
||||
//! are not polluted by the other allocation-heavy tests in
|
||||
//! `memory_integration.rs` (e.g. `test_fresh_build_rss`,
|
||||
//! `test_build_batch_peak_rss_is_bounded`, `test_compact_reduces_rss_vs_uncompacted`).
|
||||
//!
|
||||
//! Background: `libtest` runs tests in a single binary concurrently across
|
||||
//! `num_cpus` threads, and VmRSS is measured per-*process*. When this test
|
||||
//! ran inside `memory_integration.rs` it observed allocator churn from the
|
||||
//! other tests on the same process, intermittently pushing the measured
|
||||
//! "incremental growth" delta over the 20 MB budget on aarch64 fastbuild CI
|
||||
//! (`run_1_of_2` and `run_2_of_2` both failed at ~31 MB).
|
||||
//!
|
||||
//! Keep this file to a single test. If you need to add another RSS-sensitive
|
||||
//! test, give it its own file too rather than reintroducing the
|
||||
//! noisy-neighbor problem.
|
||||
|
||||
use kigi_codebase_graph::{FileEvent, IndexManager, IndexManagerConfig};
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use tempfile::tempdir;
|
||||
|
||||
/// Read current process RSS in bytes. Supports Linux and macOS.
|
||||
/// Returns `None` on unsupported platforms.
|
||||
fn rss_bytes() -> Option<usize> {
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
let status = std::fs::read_to_string("/proc/self/status").ok()?;
|
||||
for line in status.lines() {
|
||||
if let Some(val) = line.strip_prefix("VmRSS:") {
|
||||
let kb: usize = val.trim().trim_end_matches(" kB").trim().parse().ok()?;
|
||||
return Some(kb * 1024);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
use std::process::Command;
|
||||
let output = Command::new("ps")
|
||||
.args(["-o", "rss=", "-p", &std::process::id().to_string()])
|
||||
.output()
|
||||
.ok()?;
|
||||
let kb: usize = String::from_utf8_lossy(&output.stdout)
|
||||
.trim()
|
||||
.parse()
|
||||
.ok()?;
|
||||
Some(kb * 1024)
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "linux", target_os = "macos")))]
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn rss_mb() -> Option<f64> {
|
||||
rss_bytes().map(|b| b as f64 / (1024.0 * 1024.0))
|
||||
}
|
||||
|
||||
fn fmt_rss(rss: Option<f64>) -> String {
|
||||
rss.map_or("N/A".to_string(), |v| format!("{:.1}MB", v))
|
||||
}
|
||||
|
||||
/// Create N Rust source files in `dir`, each with `defs_per_file` function defs.
|
||||
fn create_rust_files(dir: &Path, count: usize, defs_per_file: usize) {
|
||||
for i in 0..count {
|
||||
let mut content = String::new();
|
||||
for d in 0..defs_per_file {
|
||||
content.push_str(&format!("fn func_{}_{}() {{}}\n", i, d));
|
||||
}
|
||||
fs::write(dir.join(format!("file_{}.rs", i)), &content).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bulk_incremental_indexing_memory() {
|
||||
let dir = tempdir().unwrap();
|
||||
let root = dir.path();
|
||||
|
||||
create_rust_files(root, 500, 10);
|
||||
|
||||
let rss_before = rss_mb();
|
||||
|
||||
let config = IndexManagerConfig::new(root.to_path_buf())
|
||||
.without_cache_load()
|
||||
.without_cache_save();
|
||||
|
||||
let handle = IndexManager::spawn(config);
|
||||
|
||||
let stats = handle.get_stats().unwrap();
|
||||
let rss_after_build = rss_mb();
|
||||
|
||||
println!(
|
||||
"Initial build: {} files, {} defs, {} refs",
|
||||
stats.files, stats.definitions, stats.references
|
||||
);
|
||||
println!(
|
||||
"RSS: {} before → {} after build",
|
||||
fmt_rss(rss_before),
|
||||
fmt_rss(rss_after_build)
|
||||
);
|
||||
|
||||
assert_eq!(stats.files, 500);
|
||||
assert!(stats.definitions >= 5000);
|
||||
|
||||
for i in 0..100 {
|
||||
let path = root.join(format!("file_{}.rs", i));
|
||||
fs::write(&path, "fn modified() {}\nfn also_modified() {}\n").unwrap();
|
||||
handle.send_event(FileEvent::modified(path)).unwrap();
|
||||
}
|
||||
|
||||
let stats_after = handle.get_stats().unwrap();
|
||||
let rss_after_incremental = rss_mb();
|
||||
|
||||
println!(
|
||||
"After 100 incremental reindexes: {} files, {} defs",
|
||||
stats_after.files, stats_after.definitions
|
||||
);
|
||||
println!("RSS after incremental: {}", fmt_rss(rss_after_incremental));
|
||||
|
||||
// Incremental reindexing should not grow memory significantly.
|
||||
if let (Some(after_inc), Some(after_build)) = (rss_after_incremental, rss_after_build) {
|
||||
let growth = after_inc - after_build;
|
||||
assert!(
|
||||
growth < 20.0,
|
||||
"Incremental reindex grew RSS by {:.1}MB (expected <20MB)",
|
||||
growth
|
||||
);
|
||||
}
|
||||
|
||||
handle.shutdown().unwrap();
|
||||
}
|
||||
Reference in New Issue
Block a user