When the distiller's cut is smaller than the marker that would announce it, and the ledger
then folds the reply, those bytes are unreachable and unannounced. That is the one thing
this pipeline is not allowed to do.
Found by Greptile on #777 and confirmed. The bound is small and exact: the arm is reached
only when distilled_len + marker.len() >= content.len(), so the loss is under roughly 80
bytes, and in the reported case it was one byte. Before #777 the reply passed through in
that situation, so nothing was lost; keeping the ledger's fold is what makes the cut
survive without a handle.
Why it is not a patch
Three shapes were tried on #777 and each one broke a guard that already exists.
Print the marker anyway. That is the double accounting #775 was filed for: a
1 bytes omitted line on top of fold markers that already account for every line.
Refuse the cut before the ledger runs. a_dropped_reply_books_no_saving goes red.
Reverting final_out before record_trace makes execution_traces store the raw and
distilled columns as one string, which removes the only corpus that measures distiller
behaviour without going through OMNI's own books. That test's comment records a previous
fix making the same mistake.
Snapshot the distiller's output for the trace, revert what is delivered. This works
only if the trace's distilled column is meant to be pre-ledger. Today it is post-ledger,
so the change alters what every recorded trace means, which is a corpus change and needs to
be a decision rather than a side effect.
The decision
One of three, and it is a call rather than a patch:
execution_traces.distilled becomes explicitly the distiller's output, pre-ledger, and
the revert is safe. Changes what the corpus means, so it needs saying and dating.
- The ledger is handed the raw content when the distiller's cut is below the floor. Costs
a comparison and keeps every stage's accounting separate.
- The sub-marker cut is accepted as a bounded, documented loss, written into the manual's
guarantee rather than left in a code comment.
I would take 2, since it keeps each stage answering for its own bytes and needs no corpus
change, but it is worth measuring how often the floor is actually reached before choosing.
When the distiller's cut is smaller than the marker that would announce it, and the ledger
then folds the reply, those bytes are unreachable and unannounced. That is the one thing
this pipeline is not allowed to do.
Found by Greptile on #777 and confirmed. The bound is small and exact: the arm is reached
only when
distilled_len + marker.len() >= content.len(), so the loss is under roughly 80bytes, and in the reported case it was one byte. Before #777 the reply passed through in
that situation, so nothing was lost; keeping the ledger's fold is what makes the cut
survive without a handle.
Why it is not a patch
Three shapes were tried on #777 and each one broke a guard that already exists.
Print the marker anyway. That is the double accounting #775 was filed for: a
1 bytes omittedline on top of fold markers that already account for every line.Refuse the cut before the ledger runs.
a_dropped_reply_books_no_savinggoes red.Reverting
final_outbeforerecord_tracemakesexecution_tracesstore the raw anddistilled columns as one string, which removes the only corpus that measures distiller
behaviour without going through OMNI's own books. That test's comment records a previous
fix making the same mistake.
Snapshot the distiller's output for the trace, revert what is delivered. This works
only if the trace's
distilledcolumn is meant to be pre-ledger. Today it is post-ledger,so the change alters what every recorded trace means, which is a corpus change and needs to
be a decision rather than a side effect.
The decision
One of three, and it is a call rather than a patch:
execution_traces.distilledbecomes explicitly the distiller's output, pre-ledger, andthe revert is safe. Changes what the corpus means, so it needs saying and dating.
a comparison and keeps every stage's accounting separate.
guarantee rather than left in a code comment.
I would take 2, since it keeps each stage answering for its own bytes and needs no corpus
change, but it is worth measuring how often the floor is actually reached before choosing.