pub struct Evidence {Show 18 fields
pub runs: usize,
pub sessions_read: usize,
pub model: String,
pub tool_calls: u64,
pub tool_errors: u64,
pub tool_error_rate: Option<f64>,
pub ended_on_failed_call: usize,
pub ended_on_failed_call_rate: Option<f64>,
pub compactions: u64,
pub stop_causes: Vec<(String, usize)>,
pub mean_peak_context_pressure: Option<f64>,
pub mean_anticipated_guilt: Option<f64>,
pub tool_denied: u64,
pub blocked_sends: u64,
pub metrics: Vec<(Metric, f64, usize)>,
pub workspaces: Vec<(String, usize)>,
pub findings: Vec<String>,
pub history: Vec<String>,
}Expand description
Everything the diagnostician is allowed to be handed about a corpus.
Numbers and findings. There is no field for a transcript excerpt, no constructor that takes one, and that absence is the safety property — see the module docs.
Fields§
§runs: usize§sessions_read: usize§model: String§tool_calls: u64§tool_errors: u64§tool_error_rate: Option<f64>§ended_on_failed_call: usize§ended_on_failed_call_rate: Option<f64>§compactions: u64§stop_causes: Vec<(String, usize)>§mean_peak_context_pressure: Option<f64>Average Homeostat::peak_context_pressure over the runs that sensed
it (docs/GOAL-SYSTEM-DESIGN.md §4 into this brief) — the machine’s
own conditions, beside what runs did. A counter like every other
field here: the diagnostician judges what a high number means, this
module only reports it.
mean_anticipated_guilt: Option<f64>Average Homeostat::anticipated_guilt over the runs that sensed it
(crate::guilt). The sensor has no behavioural consumer yet; this is
the corpus existing before anything is built on it.
Not independent of Self::mean_peak_context_pressure above it.
crate::guilt::anticipated_guilt’s own formula takes context pressure
as one of its three terms, so the two fields will move together by
construction whenever pressure is what is driving guilt up — a reader
treating a rise in both as two corroborating signals is seeing one
cause twice.
tool_denied: u64Calls a human or a policy refused, and sends the interlock refused.
Reported beside the error rate rather than folded into it, because the two are opposite findings: an error is the environment failing a call, a denial is the harness working. Without the split a diagnostician shown one rate has to guess which it is looking at, and on 2026-08-25 and 2026-08-26 it guessed twice — attributing the same ~9% first to taint propagation and then to schema validation, with nothing in the brief able to support or refute either.
blocked_sends: u64§metrics: Vec<(Metric, f64, usize)>What each metric a proposal may name currently costs: its mean over the corpus, and how many runs have any of it to reduce.
Built from Metric::ALL rather than written out, so this list and
the one in DIAGNOSE_INSTRUCTION cannot drift apart — which they
had, in the direction that matters: six metrics offered, three
reported.
workspaces: Vec<(String, usize)>Where these runs were rooted, commonest first, with a count each.
The corpus is a mixture, and pooling it averages four different
jobs. A morning-briefing run, a front-door run, a smoke test in
/tmp and a feature test in the source checkout have different normal
behaviour; a rate over all of them describes none of them. Reported so
the diagnostician can say “this is concentrated in one job” instead of
treating the average as a property of the harness — and so a reader can
see when a number came almost entirely from one place.
A path is machine-recorded from the session header, never model-authored.
findings: Vec<String>What doctor said, verbatim — machine-authored text, not third-party.
history: Vec<String>What earlier passes already tried, one line each — machine-authored from the harness candidate store, the way the learner is shown retired rules. Without it a nightly diagnostician re-derives the same rejected change forever, and every night costs a measurement that was already paid for.