Follow-up to #179 / PR #181. Not a live break — filing it because PR #181's central argument is left unapplied here, and the adversarial review of that PR flagged the inconsistency.
The pattern
Four rigs probe the current turbo state before deciding whether to write it:
tools/uci/rig_https_live.py:454
tools/uci/rig_https_local.py:1605
tools/uci/rig_https_wiki.py:650
tools/uci/rig_https_bad_finished.py:569
All four do the same thing:
try:
cat = client.get_config_category(CAT_U64_SPECIFIC)
inner = cat.get(CAT_U64_SPECIFIC, cat)
cur_speed, cur_turbo = inner.get("CPU Speed"), inner.get("Turbo Control")
except Exception as exc:
print(f" (turbo probe failed: {exc}; writing anyway)")
cur_speed = cur_turbo = None
inner.get(...) returning None is indistinguishable from "the item was absent", and both routes land on writing anyway.
Why it matters
The write is the hazard. A turbo config write — even a redundant one — glitches the UCI bridge and loses the next command; that is the documented second cause of NO_SOCKET ($88) on the C64U, and the reason these probes exist at all is to skip the write when it would be a no-op. So an unreadable probe degrades toward performing the exact action the probe was added to avoid.
The symptom would be intermittent $88, which the diagnostic ladder points at firmware. This project has a documented history of over-blaming firmware, so a silent degrade in this direction is expensive out of proportion to its rarity.
Not broken today
get_config_category is unchanged — untouched since 2026-04-05 and explicitly not in the scope of c64-test-harness PR #226, which changed only get_config_item. Post-#226, category GETs still return bare values per item, so the existing descent still works. This is a latent hazard, not a current defect.
Why it was deferred out of #181
Deliberately, and the reviewer agreed it was defensible: unlike the REU preflight, the right failure handling is a genuine judgement call rather than an obvious fail-closed. Skipping the write on a failed probe risks running the whole rig at the wrong clock, which invalidates every wall-clock number it produces. Failing the run outright is defensible but costs a device slot. Guessing at that inside a fix for something else would have been the wrong call.
Suggested shape (not prescriptive)
client.get_config_value(CAT_U64_SPECIFIC, "CPU Speed") raises rather than returning None, so the ambiguity disappears at the read. What to do with the raise is the open question — probably: retry once, then abort with a message naming $88 as the thing being avoided, since a rig that cannot establish the clock cannot produce a trustworthy measurement either.
Whatever is chosen needs a red-green test with a faked client, on the model of tools/test_reu_preflight.py — no hardware required to pin this.
Follow-up to #179 / PR #181. Not a live break — filing it because PR #181's central argument is left unapplied here, and the adversarial review of that PR flagged the inconsistency.
The pattern
Four rigs probe the current turbo state before deciding whether to write it:
tools/uci/rig_https_live.py:454tools/uci/rig_https_local.py:1605tools/uci/rig_https_wiki.py:650tools/uci/rig_https_bad_finished.py:569All four do the same thing:
inner.get(...)returningNoneis indistinguishable from "the item was absent", and both routes land on writing anyway.Why it matters
The write is the hazard. A turbo config write — even a redundant one — glitches the UCI bridge and loses the next command; that is the documented second cause of
NO_SOCKET($88) on the C64U, and the reason these probes exist at all is to skip the write when it would be a no-op. So an unreadable probe degrades toward performing the exact action the probe was added to avoid.The symptom would be intermittent
$88, which the diagnostic ladder points at firmware. This project has a documented history of over-blaming firmware, so a silent degrade in this direction is expensive out of proportion to its rarity.Not broken today
get_config_categoryis unchanged — untouched since 2026-04-05 and explicitly not in the scope of c64-test-harness PR #226, which changed onlyget_config_item. Post-#226, category GETs still return bare values per item, so the existing descent still works. This is a latent hazard, not a current defect.Why it was deferred out of #181
Deliberately, and the reviewer agreed it was defensible: unlike the REU preflight, the right failure handling is a genuine judgement call rather than an obvious fail-closed. Skipping the write on a failed probe risks running the whole rig at the wrong clock, which invalidates every wall-clock number it produces. Failing the run outright is defensible but costs a device slot. Guessing at that inside a fix for something else would have been the wrong call.
Suggested shape (not prescriptive)
client.get_config_value(CAT_U64_SPECIFIC, "CPU Speed")raises rather than returningNone, so the ambiguity disappears at the read. What to do with the raise is the open question — probably: retry once, then abort with a message naming$88as the thing being avoided, since a rig that cannot establish the clock cannot produce a trustworthy measurement either.Whatever is chosen needs a red-green test with a faked client, on the model of
tools/test_reu_preflight.py— no hardware required to pin this.