fix(test): ServerHello oracle — dead carry gate + stub skip-as-pass (audit F10) - #79
Conversation
…-as-pass (audit F10) tools/test_tls_handshake.py had two interlocking defects in the ServerHello group, and neither is visible while the other stands. 1. Test 3a read the carry as `carry = 0; if regs and "P" in regs: carry = regs["P"] & 0x01`. VICE's binary monitor names the 6502 status register "FL", so the lookup never matched, `carry` stayed pinned at 0, and the C=1 error branch was unreachable. (Same root cause as F1 in test_tls_record.py.) 3a is now read through the file's own jsr_check_carry() trampoline (LDA #0 / ROL A / STA), which captures C on the 6502 itself and does not depend on register naming at all. 2. Behind that, both `clc; rts` stub checks answered a detected stub with `return 0, 0`, zeroing the group's passed AND failed counters so it vanished from the denominator — a routine that unconditionally claims success was reported as "ALL 18 TESTS PASSED", exit 0. Fixing (1) alone would have made that path reachable for the first time and traded a dead assertion for a silent skip, so both are fixed together: report_if_stub() prints a loud STUB: diagnostic naming the routine and the tests run anyway, failing on their own merits. The identical stub-skip on tls_derive_handshake_keys gets the same treatment, and the VICE launch now goes through _vice_helpers.default_vice_config() like the other in-tree VICE tests. A/B, `tls_parse_server_hello` replaced by a `clc; rts` stub (verified in the built PRG: bytes at $1491, the label address, read 18 60 where pristine reads A0 00): pristine 21/21 pass, exit 0 stub, fixed test 3a/3b/3c all FAIL, group 0/3, 18/21, exit 1, "STUB: tls_parse_server_hello is a `clc; rts` stub -- unimplemented" stub, baseline test (same binary) prints two FAIL lines, then "SKIP: remaining ServerHello tests" and reports "ALL 18 TESTS PASSED", exit 0 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
JC-000
commented
Aug 13, 2026
Independently reproduced by the supervising session. Built a stubbed binary from a clean copy at Pre-fix ( Post-fix (this branch), same binary, exit 1: The old path printed two genuine failures and then discarded them along with the group; the denominator shrank 21 → 18 and the suite reported success. That is a stronger demonstration than the original finding claimed. Using the file's own Two follow-ups raised here and deliberately left alone are worth tracking separately: Confirms audit finding F10. |
F10 — the ServerHello oracle: a dead carry gate hiding a skip-as-pass
Two defects in
tools/test_tls_handshake.py, fixed together because neither isvisible while the other stands.
1. The carry gate was dead. Test 3a read
carry = 0; if regs and "P" in regs: carry = regs["P"] & 0x01. VICE's binarymonitor names the 6502 status register
FL(harnessbackends/vice_binary.py:1325), so the lookup never matched,carrystayedpinned at
0, and theelsebranch — "parser returned C=1 for a validServerHello" — was unreachable. Same root cause as F1 in
test_tls_record.py.3a now reads the carry through this file's own
jsr_check_carry()trampoline(
LDA #0 / ROL A / STA $033F), which captures C on the 6502 itself and has nodependency on register naming.
2. Behind it, a skip-as-pass. Both
clc; rtsstub checks answered adetected stub with
return 0, 0, zeroing the group's passed and failedcounters, so the group left the denominator entirely.
report_if_stub()nowprints a loud
STUB:diagnostic naming the routine and the tests run anyway,failing on their own merits.
Why one PR. Fixing (1) alone makes the
elsebranch reachable for the firsttime, at which point a stub lands in (2) and silently vanishes instead of
failing — a dead assertion traded for a silent skip.
Also in scope: the identical stub-skip on
tls_derive_handshake_keys(samefile, same shape, mechanical), and the VICE launch moved to
_vice_helpers.default_vice_config()like the other in-tree VICE tests.Stub effectiveness — proven in the built binary
tls_parse_server_hello(src/tls_handshake.s:338) prefixed withclc; rts—exactly what the deleted skip branch was written to detect.
build/labels.txtputs the label at
$1491; reading the built PRG at that address:The suite then ran with
C64_SKIP_BUILD=1, so the binary under test is the oneproven above. The mutation lived in the working tree only and was reverted before
the commit.
Acceptance A/B (VICE, ip65 default profile)
PRISTINE ⇒ 21/21, exit 0
(
EXIT=0)STUB ⇒ group 0/3, exit 1, stub named
(
EXIT=1)The defect, demonstrated on the same binary
The pre-fix test code (
git show origin/docs/benchmark-refresh:tools/test_tls_handshake.py)run against the identical stub PRG,
C64_SKIP_BUILD=1:(
EXIT=0)It printed two FAIL lines and then reported a clean pass: the
return 0, 0discarded 3a's failures along with the group, and the denominator silently shrank
21 → 18. That is the whole finding in one screen.
Does the newly-reachable error branch expose anything?
tls_parse_server_hellosatisfies the assertion that was never being made. Nolatent bug was being masked by the dead gate.
before, since nothing could reach it.
carrypinned to 0 it always took the success path, so "parser reportedsuccess" was assumed, not checked. It is checked now.
test_key_schedule(the RFC 8448tls_derive_handshake_keysgroup, 5 tests) is defined but never registered intest_groups— dead code that has never run. I repaired its stub-skip forconsistency, but someone should decide whether to wire it up or delete it.
(
check_labels(...) → return 0, 0), which is F3's shape. Left alonedeliberately so it follows whatever convention Lane C lands for F3 rather than
inventing a second one.