fix: 6 bugs found during fresh-eyes code review

1. cache: record diagnostic miss before early-return on modified()/duration_since() failure
2. dump-state: resolve all cache_dir template vars ({cache_version}, {config_hash})
3. config: remove dead breakpoint_hysteresis field from GlobalConfig (breakpoints.hysteresis is used)
4. config: align Rust Default cache_dir with defaults.json template
5. vcs: apply branch truncation in render_stale_cache (--no-shell path)
6. vcs: fix jj prefetch retry on already-failed command (flatten→unwrap_or_else)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Taylor Eernisse
2026-02-06 16:11:02 -05:00
parent 4c9139ec42
commit 4e38b8259b
4 changed files with 45 additions and 29 deletions

View File

@@ -229,6 +229,7 @@ fn main() {
vcs_type,
project_dir,
&session,
&config_hash,
&ctx,
);
return;
@@ -404,6 +405,7 @@ fn dump_state_output(
vcs: section::VcsType,
project_dir: &str,
session_id: &str,
config_hash: &str,
ctx: &RenderContext,
) {
// Render all sections with per-section timing
@@ -468,7 +470,10 @@ fn dump_state_output(
"cache": cache_diags,
"paths": {
"project_dir": project_dir,
"cache_dir": config.global.cache_dir.replace("{session_id}", session_id),
"cache_dir": config.global.cache_dir
.replace("{session_id}", session_id)
.replace("{cache_version}", &config.global.cache_version.to_string())
.replace("{config_hash}", config_hash),
},
"session_id": session_id,
});

View File

@@ -95,8 +95,20 @@ impl Cache {
return None;
}
};
let modified = meta.modified().ok()?;
let age = SystemTime::now().duration_since(modified).ok()?;
let modified = match meta.modified().ok() {
Some(m) => m,
None => {
self.record_diag(key, false, None);
return None;
}
};
let age = match SystemTime::now().duration_since(modified).ok() {
Some(a) => a,
None => {
self.record_diag(key, false, None);
return None;
}
};
let age_ms = age.as_millis() as u64;
let effective_ttl = self.jittered_ttl(key, ttl);
if age < effective_ttl {

View File

@@ -69,7 +69,6 @@ pub struct GlobalConfig {
pub shell_env: HashMap<String, String>,
pub cache_version: u32,
pub drop_strategy: String,
pub breakpoint_hysteresis: u16,
}
impl Default for GlobalConfig {
@@ -80,7 +79,7 @@ impl Default for GlobalConfig {
vcs: "auto".into(),
width: None,
width_margin: 4,
cache_dir: "/tmp/claude-sl-{session_id}".into(),
cache_dir: "/tmp/claude-sl-{session_id}-{cache_version}-{config_hash}".into(),
cache_gc_days: 7,
cache_gc_interval_hours: 24,
cache_ttl_jitter_pct: 10,
@@ -100,7 +99,6 @@ impl Default for GlobalConfig {
shell_env: HashMap::new(),
cache_version: 1,
drop_strategy: "tiered".into(),
breakpoint_hysteresis: 2,
}
}
}

View File

@@ -30,7 +30,13 @@ pub fn render(ctx: &RenderContext) -> Option<SectionOutput> {
/// Serve stale cached VCS data without running any commands.
fn render_stale_cache(ctx: &RenderContext) -> Option<SectionOutput> {
let branch = ctx.cache.get_stale("vcs_branch")?;
let branch_raw = ctx.cache.get_stale("vcs_branch")?;
let trunc = &ctx.config.sections.vcs.truncate;
let branch = if trunc.enabled && trunc.max > 0 {
crate::format::truncate(&branch_raw, trunc.max, &trunc.style)
} else {
branch_raw
};
let branch_glyph = glyph::glyph("branch", &ctx.config.glyphs);
let raw = format!("{branch_glyph}{branch}");
let ansi = if ctx.color_enabled {
@@ -164,13 +170,8 @@ fn render_jj(
let branch_ttl = Duration::from_secs(ttl.branch);
let branch = ctx.cache.get("vcs_branch", branch_ttl).or_else(|| {
// Use prefetched result if available
let out = ctx
.shell_results
.get("vcs")
.cloned()
.flatten()
.or_else(|| {
// Use prefetched result if available, otherwise exec
let out = ctx.shell_results.get("vcs").cloned().unwrap_or_else(|| {
shell::exec_gated(
ctx.shell_config,
"jj",