startup: report PC/SC access denial instead of a silent serial fallback

When no reader was named and readers() failed (e.g. SCARD_E_NO_ACCESS -
the user may not use pcscd), the auto-detect swallowed the error and pySim
fell back to the Serial transport, failing on /dev/ttyUSB0 while the
server still printed "listening".  The startup now probes PC/SC,
classifies the failure by hresult (access/service/reader), reports the
cause with the pcscd group/polkit and pcsc_scan guidance and exits 2; the
python -m guard uses sys.exit(main()).  An explicit -d/--device keeps the
serial path; a reader without a card stays a normal cardless start; a
readerless start exits with its own message.

start.sh runs the same access pre-flight before launching (readers() with
a 3x retry for socket activation; -d is detected and skips it).  READMEs,
CHANGELOG (folded into the unreleased 3.38.1) and AGENTS updated.

Tests: tests/test_pcsc_startup.py (16: the error classifier, the probe,
the report guidance, the serial-arg detection and the source pins).
1083 Python + 1075 frontend.
This commit is contained in:
2026-10-25 00:29:26 +03:00
parent 0231df905c
commit a269f8bd2e
6 changed files with 333 additions and 31 deletions
+13
View File
@@ -25,6 +25,19 @@ every change carries a descriptive commit message.
- The startup TERMINAL PROFILE drain uses the chain's final SW, so an idle
chain no longer costs one extra STATUS poll (~128 ms).
### Fixed
- **A PC/SC access denial is reported instead of a silent serial fallback.**
When no reader was named and `readers()` failed (e.g. `SCARD_E_NO_ACCESS` —
the user may not use `pcscd`), the error was swallowed and pySim fell back to
the serial transport, failing on `/dev/ttyUSB0` while the server still printed
"listening". The startup now probes PC/SC and reports **`PC/SC access
denied`** (with the `pcscd` group/polkit guidance and the `pcsc_scan`
cross-check), **`pcscd is not running`** or **`no PC/SC reader found`**, then
exits 2; `start.sh` runs the same access pre-flight before launching. An
explicit `-d <device>` keeps the serial path, and a reader present but no card
is still a normal cardless start.
## [3.38.0] — 2026-10-24
### Added