E0-threshold patch bench-verified: PASS at E0000105; counter semantics corrected

Display observation (Cyd, on-cabinet): held F0000000 through the clean
handshake and four NAK-then-ACK sub-threshold cycles, flipped exactly at
the 5th teardown to E0000105. That reading recalibrates the counters:
$3184 counts give-up cycles (not per-retransmit) and $3185 counts
teardowns of any imperfect reply cycle — the counter behind the original
lone E0000001. Also recorded: 5 retransmits per cycle (not 4), reply-
await arms only after the complete frame, NAK forces exactly one counted
retransmit, and a late ACK cannot rescue a cycle once retries begin.
Tool predictor updated to the confirmed semantics.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-19 15:39:03 -05:00
co-authored by Claude Fable 5
parent 6b02eb4d1b
commit b5e2ad35af
+16 -13
View File
@@ -170,19 +170,22 @@ internal static class E0Test
}
// Handshake bookkeeping: fold any retries/give-up into the prediction.
// Bench-calibrated counter semantics (2026-07-19, confirmed on the
// display): $3184 = timeout-retry cycles (give-ups), $3185 = reply
// teardowns, i.e. any cycle that needed at least one retransmission.
await Task.Delay(300);
byte[] hs = Drain();
int retx = Math.Max(0, CountAll(0x86) - 1); // $3184 prediction
int giveup = SeenAll(0xFE) ? 1 : 0; // $3185 prediction
int cycles = SeenAll(0xFE) ? 1 : 0; // $3184 prediction
int teardowns = CountAll(0x86) > 1 ? 1 : 0; // $3185 prediction
Console.WriteLine();
Console.WriteLine($"== E0-threshold test :: {transport.Description}, firmware {version?.Major}.{version?.Minor} ==");
Console.WriteLine($" threshold {Threshold}; phase A: {holdEvents} sub-threshold event(s), phase B: {flipEvents} give-up event(s)");
if (retx > 0 || giveup > 0)
Console.WriteLine($" note: handshake cost {retx} retransmit(s){(giveup > 0 ? " + a give-up" : "")}; predictions include them.");
if (cycles > 0 || teardowns > 0)
Console.WriteLine($" note: handshake was not clean (teardowns={teardowns}, give-ups={cycles}); predictions include it.");
Console.WriteLine(" HANDS OFF buttons/keypads for the whole run.");
Console.WriteLine();
string expected = Expected(retx, giveup);
string expected = Expected(cycles, teardowns);
Console.WriteLine($">>> WATCH THE 8-DIGIT DISPLAY. It should read {expected} right now. <<<");
await Task.Delay(4000);
@@ -196,7 +199,7 @@ internal static class E0Test
Console.WriteLine();
Console.WriteLine("== done ==");
Console.WriteLine($" final predicted counters: retx=${retx:X2} giveup=${giveup:X2} -> display {Expected(retx, giveup)}");
Console.WriteLine($" final predicted counters: $3184=${cycles:X2} $3185=${teardowns:X2} -> display {Expected(cycles, teardowns)}");
Console.WriteLine(" PASS = display held F0000000 through every sub-threshold line above and");
Console.WriteLine(" matched the E0 predictions after the threshold crossing.");
Console.WriteLine(" (Stock firmware flips at the very first retry.) DTR reset restores F0.");
@@ -225,19 +228,19 @@ internal static class E0Test
return false;
}
retx += Math.Max(0, transmissions - 1);
if (sawRestart) giveup++;
if (transmissions > 1) teardowns++; // $3185: imperfect cycle
if (sawRestart && mode == AckMode.Never) cycles++; // $3184: give-up
Console.WriteLine($"[event {eventNo}] {phase}: reply x{transmissions} " +
$"({transmissions - 1} retries), give-up={sawRestart} " +
$"-> retx=${retx:X2} giveup=${giveup:X2}");
Console.WriteLine($" >>> DISPLAY SHOULD NOW READ: {Expected(retx, giveup)} <<<");
$"({transmissions - 1} retransmit(s)), give-up cycle={mode == AckMode.Never} " +
$"-> $3184=${cycles:X2} $3185=${teardowns:X2}");
Console.WriteLine($" >>> DISPLAY SHOULD NOW READ: {Expected(cycles, teardowns)} <<<");
await Task.Delay(4000);
return true;
}
string Expected(int r, int g) =>
r >= Threshold || g >= Threshold ? $"E000{r:X2}{g:X2}" : "F0000000";
string Expected(int cy, int td) =>
cy >= Threshold || td >= Threshold ? $"E000{cy:X2}{td:X2}" : "F0000000";
byte[] Drain()
{