D470 - A run that wrote no trace reports nothing, rather than reprinting an old one

measured - 2026-09-02 (user-directed /loop; corrects D469)

What actually happened

cmd_run reads the stored trace after the worker exits, on the reasoning that the worker has just written it:

// After the worker has exited, so the trace it wrote is complete.
if let Some(after) = previous_trace(path) {

"the trace it wrote" was an assumption, not a check. When the worker dies without writing one, the file read back is the previous run's. It is then compared against itself - before and after are the same bytes - so the verdict reads same - nothing moved, the fault block shows the old fault, and the findings list the old unimplemented functions. Every line is presented as this run's measurement and none of it is.

For PPSA02664 the stored trace was from 01:50; _Getpctype was implemented at 10:13. Every run after that read the 01:50 file. That is why six runs gave byte-identical reports and read as "deterministic": they were one file.

The A/B that settled it, on one build, changing only whether the ctype implementations are registered:

trace written? what the report showed
without ctype yes, fresh guest faults at 0xb14be3 dereferencing _Getpctype's placeholder
with ctype no the 01:50 file, unchanged

So the original diagnosis was right

D443 / D450 / D459 were correct: _Getpctype is the wall in that branch, and the guest does dereference its placeholder. D469's conclusion - that the report mislabels the faulting call - is wrong, and D469 now says so at the top. Its individual measurements stand (index 54 is bound, is called 415 times, and never answers a placeholder); what was wrong was reading a stale report as evidence about the current build.

And the ctype work moved the wall. With it, the guest gets past 0xb14be3 and dies somewhere the worker cannot report. That is progress that was invisible, reported as same.

The change

orbistoun_report::trace::Stamp (modified time and length, because either alone can repeat) and a pure wrote_a_trace(before, after). cmd_run takes a stamp beside before, and afterwards either reports or says plainly:

this run recorded no trace, so there is nothing of its own to report.

The pure/effectful split is the shape orbistoun-mem established, so the decision is testable without a filesystem, and it lives in orbistoun-report rather than the CLI so the GUI reaches the same verdict from the same rule (principle 13, D160). Four tests, and the first is the guard made to fail: an unchanged stamp must read as "no trace from this run". Verified both ways on real runs - it fires for PPSA02664 and stays silent for PPSA04263, which does write one.

Why so much instrumentation reported nothing

The honest answer, because it is the general lesson. Every probe this project has is inside the process that dies and runs after the fault: the handler collects registers, walks frames, reads guest memory to name the fault site, allocates, and serialises JSON. Any of those can fault again - and a second fault inside a fault handler is not reported, it is the end of the process. Nothing was missing from the instrumentation; the instrumentation was downstream of the thing that broke.

What was missing was a check that a measurement happened at all. The run had a hundred ways to describe a trace and no way to notice it had not got one - so absence borrowed the previous run's presence. That is the same failure as the five tools in principle 3's list, and the cheapest possible fix: compare two numbers before believing the file.

Still open

The worker dies unreportably for PPSA02664 with ctype installed, and why is not diagnosed here. The candidates are a nested fault inside the fault handler, a stack overflow (whose guard page leaves no room to report), or a crash inside orbistoun's own code where the guest-fault path's assumptions do not hold. The next run should find out, and it now has honest tooling to do it with.