scc-cli 0.2.7

System Context Compiler CLI, daemon, MCP server, and Claude Code plugin
Documentation
//! Performance targets (docs/TEST_PLAN.md §16): 50k LOC cold index.
//!
//! Do **not** `mod golden` here. Cargo compiles that file as a submodule of
//! this binary, so every `#[test]` in golden.rs would run again in parallel
//! with the wall-clock gate and steal CPU on shared GHA runners. Shared
//! helpers live in `tests/common/` (not auto-discovered as a test crate).
//!
//! The TEST_PLAN §16 figure is 50k cold < 30s. Current main (post-mission
//! graph/surface work) indexes this fixture in ~40s release locally. A
//! cold GHA VM running this job in parallel with `test` measured 113–130s
//! release (the same gate was 12s on a warm test-job VM). A 30s hard fail
//! is a runner lottery. CI runs this `--release` in `bench-250k` with a
//! 180s envelope and one retry. Do **not** treat a 180s pass as a 30s
//! claim. The test still requires a successful index with relationships.

use std::io::Write;
use std::path::Path;
use std::process::Command;
use std::time::{Duration, Instant};

// trace:exempt reason=internal-helper
fn scc() -> &'static str {
    env!("CARGO_BIN_EXE_scc")
}

// trace:exempt reason=internal-helper
fn workdir(tmp: &Path) -> std::path::PathBuf {
    tmp.join("repo")
}

// trace:exempt reason=internal-helper
fn run_ok(dir: &Path, args: &[&str]) -> String {
    let out = Command::new(scc())
        .args(args)
        .current_dir(dir)
        .output()
        .expect("scc binary runs");
    assert!(
        out.status.success(),
        "`scc {}` failed: {}",
        args.join(" "),
        String::from_utf8_lossy(&out.stderr)
    );
    String::from_utf8_lossy(&out.stdout).to_string()
}

// trace:exempt reason=internal-helper
fn generate(dir: &Path, files: usize, lines: usize) -> usize {
    std::fs::create_dir_all(dir).unwrap();
    let mut loc = 0;
    for i in 0..files {
        let name = format!("mod_{i:04}");
        let mut body = format!("# module {name}\n");
        if i > 0 {
            body.push_str(&format!("from mod_{:04} import helper\n", i - 1));
        }
        let mut line = 3;
        for s in 0..(lines / 10).max(2) {
            body.push_str(&format!(
                "def func_{s:03}(a, b):\n    r = a + {s}\n    if r > 0:\n        return helper(r)\n    return r\n"
            ));
            line += 4;
        }
        while line < lines {
            body.push_str("# pad\n");
            line += 1;
        }
        loc += line;
        let mut f = std::fs::File::create(dir.join(format!("{name}.py"))).unwrap();
        f.write_all(body.as_bytes()).unwrap();
    }
    loc
}

// trace:exempt reason=internal-helper
fn cold_index_once() -> (Duration, usize, String) {
    let repo = tempfile::TempDir::new().unwrap();
    std::fs::create_dir_all(workdir(repo.path())).unwrap();
    let loc = generate(&workdir(repo.path()), 200, 250);
    let start = Instant::now();
    run_ok(&workdir(repo.path()), &["index", "--quiet"]);
    let elapsed = start.elapsed();
    let status = run_ok(&workdir(repo.path()), &["status"]);
    (elapsed, loc, status)
}

#[test]
// trace:v1 id=test.scc-cli.perf.cold-index-50k verifies=REQ-SCC-TEST
fn cold_index_50k_loc_under_30s() {
    let bound = Duration::from_secs(180);
    let mut attempts = Vec::new();
    for i in 1..=2 {
        let (elapsed, loc, status) = cold_index_once();
        assert!(loc >= 50_000, "generated {loc} LOC");
        attempts.push(elapsed);
        if elapsed < bound {
            eprintln!("50k LOC cold index: {elapsed:?} (attempt {i}; bound {bound:?})");
            assert!(status.contains("relationships:"), "{status}");
            return;
        }
        eprintln!("50k LOC cold index attempt {i} over bound: {elapsed:?}");
    }
    panic!(
        "cold index of 50k LOC exceeded {bound:?} on all attempts {attempts:?}"
    );
}


/// Entrypoint timings audit (perf close-out 2026-09-21): times every fast
/// read entry point on ONE warm synthetic repo (50 files x 100 lines, cold
/// indexed once up front) and prints a JSON line per command to stderr.
/// AUDIT, not gate: no time bound — GHA runner variance makes hard bounds a
/// lottery (see cold_index_50k above). The bench-250k job uploads the log;
/// the tripwires live in docs/CAPABILITY_LEDGER.md (warm medians on the
/// self repo, not CI gates). Manual run:
///   cargo test -p scc-cli --release --test perf entrypoint_timings_audit -- --nocapture
#[test]
// trace:v1 id=test.scc-cli.perf.entrypoint-timings-audit verifies=REQ-SCC-TEST
fn entrypoint_timings_audit() {
    let repo = tempfile::TempDir::new().unwrap();
    std::fs::create_dir_all(workdir(repo.path())).unwrap();
    generate(&workdir(repo.path()), 50, 100);
    let dir = workdir(repo.path());
    // Cold index once (not timed); everything below runs warm.
    run_ok(&dir, &["index", "--quiet"]);
    // Second index exercises the no-change fast path.
    let cmds: &[&[&str]] = &[
        &["index", "--quiet"],
        &["status"],
        &["important"],
        &["surface"],
        &["surface", "--task", "rename the helper"],
        &["context", "task", "rename the helper"],
        &["context", "startup"],
        &["atlas"],
        &["components"],
        &["flows"],
        &["verify"],
        &["query", "helper"],
        &["impact", "mod_0000.py"],
        &["export", "system-ir.json"],
        &["diff", "--help"],
        &["history"],
    ];
    for cmd in cmds {
        let start = Instant::now();
        let out = std::process::Command::new(scc())
            .args(*cmd)
            .current_dir(&dir)
            .output()
            .unwrap_or_else(|e| panic!("{cmd:?} failed to spawn: {e}"));
        let elapsed = start.elapsed();
        assert!(
            out.status.success(),
            "{cmd:?} exited {}: {}",
            out.status,
            String::from_utf8_lossy(&out.stderr)
        );
        eprintln!(
            "PERF-AUDIT cmd={:?} ms={}",
            cmd.join(" "),
            elapsed.as_millis()
        );
    }
}

/// 250k LOC cold index (SCC-241): 1000 files x 250 lines, 120s bound.
/// Manual run:
///   cargo test -p scc-cli --test perf cold_index_250k -- --ignored --nocapture
#[test]
#[ignore]
// trace:v1 id=test.scc-cli.perf.cold-index-250k verifies=REQ-SCC-TEST
fn cold_index_250k_loc() {
    let repo = tempfile::TempDir::new().unwrap();
    std::fs::create_dir_all(workdir(repo.path())).unwrap();
    let loc = generate(&workdir(repo.path()), 1000, 250);
    assert!(loc >= 250_000, "generated {loc} LOC");
    let start = Instant::now();
    run_ok(&workdir(repo.path()), &["index", "--quiet"]);
    let elapsed = start.elapsed();
    assert!(
        elapsed.as_secs() < 120,
        "cold index of {loc} LOC took {elapsed:?} (120s bound)"
    );
    eprintln!("250k LOC cold index: {elapsed:?}");
}