Skip to content

Commit f26c842

Browse files
hyperpolymathclaude
andcommitted
chore: sync local changes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a31422c commit f26c842

File tree

8 files changed

+99
-56
lines changed

8 files changed

+99
-56
lines changed

.hypatia/activity.jsonl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"timestamp":"2026-03-08T02:05:04Z","bot":"hypatia-autofix","action":"scan","details":"fixes=0"}

.hypatia/last-visit.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"last_visit": "2026-03-08T02:05:04Z",
3+
"last_bot": "hypatia-autofix",
4+
"last_action": "scan",
5+
"visits_total": 1
6+
}

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ opt-level = 3
4747
lto = "thin"
4848
codegen-units = 1
4949
strip = "symbols"
50-
panic = "abort"
50+
panic = "unwind"
5151

5252
[[bin]]
5353
name = "panic-attack"

src/abduct/mod.rs

Lines changed: 39 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -303,27 +303,45 @@ fn collect_selected_files(
303303
}
304304
DependencyScope::Direct | DependencyScope::TwoHops => {
305305
let maybe_target_rel = target.strip_prefix(source_root).ok();
306-
if maybe_target_rel.is_none() {
307-
notes.push(
308-
"target is outside --source-root; dependency scope fell back to target only"
309-
.to_string(),
310-
);
311-
} else if let Ok(report) = assail::analyze(source_root) {
312-
let target_rel = maybe_target_rel
313-
.expect("checked is_some")
314-
.to_string_lossy()
315-
.to_string();
316-
let depth = if scope == DependencyScope::Direct {
317-
1
306+
if let Some(target_rel_path) = maybe_target_rel {
307+
if let Ok(report) = assail::analyze(source_root) {
308+
let target_rel = target_rel_path
309+
.to_string_lossy()
310+
.to_string();
311+
let depth = if scope == DependencyScope::Direct {
312+
1
313+
} else {
314+
2
315+
};
316+
let rel_nodes =
317+
related_nodes_from_graph(&target_rel, &report.dependency_graph.edges, depth);
318+
if rel_nodes.len() <= 1 {
319+
notes.push(
320+
"no direct dependency neighbors found; falling back to same directory"
321+
.to_string(),
322+
);
323+
if let Some(parent) = target.parent() {
324+
for entry in fs::read_dir(parent)
325+
.with_context(|| format!("reading directory {}", parent.display()))?
326+
{
327+
let entry = entry?;
328+
let path = entry.path();
329+
if path.is_file() {
330+
selected.insert(path);
331+
}
332+
}
333+
}
334+
} else {
335+
for rel in rel_nodes {
336+
let abs = source_root.join(&rel);
337+
if abs.is_file() {
338+
selected.insert(abs);
339+
}
340+
}
341+
}
318342
} else {
319-
2
320-
};
321-
let rel_nodes =
322-
related_nodes_from_graph(&target_rel, &report.dependency_graph.edges, depth);
323-
if rel_nodes.len() <= 1 {
324343
notes.push(
325-
"no direct dependency neighbors found; falling back to same directory"
326-
.to_string(),
344+
"assail dependency analysis failed; fell back to same directory".to_string(),
327345
);
328346
if let Some(parent) = target.parent() {
329347
for entry in fs::read_dir(parent)
@@ -336,29 +354,12 @@ fn collect_selected_files(
336354
}
337355
}
338356
}
339-
} else {
340-
for rel in rel_nodes {
341-
let abs = source_root.join(&rel);
342-
if abs.is_file() {
343-
selected.insert(abs);
344-
}
345-
}
346357
}
347358
} else {
348359
notes.push(
349-
"assail dependency analysis failed; fell back to same directory".to_string(),
360+
"target is outside --source-root; dependency scope fell back to target only"
361+
.to_string(),
350362
);
351-
if let Some(parent) = target.parent() {
352-
for entry in fs::read_dir(parent)
353-
.with_context(|| format!("reading directory {}", parent.display()))?
354-
{
355-
let entry = entry?;
356-
let path = entry.path();
357-
if path.is_file() {
358-
selected.insert(path);
359-
}
360-
}
361-
}
362363
}
363364
}
364365
}

