test(tx-safe): repair the emergency-stop wiring guard, which checked only its own text - #200
Merged
Merged
Conversation
…only its own text (FR-TX-SAFE-05)
fr_tx_safe_05_estop_is_dispatched_before_all_other_key_handling read the whole
of main.rs and searched for `Message::KeyPressed(key, mods) => {`. When the arm
gained a third argument (c11b377, 2026-07-21) that text occurred once, inside the
guard itself, and every assertion was satisfied by the guard's own literals. It
had not checked anything since: deleting the real
`self.send(WorkerCmd::EmergencyStop)` left it green (confirmed before changing
anything). The real code is correct.
fr_ui_hold_01_tap_hold_wraps_a_non_interactive_visual had the same shape: it
counted its own `tap_hold(` line as a seventh call, so one of the six real popup
chips could be removed and "at least six" still passed.
- source_guard::production() returns only the code above the test modules.
- The checks are pure functions of a source string, tested on synthetic sources
(three arities x three indentations, missing/renamed/duplicated arm, code
before the check, dispatch outside the check's block, no return, ...).
- The arm is found by shape, so another argument cannot rot it; none found is an
error, not a pass. Only comments may precede the check.
- Verified by sabotaging the real code: dispatch deleted, return deleted, a modal
check moved before it, an unrelated statement before it, the check disabled,
the arm renamed - all caught. The first version of this fix read the arm's
indentation wrongly and still missed the deleted dispatch; the real-code
sabotage found it.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ma4bQKqGNFTYyVSEKPcXRk
dc0sk
force-pushed
the
fix/structural-guards-self-match
branch
from
September 22, 2026 07:12
be15673 to
37e79d3
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
fr_tx_safe_05_estop_is_dispatched_before_all_other_key_handlinghas checked nothing since 2026-07-21. The emergency-stop code itself is correct — the check is the first statement of theKeyPressedarm. What was lost is the alarm that would catch a future regression.What was wrong (confirmed before changing anything)
Deleting the real
self.send(WorkerCmd::EmergencyStop)left the guard green.The guard
include_str!s all ofmain.rsand searched forMessage::KeyPressed(key, mods) => {. Commitc11b377gave the arm a third argument, so that text occurred exactly once — inside the guard itself — and every assertion was satisfied by the guard's own literals. Its.expect("the KeyPressed handler must exist"), written to fail loudly on rot, never fired.A second guard had the same shape:
fr_ui_hold_01_tap_hold_wraps_a_non_interactive_visualcounted its ownmatch_indices("tap_hold(")line as a seventh call (production has exactly six), so one real popup chip could be deleted and "at least six" would still pass.The fix
source_guard::production()returns only the code above the test modules (its marker is built withconcat!so it does not contain itself).return, a multi-line condition with nested calls, arm renamed / only constructed / present twice.Message::KeyPressed(…) => {), so another argument cannot rot it; finding none is an error, not a pass.return.Verified by sabotaging the real code
Dispatch deleted · dispatch kept but
returndeleted · a modal check moved before it · an unrelated statement before it · the check disabled · the arm renamed — all six caught (the first is the one the old guard missed). The tap/hold count is exactly six. 23 mutations of the guards themselves are all killed.My first version of this fix had a bug of its own, which the real-code sabotage found: it read the arm's indentation from the pattern's position (always empty), so the "next arm" was never found, the arm ran to the end of the file, and deleting the dispatch was still missed. The synthetic test that should have caught it only ran at zero indentation; every negative case now runs at every indentation.
fmt, clippy
--all-features, 403 workspace tests,cargo xtaskOK.Merge note
The ledger header is
4.14.1because the open stack #196–#199 uses 4.15+ (and the SRS 0.64+). Whichever merges second gets a trivial conflict in thedocs/test/test-strategy.mdheader and the row above4.14.Not covered
The guards on the other branches (TLS, redraw pacing, afterglow) each already slice off their own test modules, and each has its own sabotage evidence. A repo-wide "no test may scan its own file unsliced" check was considered and not added, because it would fail those PRs at merge; say if you want it as a follow-up.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Ma4bQKqGNFTYyVSEKPcXRk