docs(vehicle): document BLE timeout verification contract#56
Merged
Conversation
added 3 commits
July 10, 2026 08:39
Live testing proved door_unlock/door_lock both raised BluetoothTimeout while physically executing, disproving the prior "timeout means the write never landed" note. Document the corrected contract on VehicleBluetooth and Commands._command: a mutating-command timeout is inconclusive, and the library's own WAIT/fault retry can double-apply a non-idempotent command.
Bre77
force-pushed
the
fm/tfa-ble-verify-contract-k2
branch
from
July 9, 2026 22:40
933fe39 to
5c6a51c
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.
Intent
wake_up()) can raiseBluetoothTimeouteven though the command executed on the vehicle - live BLE testing confirmeddoor_unlock/door_lockandwake_up()timing out while a follow-up state read showed the command had taken effect.VehicleBluetoothstating the contract: aBluetoothTimeoutfrom a mutating command is inconclusive; callers must snapshot -> act -> verify-by-state, and must never blind-retry a non-idempotent command on timeout.Commands._commanddocumenting that its own WAIT/fault retry can re-send an already-executed, non-idempotent command.AGENTS.md/CLAUDE.mdnote that claimed "a write timeout means the write never landed" - disproven by live testing - and rewrote it to the inconclusive/verify-by-state contract, plus added a new bullet on the retry double-execution window.bluetooth.py's_send/connect internals left untouched beyond the class docstring - a parallel effort is wrapping transport exceptions there, and touching more would create rebase conflicts.ruff check,ruff format --checkon touched files,pyrightstrict (0 errors), and the fullpytestsuite (153 passed) - all clean.What Changed
VehicleBluetoothBLE mutating-command contract:BluetoothTimeoutis inconclusive, so callers should verify actuation from follow-up vehicle state instead of treating it as definitive failure.Risk Assessment
✅ Low: The change is documentation-only, narrowly scoped to clarifying BLE timeout and retry semantics, and I found no introduced correctness or API-contract risks.
Testing
Inspected the documentation-only diff, exercised BLE mutating command paths and the full suite, and produced runtime evidence showing the new developer-facing contract plus the WAIT retry double-send behavior; all tests passed and no working-tree artifacts remain.
Evidence: BLE verify contract evidence
Runtime evidence extracts the new VehicleBluetooth and Commands._command docstrings and demonstrates WAIT-then-OK on mocked BLE door_lock produces two _send calls with RKE_ACTION_LOCK both times.Full narrative / original brief
Document and enforce a verify-actuation-by-state contract for BLE mutating commands in tesla_fleet_api. Live BLE testing (not part of this diff) proved that door_unlock/door_lock and wake_up() can raise BluetoothTimeout while the command actually executed on the vehicle - so a caller treating that timeout as failure is wrong, and blind-retrying on it double-executes non-idempotent commands. This PR is documentation-only by design (explicitly scoped as contract, not a redesign): (1) added a docstring to the VehicleBluetooth class stating the contract - a BluetoothTimeout from a mutating command is inconclusive, callers must snapshot->act->verify-by-state, and must never blind-retry a non-idempotent command on timeout; (2) added a docstring to Commands._command documenting that its own WAIT/fault retry can double-execute a non-idempotent command; (3) corrected a stale AGENTS.md/CLAUDE.md note that previously claimed 'a write timeout means the write never landed' - that claim is disproven by the live evidence, so the bullet was rewritten to the corrected inconclusive/verify-by-state contract, and a new bullet was added documenting the retry double-execution window. No behavior changes, no new retry logic, no defensive machinery were added - deliberately out of scope. Also deliberately left tesla_fleet_api/tesla/vehicle/bluetooth.py's _send/connect internals untouched beyond the class docstring, since a parallel effort is wrapping transport exceptions there and touching more would create rebase conflicts. Verified with ruff check, ruff format --check on the touched files, pyright strict (0 errors), and the full pytest suite (153 passed) - all clean.
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 1 issue found → auto-fixed ✅
tesla_fleet_api/tesla/vehicle/bluetooth.py:185- The new public class docstring sends readers toAGENTS.mdfor the evidence behind the BLE timeout contract, but the wheel only packagestesla_fleet_api*pluspy.typed, so installed users readinghelp(VehicleBluetooth)or generated API docs get an internal, unshipped reference. Since this PR is documenting a user-facing safety contract, consider keeping the rationale self-contained here or pointing at shipped/repository documentation instead.🔧 Fix: Remove internal doc references
✅ Re-checked - no issues remain.
✅ **Test** - passed
✅ No issues found.
Inspected changed files withgit diff --unified=80 629c16d8123211a64c2cd31f68b3866e29e4d6c6..e36797e3f618d46c02c38cf06174b6c4db468445 -- AGENTS.md tesla_fleet_api/tesla/vehicle/bluetooth.py tesla_fleet_api/tesla/vehicle/commands.py.Ran BLE-focused command-path tests:uv run pytest tests/test_ble_mocked_commands.py tests/test_ble_mocked_closures_locks.py tests/test_ble_mocked_media_commands.py tests/test_ble_charging_commands.py tests/test_ble_climate_commands.py tests/test_ble_send_transport.py.Ran full regression suite:uv run pytest tests.Generated reviewer evidence withPYTHONPATH=tests uv run python - <<'PY' > /tmp/no-mistakes-evidence/01KX4DTJXFBCSN1NWT310F0YC0/ble_verify_contract_evidence.txt, extracting runtime docstrings and demonstrating WAIT retry behavior over mocked BLE transport.Removed transient working-tree caches withfind . -name '__pycache__' -type d -prune -exec rm -rf {} + && rm -rf .pytest_cache.✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.