scratch(micromate): pin the probe's control to THOR's 1024, not the new default

The probe compared each candidate request size against a "known-good" download
that used micromate's DEFAULT chunk size -- which is now 16,384.  That makes the
experiment circular: if 16 KB is broken on a given link, the reference is broken
the same way and every comparison passes.

The control is now pinned to THOR_CHUNK_SIZE.  1024 is the size with THOR's own
captures behind it and the only one proven over a cellular modem, so it is the
thing to measure against.

Also raised the default idle gap from 2 s to 3 s.  A 16 KB response is ~1.4 s of
serial time at 115200 before the modem's ~1 s forwarding delay, and too small a
gap makes a slow link look like a clamp -- which would read as a device limit
that is really a timeout.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ru8Lg9HkkYvX9VWWo65SmL
This commit is contained in:
2026-10-02 15:00:02 -04:00
co-authored by Claude Opus 5
parent 423608ccd1
commit eefc846c8c
+19 -11
View File
@@ -52,7 +52,7 @@ sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "bridges"))
from micromate.client import MicromateClient, _content # noqa: E402 from micromate.client import MicromateClient, _content # noqa: E402
from micromate.framing import MicromateFrameParser, build_request # noqa: E402 from micromate.framing import MicromateFrameParser, build_request # noqa: E402
from micromate.protocol import SUB_BULK_DOWNLOAD # noqa: E402 from micromate.protocol import SUB_BULK_DOWNLOAD, THOR_CHUNK_SIZE # noqa: E402
from mm_client_check import StdlibSerial # noqa: E402 from mm_client_check import StdlibSerial # noqa: E402
from minimateplus.transport import TcpTransport # noqa: E402 from minimateplus.transport import TcpTransport # noqa: E402
@@ -83,9 +83,11 @@ def main() -> int:
ap.add_argument("--event", default="smallest", ap.add_argument("--event", default="smallest",
help="a key in hex, 'smallest' (default — the gentlest " help="a key in hex, 'smallest' (default — the gentlest "
"first test) or 'largest' (the one that matters)") "first test) or 'largest' (the one that matters)")
ap.add_argument("--idle-gap", type=float, default=2.0, ap.add_argument("--idle-gap", type=float, default=3.0,
help="seconds of silence that end a streaming read; 2.0 is " help="seconds of silence that end a read. A 16 KB response "
"generous for a modem, which buffers ~1 s") "is ~1.4 s of serial time at 115200 BEFORE the modem's "
"~1 s forwarding delay, so this is deliberately roomy; "
"too small and a slow link looks like a clamp.")
ap.add_argument("--timeout", type=float, default=90.0) ap.add_argument("--timeout", type=float, default=90.0)
a = ap.parse_args() a = ap.parse_args()
@@ -123,16 +125,22 @@ def main() -> int:
return 2 return 2
ref = matches[0] ref = matches[0]
n_chunks = math.ceil(ref.size / 1024) n_chunks = math.ceil(ref.size / THOR_CHUNK_SIZE)
print(f"\n target: {ref.key_hex} {ref.size} B {ref.record_type} " print(f"\n target: {ref.key_hex} {ref.size} B {ref.record_type} "
f"({n_chunks} chunks the known-good way)") f"({n_chunks} requests at THOR's chunk size)")
# ── 1. the known-good chunk loop ────────────────────────────────────── # ── 1. the control: THOR's 1024-byte chunk loop ───────────────────────
# ⚠ Pinned to THOR_CHUNK_SIZE on purpose. The library default is now
# 16,384, and using it here would make the experiment circular -- the
# "known-good" reference would share any fault with the sizes under test.
# 1024 is the size with THOR's own captures behind it and the one proven
# over a modem, so it is the control.
t0 = time.monotonic() t0 = time.monotonic()
chunked = mm.protocol.read_event_file(ref.key, ref.size) chunked = mm.protocol.read_event_file(ref.key, ref.size,
chunk_size=THOR_CHUNK_SIZE)
dt_chunked = time.monotonic() - t0 dt_chunked = time.monotonic() - t0
print(f"\n [1] chunk loop ...... {len(chunked)} B in {dt_chunked:.2f} s " print(f"\n [1] control ......... {len(chunked)} B in {dt_chunked:.2f} s "
f"({n_chunks} requests)") f"({n_chunks} requests at THOR's 1024 B)")
# ── 2. how many bytes will it serve in ONE frame? ───────────────── # ── 2. how many bytes will it serve in ONE frame? ─────────────────
# The streaming hypothesis is dead (see the module docstring): `offset` # The streaming hypothesis is dead (see the module docstring): `offset`
@@ -176,7 +184,7 @@ def main() -> int:
if best is None: if best is None:
print(" VERDICT: nothing above the current chunk size verified.") print(" VERDICT: nothing above the current chunk size verified.")
else: else:
now = math.ceil(ref.size / 1024) now = math.ceil(ref.size / THOR_CHUNK_SIZE)
then = math.ceil(ref.size / best) then = math.ceil(ref.size / best)
print(f" VERDICT: the device serves at least {best} B per request,") print(f" VERDICT: the device serves at least {best} B per request,")
print(f" verified byte-identical. For this {ref.size} B event that") print(f" verified byte-identical. For this {ref.size} B event that")