Wrap get_usb_speed, get_serial_number, and get_last_error in try/except
so a STALL on one command returns "unavailable" instead of crashing the
entire status read. Discovered when vendor command 0x07 (get_usb_speed)
STALLs on real hardware despite working firmware version readback.
Extract MockSkyWalker1 to shared mock_device.py (used by both unit tests
and server lifespan). Server checks SKYWALKER_MOCK env var at startup —
when set, uses mock device instead of USB hardware, enabling full MCP
transport testing via claude -p without the dongle connected.
Verified: 64 unit tests pass, claude -p integration tests exercise
identify_frequency, get_device_status, and sweep_spectrum through the
complete JSON-RPC pipeline.
Motor watchdog: asyncio background task auto-halts motor after 30s of
continuous drive, fires even if LLM client disconnects. Integrated into
move_dish (start on continuous, cancel on halt/goto/gotox) and lifespan
teardown.
Test suite: 64 tests covering all 17 MCP tools — device status, spectrum
sweep validation, tune/blind-scan boundary checks, motor safety (stepped,
continuous opt-in, watchdog lifecycle), jog/store limits, LNB/I2C, TS
capture, frequency identification, and path traversal protection. Uses
MockSkyWalker1 + MockContext for direct async function testing without
USB hardware.
Fixes: FastMCP 2.x description→instructions constructor change,
parents[4] path resolution for tools directory import.
Four new tools transforming the SkyWalker-1 from satellite TV receiver into
a general-purpose RF observatory:
- skywalker-mcp: FastMCP server exposing 20 tools, 4 resources, 2 prompts.
Thread-safe DeviceBridge with motor safety (continuous drive opt-in),
input validation on all frequency/symbol rate/step parameters,
try/finally on TS capture, path traversal sanitization, and reduced
lock scope so emergency motor halt isn't blocked during long surveys.
- h21cm.py: Hydrogen 21 cm drift-scan radiometer at 1420.405 MHz with
Doppler velocity calculation, control band comparison, and CSV output.
- beacon_logger.py: Long-term Ku-band beacon SNR/AGC logger with auto-relock,
dual CSV/JSONL output, signal handlers, and systemd unit generation.
- arc_survey.py: Multi-satellite orbital arc census with USALS motor control,
per-slot catalog persistence, resume support, and defensive motor halt
on all error/interrupt paths.
Documentation: experimenter's roadmap guide + 4 tool reference pages (48 pages total).