From 9bfeb2c6a27684d1e37454cb01d7581a8c9b222d Mon Sep 17 00:00:00 2001 From: "Claude (sandbox)" Date: Mon, 13 Jul 2026 12:10:06 +0000 Subject: [PATCH] feat(causal): ledger-audit output in the pipeline demo and attrib probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - causal_pipeline: SMARM_CAUSAL_AUDIT=1 appends render_ledger_audit() after the summary; pinned summary format untouched. - causal_attrib_probe: per-pct audit line (absorbed/forgiven/drops/ discards) under the existing eff line, so in-site-vs-attributed and the loss buckets land in one place for the sweep. 1-core smoke (work + wide): books balance — absorbed = 2x injected and forgiven = 2x injected, i.e. owed = injected x (N-1) with N=5 actors, zero outstanding. drop park = 0 even in wide mode (the bottleneck's queue is never empty, so its in-guard recv never parks); drop yield is ~1500 events but ~0.1ms per window, confirming slice-expiry yields sample at their own checkpoint. Deficit decomposition needs the parallel box. --- .gitignore | 1 + examples/causal_attrib_probe.rs | 18 ++++++++++++++++++ examples/causal_pipeline.rs | 6 ++++++ 3 files changed, 25 insertions(+) diff --git a/.gitignore b/.gitignore index f63a5bb..1879489 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ smarm_trace.json /bench_results/ __pycache__/ *.pyc +profile.coz diff --git a/examples/causal_attrib_probe.rs b/examples/causal_attrib_probe.rs index 7f777f4..2663669 100644 --- a/examples/causal_attrib_probe.rs +++ b/examples/causal_attrib_probe.rs @@ -136,9 +136,11 @@ fn main() { let g0 = smarm::causal::global_delay_cycles(); let s0 = IN_SITE_CYCLES.load(Ordering::Relaxed); let e0 = SITE_ENTRIES.load(Ordering::Relaxed); + let a0 = smarm::causal::ledger_counters(); smarm::causal::begin_experiment_for_test("reserve", pct); smarm::sleep(Duration::from_millis(1000)); smarm::causal::end_experiment_for_test(); + let audit = smarm::causal::ledger_counters().delta_since(&a0); let injected = smarm::causal::global_delay_cycles() - g0; let in_site = IN_SITE_CYCLES.load(Ordering::Relaxed) - s0; let entries = SITE_ENTRIES.load(Ordering::Relaxed) - e0; @@ -156,6 +158,22 @@ fn main() { in_site as f64 / hz * 1e3, attributed / hz * 1e3, ); + // RFC 007 deficit hunt: name the losses. Drop/discard columns are + // in would-be delta terms — divide by pct/100 to compare with the + // missing attribution above. + let ms = |c: u64| c as f64 / hz * 1e3; + println!( + " audit: absorbed {:>7.1}ms forgiven {:>6.1}ms drop park {:>5.2}ms/{:<5} yield {:>5.2}ms/{:<5} discard >max {:>5.2}ms/{:<3} unarmed {}", + ms(audit.spin_absorbed_cycles), + ms(audit.park_forgiven_cycles), + ms(audit.drop_park_cycles), + audit.drop_park_n, + ms(audit.drop_yield_cycles), + audit.drop_yield_n, + ms(audit.discard_overmax_cycles), + audit.discard_overmax_n, + audit.discard_unarmed_n + ); smarm::sleep(Duration::from_millis(150)); } diff --git a/examples/causal_pipeline.rs b/examples/causal_pipeline.rs index f50ae5f..7ae8eb3 100644 --- a/examples/causal_pipeline.rs +++ b/examples/causal_pipeline.rs @@ -247,6 +247,12 @@ fn main() { background.join().unwrap(); print!("{}", smarm::causal::render_summary(&results)); + // RFC 007 deficit hunt: SMARM_CAUSAL_AUDIT=1 appends the per-cell + // ledger audit (injected/absorbed/forgiven + drop and discard + // buckets) without touching the pinned summary format. + if std::env::var_os("SMARM_CAUSAL_AUDIT").is_some() { + print!("{}", smarm::causal::render_ledger_audit(&results)); + } let coz = smarm::causal::render_coz(&results); match std::fs::write("profile.coz", coz) { Ok(()) => println!("\nwrote profile.coz"),