docs(comments): rewrite comments across all crates to the guidelines
Sweep every first-party crate source (1956 .rs files) to the project comment guidelines: delete redundant restatements, decorative banners, change narration, and end-of-line comments; keep and tighten the crucial ones (invariants, bug rationale, SAFETY blocks, ported-source attribution). No functional code changed. Every edit is proven comment-only against the prior tree by a comment-stripping lexer (string/char/raw-string aware) plus a separate doctest-fence check. Where removing a comment made rustfmt or clippy want to re-lay-out adjacent code, the minimal triggering comment is restored so code tokens stay byte-identical. Gates green: cargo fmt --all --check (0 diffs), cargo check and cargo clippy --workspace --all-targets (0 warnings). Adds scripts/check_codegen_comment_guidelines.py — the enforcement gate for these guidelines (flags banners, end-of-line comments, change narration, and commented-out code).
This commit is contained in:
@@ -32,13 +32,11 @@ use kigi_tools::computer::local::cgroup::{CgroupMemoryConfig, PROCESS_OOM_EXIT_C
|
||||
use kigi_tools::computer::types::{TerminalBackend, TerminalRunRequest, TerminalRunResult};
|
||||
use kigi_tools::notification::types::ToolNotificationHandle;
|
||||
|
||||
// ── Helpers ──────────────────────────────────────────────────────────────
|
||||
|
||||
/// Small memory limit for testing: 32 MiB high, 32 MiB headroom (64 MiB hard max).
|
||||
fn test_memory_config() -> CgroupMemoryConfig {
|
||||
CgroupMemoryConfig {
|
||||
memory_high_bytes: 32 * 1024 * 1024, // 32 MiB
|
||||
headroom_bytes: 32 * 1024 * 1024, // 32 MiB headroom → 64 MiB hard max
|
||||
memory_high_bytes: 32 * 1024 * 1024,
|
||||
headroom_bytes: 32 * 1024 * 1024,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +70,6 @@ fn make_request(command: &str, timeout_secs: u64) -> TerminalRunRequest {
|
||||
fn is_linux_with_cgroupv2() -> bool {
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
// Check that cgroupv2 is mounted
|
||||
std::path::Path::new("/sys/fs/cgroup/cgroup.controllers").exists()
|
||||
}
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
@@ -92,7 +89,6 @@ fn can_create_cgroups() -> bool {
|
||||
for line in contents.lines() {
|
||||
if let Some(path) = line.strip_prefix("0::") {
|
||||
let cgroup_dir = std::path::PathBuf::from(format!("/sys/fs/cgroup{}", path));
|
||||
// Check if we can write to this cgroup's subtree_control
|
||||
let subtree = cgroup_dir.join("cgroup.subtree_control");
|
||||
return subtree.exists();
|
||||
}
|
||||
@@ -133,9 +129,6 @@ fn print_result(label: &str, result: &TerminalRunResult) {
|
||||
);
|
||||
}
|
||||
|
||||
// ── Tests ────────────────────────────────────────────────────────────────
|
||||
|
||||
/// Test 1: A command that stays well under the limit exits normally.
|
||||
#[tokio::test]
|
||||
#[ignore = "requires Linux cgroupv2 with delegation — run with: cargo test --test cgroup_memory_test -- --ignored --nocapture"]
|
||||
async fn test_under_limit_exits_normally() {
|
||||
@@ -173,7 +166,6 @@ async fn test_under_limit_exits_normally() {
|
||||
eprintln!("✅ PASSED: under_limit_exits_normally");
|
||||
}
|
||||
|
||||
/// Test 2: A command that allocates way more than the limit is killed with 137/oom.
|
||||
#[tokio::test]
|
||||
#[ignore = "requires Linux cgroupv2 with delegation"]
|
||||
async fn test_over_limit_gets_oom_killed() {
|
||||
@@ -216,7 +208,6 @@ print('Allocation succeeded (should not reach here)', flush=True)
|
||||
result.exit_code, result.signal
|
||||
);
|
||||
|
||||
// Output before the kill should be preserved
|
||||
assert!(
|
||||
result.combined_output.contains("Allocating 128 MiB"),
|
||||
"Output before OOM should be captured"
|
||||
@@ -225,7 +216,6 @@ print('Allocation succeeded (should not reach here)', flush=True)
|
||||
eprintln!("✅ PASSED: over_limit_gets_oom_killed");
|
||||
}
|
||||
|
||||
/// Test 3: After an OOM, the backend still works for subsequent commands.
|
||||
#[tokio::test]
|
||||
#[ignore = "requires Linux cgroupv2 with delegation"]
|
||||
async fn test_session_survives_oom() {
|
||||
@@ -238,7 +228,6 @@ async fn test_session_survives_oom() {
|
||||
let backend = LocalTerminalBackend::with_memory_limit(test_memory_config());
|
||||
tokio::time::sleep(Duration::from_millis(200)).await;
|
||||
|
||||
// First: trigger an OOM
|
||||
let oom_cmd = r#"python3 -c "data = bytearray(128 * 1024 * 1024)""#;
|
||||
let oom_result = backend
|
||||
.run(make_request(oom_cmd, 30))
|
||||
@@ -250,7 +239,6 @@ async fn test_session_survives_oom() {
|
||||
// Small delay so cgroup memory is reclaimed
|
||||
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
|
||||
// Second: run a lightweight command — should succeed
|
||||
let ok_result = backend
|
||||
.run(make_request("echo 'alive after OOM'", 10))
|
||||
.await
|
||||
@@ -271,7 +259,6 @@ async fn test_session_survives_oom() {
|
||||
eprintln!("✅ PASSED: session_survives_oom");
|
||||
}
|
||||
|
||||
/// Test 4: Background tasks are also subject to the memory limit.
|
||||
#[tokio::test]
|
||||
#[ignore = "requires Linux cgroupv2 with delegation"]
|
||||
async fn test_background_task_oom() {
|
||||
@@ -284,7 +271,6 @@ async fn test_background_task_oom() {
|
||||
let backend = LocalTerminalBackend::with_memory_limit(test_memory_config());
|
||||
tokio::time::sleep(Duration::from_millis(200)).await;
|
||||
|
||||
// Start a background command that will OOM
|
||||
let alloc_cmd = r#"python3 -c "
|
||||
import time
|
||||
print('BG: allocating...', flush=True)
|
||||
@@ -301,7 +287,6 @@ time.sleep(60)
|
||||
|
||||
eprintln!(" Background task_id: {}", handle.task_id);
|
||||
|
||||
// Wait for completion (it should be killed before the 60s timeout)
|
||||
let snapshot = backend
|
||||
.wait_for_completion(&handle.task_id, Some(Duration::from_secs(30)))
|
||||
.await;
|
||||
@@ -331,9 +316,8 @@ time.sleep(60)
|
||||
eprintln!("✅ PASSED: background_task_oom");
|
||||
}
|
||||
|
||||
/// Test 5: Gradual allocation that slowly ramps past the limit.
|
||||
/// This tests that the inotify monitor catches the memory.high event
|
||||
/// rather than relying on the kernel's hard memory.max kill.
|
||||
/// Slow ramp past the limit exercises the inotify monitor catching the
|
||||
/// memory.high event rather than the kernel's hard memory.max kill.
|
||||
#[tokio::test]
|
||||
#[ignore = "requires Linux cgroupv2 with delegation"]
|
||||
async fn test_gradual_allocation_oom() {
|
||||
@@ -377,13 +361,11 @@ print('Finished all allocations (should not reach here)', flush=True)
|
||||
result.exit_code, result.signal
|
||||
);
|
||||
|
||||
// Should have some output showing allocations before the kill
|
||||
assert!(
|
||||
result.combined_output.contains("Allocated"),
|
||||
"Should see some allocation progress before kill"
|
||||
);
|
||||
|
||||
// Should NOT have finished all 128 MiB
|
||||
assert!(
|
||||
!result.combined_output.contains("Finished all allocations"),
|
||||
"Should have been killed before finishing"
|
||||
@@ -392,13 +374,10 @@ print('Finished all allocations (should not reach here)', flush=True)
|
||||
eprintln!("✅ PASSED: gradual_allocation_oom");
|
||||
}
|
||||
|
||||
/// Test 6: No memory config → no cgroup enforcement, large alloc succeeds.
|
||||
/// This verifies the no-op path works correctly.
|
||||
#[tokio::test]
|
||||
async fn test_no_config_no_enforcement() {
|
||||
eprintln!("\n=== Test: no_config_no_enforcement ===");
|
||||
|
||||
// Use the plain `new()` constructor — no memory limits
|
||||
let backend = LocalTerminalBackend::new();
|
||||
tokio::time::sleep(Duration::from_millis(200)).await;
|
||||
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
//! Data-driven tests for path-not-found hint logic using synthetic filesystem
|
||||
//! layouts that exercise common model path-guess failure modes.
|
||||
//!
|
||||
//! Each [`Case`] sets up a temporary filesystem layout, calls
|
||||
//! Each test sets up a temporary filesystem layout, calls
|
||||
//! [`path_not_found_hint`] or [`format_not_found_error`], and asserts the
|
||||
//! output matches what we want the model to see.
|
||||
//!
|
||||
//! To add a new pattern, add a `Case` struct literal to the relevant
|
||||
//! `#[tokio::test]` function. No boilerplate needed.
|
||||
//!
|
||||
//! Run:
|
||||
//! ```bash
|
||||
//! cargo test -p kigi-tools --test path_suggestions_production
|
||||
@@ -17,8 +14,6 @@ use kigi_tools::util::path_suggestions::{format_not_found_error, path_not_found_
|
||||
use std::path::PathBuf;
|
||||
use tempfile::TempDir;
|
||||
|
||||
// ── Helpers ──────────────────────────────────────────────────────────────
|
||||
|
||||
/// Set up a temp dir with the given dirs and files, then return (tmpdir, root).
|
||||
fn setup_fs(dirs: &[&str], files: &[&str]) -> (TempDir, PathBuf) {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
@@ -44,7 +39,6 @@ fn similar_names(hint: &kigi_tools::util::path_suggestions::PathNotFoundHint) ->
|
||||
.collect()
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
// Pattern 1: Hallucinated deep paths — model guesses plausible paths where
|
||||
// the parent directory exists but the leaf file doesn't.
|
||||
//
|
||||
@@ -52,11 +46,9 @@ fn similar_names(hint: &kigi_tools::util::path_suggestions::PathNotFoundHint) ->
|
||||
// path: features/billing/impl/src/.../BillingFeaturesImpl.kt
|
||||
// path: subsystem/core/components/impl/src/test
|
||||
// path: .github/PULL_REQUEST_TEMPLATE.md
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
#[tokio::test]
|
||||
async fn pattern1_parent_exists_wrong_leaf_suggests_similar() {
|
||||
// Model asks for BillingFeaturesImpl.kt but BillingFeatures.kt exists.
|
||||
let (_tmp, root) = setup_fs(
|
||||
&["features/billing/impl/src/main/kotlin/com/example/billing"],
|
||||
&["features/billing/impl/src/main/kotlin/com/example/billing/BillingFeatures.kt"],
|
||||
@@ -77,7 +69,6 @@ async fn pattern1_parent_exists_wrong_leaf_suggests_similar() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn pattern1_pluralization_typo() {
|
||||
// Model asks for "lib" directory but "libs" exists at root.
|
||||
let (_tmp, root) = setup_fs(&["libs"], &[]);
|
||||
let cwd = root.clone();
|
||||
let missing = root.join("lib");
|
||||
@@ -93,7 +84,6 @@ async fn pattern1_pluralization_typo() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn pattern1_missing_extension() {
|
||||
// Model asks for "README" but "README.md" exists.
|
||||
let (_tmp, root) = setup_fs(&[], &["README.md"]);
|
||||
let cwd = root.clone();
|
||||
let missing = root.join("README");
|
||||
@@ -109,7 +99,6 @@ async fn pattern1_missing_extension() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn pattern1_wrong_suffix() {
|
||||
// Model asks for "helpers.rs" but "helper.rs" exists.
|
||||
let (_tmp, root) = setup_fs(&["src/util"], &["src/util/helper.rs"]);
|
||||
let cwd = root.clone();
|
||||
let missing = root.join("src/util/helpers.rs");
|
||||
@@ -125,8 +114,7 @@ async fn pattern1_wrong_suffix() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn pattern1_parent_dir_itself_missing() {
|
||||
// Model asks for "nonexistent_dir/foo.rs" — parent doesn't exist either.
|
||||
// Should gracefully return empty similar, no crash.
|
||||
// Parent dir is missing too — should degrade gracefully, not crash.
|
||||
let (_tmp, root) = setup_fs(&[], &[]);
|
||||
let cwd = root.clone();
|
||||
let missing = root.join("nonexistent_dir/foo.rs");
|
||||
@@ -140,8 +128,7 @@ async fn pattern1_parent_dir_itself_missing() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn pattern1_contributing_md_guess() {
|
||||
// Model guesses CONTRIBUTING.md exists (common file, not every repo).
|
||||
// No similar names should appear if nothing matches.
|
||||
// A hallucinated common file with nothing similar in the tree → no suggestion.
|
||||
let (_tmp, root) = setup_fs(&[".github"], &["LICENSE", "Cargo.toml"]);
|
||||
let cwd = root.clone();
|
||||
let missing = root.join("CONTRIBUTING.md");
|
||||
@@ -149,13 +136,9 @@ async fn pattern1_contributing_md_guess() {
|
||||
let hint = path_not_found_hint(&missing, &cwd, &cwd).await;
|
||||
|
||||
assert!(hint.suggestion.is_none());
|
||||
// "CONTRIBUTING.md" doesn't substring-match "LICENSE" or "Cargo.toml"
|
||||
// so similar should be empty.
|
||||
// (It might match ".github" since "contribut" doesn't contain ".github".)
|
||||
assert!(!hint.cwd_note.is_empty());
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
// Pattern 2: Absolute paths to wrong locations — model uses absolute paths
|
||||
// pointing outside CWD (other user homes, worktree internals, cargo registry).
|
||||
//
|
||||
@@ -163,12 +146,9 @@ async fn pattern1_contributing_md_guess() {
|
||||
// path: /Users/alice/.cargo/registry/... (cwd: /Users/alice/project)
|
||||
// path: /tmp/.tool/sessions/%2F.../terminal/.. (cwd: /workspace/repo)
|
||||
// path: /Users/bob/workspace/worktrees/app/.. (cwd: /Users/bob/workspace/app/...)
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
#[tokio::test]
|
||||
async fn pattern2_absolute_path_completely_different_tree() {
|
||||
// Model asks for /Users/other/project/src/foo.rs, cwd is /Users/me/project.
|
||||
// Completely unrelated — no suggestion, just CWD note.
|
||||
let (_tmp, root) = setup_fs(&["src"], &["src/foo.rs"]);
|
||||
let cwd = root.clone();
|
||||
let unrelated = PathBuf::from("/Users/other/project/src/foo.rs");
|
||||
@@ -182,7 +162,6 @@ async fn pattern2_absolute_path_completely_different_tree() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn pattern2_kigi_sessions_internal_path() {
|
||||
// Model searches internal session paths — no suggestion should fire.
|
||||
let (_tmp, root) = setup_fs(&["src"], &[]);
|
||||
let cwd = root.clone();
|
||||
let internal =
|
||||
@@ -194,13 +173,11 @@ async fn pattern2_kigi_sessions_internal_path() {
|
||||
assert!(hint.similar.is_empty());
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
// Pattern 3: Dropped repo folder — model omits the repo directory name from
|
||||
// the path. E.g. asks for /parent/src when CWD is /parent/repo and
|
||||
// /parent/repo/src exists.
|
||||
//
|
||||
// This is the primary target of try_suggest_under_cwd().
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
#[tokio::test]
|
||||
async fn pattern3_dropped_folder_with_display_remap() {
|
||||
@@ -235,7 +212,6 @@ async fn pattern3_dropped_folder_with_display_remap() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn pattern3_dropped_folder_relative_path_skipped() {
|
||||
// Relative paths should never trigger the dropped-folder detector.
|
||||
let (_tmp, root) = setup_fs(&["repo/src"], &[]);
|
||||
let cwd = root.join("repo");
|
||||
|
||||
@@ -249,7 +225,6 @@ async fn pattern3_dropped_folder_relative_path_skipped() {
|
||||
);
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
// Pattern 4: Common prefix guesses — model uses src/, app/, lib/ as first
|
||||
// component but the repo doesn't have that top-level dir, or uses a variant.
|
||||
//
|
||||
@@ -257,11 +232,9 @@ async fn pattern3_dropped_folder_relative_path_skipped() {
|
||||
// path: src/search_engine/index.py (repo has no top-level src/)
|
||||
// path: lib/utils.rs (repo uses libs/ not lib/)
|
||||
// path: app/_components/galaxy (wrong component dir name)
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
#[tokio::test]
|
||||
async fn pattern4_lib_vs_libs() {
|
||||
// Model asks for "lib/utils.rs", repo has "libs/" directory.
|
||||
let (_tmp, root) = setup_fs(&["libs"], &["libs/utils.rs"]);
|
||||
let cwd = root.clone();
|
||||
let missing = root.join("lib");
|
||||
@@ -277,7 +250,6 @@ async fn pattern4_lib_vs_libs() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn pattern4_src_does_not_exist_no_misleading_suggestion() {
|
||||
// Model asks for src/main.py but top-level has no src/ and nothing similar.
|
||||
let (_tmp, root) = setup_fs(&["python", "scripts"], &["setup.py"]);
|
||||
let cwd = root.clone();
|
||||
let missing = root.join("src");
|
||||
@@ -293,14 +265,11 @@ async fn pattern4_src_does_not_exist_no_misleading_suggestion() {
|
||||
);
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
// Pattern 5: Root-level file guesses — model guesses a file exists at the
|
||||
// repo root when it doesn't (CONTRIBUTING.md, .github, etc).
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
#[tokio::test]
|
||||
async fn pattern5_root_file_with_close_match() {
|
||||
// Model asks for "CHANGELOG" (no extension), "CHANGELOG.md" exists.
|
||||
let (_tmp, root) = setup_fs(&[], &["CHANGELOG.md"]);
|
||||
let cwd = root.clone();
|
||||
let missing = root.join("CHANGELOG");
|
||||
@@ -316,7 +285,6 @@ async fn pattern5_root_file_with_close_match() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn pattern5_root_file_no_match() {
|
||||
// Model asks for a crate-like name that is not a path at root.
|
||||
let (_tmp, root) = setup_fs(&["crates", "scripts"], &["Cargo.toml", "Cargo.lock"]);
|
||||
let cwd = root.clone();
|
||||
let missing = root.join("example-cli-tool");
|
||||
@@ -332,14 +300,11 @@ async fn pattern5_root_file_no_match() {
|
||||
);
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
// format_not_found_error — integration tests verifying the full formatted
|
||||
// output string for each major pattern.
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
#[tokio::test]
|
||||
async fn format_hallucinated_deep_path_with_similar() {
|
||||
// Model asks for wrong leaf in a deep path where parent exists.
|
||||
let (_tmp, root) = setup_fs(
|
||||
&["src/components"],
|
||||
&[
|
||||
@@ -369,7 +334,6 @@ async fn format_hallucinated_deep_path_with_similar() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn format_hints_disabled_bare_error() {
|
||||
// When hints are off, output must be identical to the old behavior.
|
||||
let (_tmp, root) = setup_fs(&["src"], &["src/real.rs"]);
|
||||
let cwd = root.clone();
|
||||
let missing = root.join("src/fake.rs");
|
||||
@@ -390,7 +354,6 @@ async fn format_hints_disabled_bare_error() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn format_no_match_just_cwd_note() {
|
||||
// When nothing matches, the output should just have the CWD note.
|
||||
let (_tmp, root) = setup_fs(&[], &["totally_unrelated.py"]);
|
||||
let cwd = root.clone();
|
||||
let missing = root.join("xyz_nonexistent");
|
||||
@@ -408,11 +371,12 @@ async fn format_no_match_just_cwd_note() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn format_dropped_folder_shows_display_path() {
|
||||
// Dropped-folder suggestion must use display path in final output.
|
||||
let (_tmp, root) = setup_fs(&["repo/src"], &[]);
|
||||
let cwd = root.join("repo");
|
||||
let display_cwd = &cwd; // same for simplicity
|
||||
let bad_path = root.join("src"); // dropped "repo"
|
||||
// display and resolved cwd are identical here
|
||||
let display_cwd = &cwd;
|
||||
// dropped "repo"
|
||||
let bad_path = root.join("src");
|
||||
|
||||
let msg = format_not_found_error(&bad_path, &bad_path, &cwd, display_cwd, true).await;
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
//! Integration tests for the shared web citation counter.
|
||||
//!
|
||||
//! Old tests deleted (Phase 6) — they used removed page-fetch tool impls.
|
||||
//! Citation counter behavior is covered by unit tests on
|
||||
//! [`kigi_tools::types::resources::WebCitationCounter`] and by
|
||||
//! web-tool integration tests that share the counter via Resources.
|
||||
|
||||
Reference in New Issue
Block a user