src/ambush/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ pub fn execute_timeline(
119119
thread::sleep(Duration::from_millis(25));
120120
}
121121
let peak_memory = stress.stop();
122-
let mut reports = reports.lock().expect("timeline report lock");
122+
let mut reports = reports.lock().unwrap_or_else(|e| e.into_inner());
123123
reports.push(TimelineEventReport {
124124
id: event.id,
125125
axis: event.axis,
@@ -135,7 +135,7 @@ pub fn execute_timeline(
135135
ran: true,
136136
});
137137
} else {
138-
let mut reports = reports.lock().expect("timeline report lock");
138+
let mut reports = reports.lock().unwrap_or_else(|e| e.into_inner());
139139
reports.push(TimelineEventReport {
140140
id: event.id,
141141
axis: event.axis,
@@ -178,7 +178,7 @@ pub fn execute_timeline(
178178
};
179179

180180
let event_reports = {
181-
let mut reports = reports.lock().expect("timeline report lock");
181+
let mut reports = reports.lock().unwrap_or_else(|e| e.into_inner());
182182
reports.sort_by_key(|report| report.start_offset);
183183
reports.clone()
184184
};
@@ -389,7 +389,7 @@ fn spawn_network_stress(
389389

390390
for _ in 0..clients {
391391
let stop = stop.clone();
392-
let addr = addr.clone();
392+
let addr = addr;
393393
threads.push(thread::spawn(move || {
394394
let payload = vec![0x5A_u8; 4096];
395395
while !stop.load(Ordering::Relaxed) && Instant::now() < deadline {

src/assemblyline.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,11 +184,22 @@ fn collect_source_hashes(
184184
Ok(())
185185
}
186186

187-
/// Hash a single file with BLAKE3 using memory-mapped I/O for performance
187+
/// Hash a single file with BLAKE3 using memory-mapped I/O for performance.
188+
///
189+
/// Falls back to buffered read if mmap fails (e.g. symlinks to deleted files,
190+
/// special files, permission issues, or files that vanish during parallel scan).
188191
fn hash_file(path: &Path) -> Result<blake3::Hash> {
189192
let mut hasher = blake3::Hasher::new();
190-
hasher.update_mmap(path)?;
191-
Ok(hasher.finalize())
193+
match hasher.update_mmap(path) {
194+
Ok(_) => Ok(hasher.finalize()),
195+
Err(_) => {
196+
// Fallback: read the file into memory instead of mmap
197+
let content = fs::read(path)?;
198+
let mut hasher = blake3::Hasher::new();
199+
hasher.update(&content);
200+
Ok(hasher.finalize())
201+
}
202+
}
192203
}
193204

194205
/// Check if a file has a known source code extension

src/main.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -574,8 +574,8 @@ enum Commands {
574574
bundle_size: bool,
575575

576576
/// Store snapshot as VeriSimDB hexad
577-
#[arg(long, default_value_t = false)]
578-
store: bool,
577+
#[arg(long = "store-hexad", default_value_t = false)]
578+
store_hexad: bool,
579579

580580
/// Output snapshot to file
581581
#[arg(short, long)]
@@ -1726,12 +1726,13 @@ fn run_main() -> Result<()> {
17261726
cache_file: cache_file.clone(),
17271727
};
17281728

1729-
if cache_file.is_some() && !cli.quiet {
1730-
let cf = cache_file.as_ref().unwrap();
1731-
if cf.exists() {
1732-
println!("Incremental mode: loading cache from {}", cf.display());
1733-
} else {
1734-
println!("Incremental mode: first run (cache will be saved to {})", cf.display());
1729+
if let Some(cf) = &cache_file {
1730+
if !cli.quiet {
1731+
if cf.exists() {
1732+
println!("Incremental mode: loading cache from {}", cf.display());
1733+
} else {
1734+
println!("Incremental mode: first run (cache will be saved to {})", cf.display());
1735+
}
17351736
}
17361737
}
17371738

@@ -1821,7 +1822,7 @@ fn run_main() -> Result<()> {
18211822
label,
18221823
build_time,
18231824
bundle_size,
1824-
store,
1825+
store_hexad,
18251826
output,
18261827
} => {
18271828
qprintln!(
@@ -1929,7 +1930,7 @@ fn run_main() -> Result<()> {
19291930
println!("{}", json);
19301931
}
19311932

1932-
if store {
1933+
if store_hexad {
19331934
qprintln!(cli.quiet, "VeriSimDB storage for snapshots: planned");
19341935
}
19351936

system-image.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"format": "panic-attack.system-image.v1",
3+
"generated_at": "2026-03-13T11:28:26.200902216+00:00",
4+
"scan_surface": ".",
5+
"node_count": 0,
6+
"edge_count": 0,
7+
"global_health": 1.0,
8+
"global_risk": 0.0,
9+
"total_weak_points": 0,
10+
"total_critical": 0,
11+
"total_lines": 0,
12+
"total_files": 0,
13+
"repos_scanned": 0,
14+
"nodes": [],
15+
"edges": [],
16+
"risk_distribution": {
17+
"healthy": 0,
18+
"low": 0,
19+
"moderate": 0,
20+
"high": 0,
21+
"critical": 0
22+
}
23+
}

0 commit comments

Comments
 (0)