Untrusted profiles could bypass the confirmation and responses were mis-parsed:
- effective_risk(action): risk is now DERIVED from the actual service IDs the
steps send — any write/actuator/reset/transfer SID (2F/31/11/14/2E/27/34-37/…)
forces 'danger'; unknown SID / non-default session / security block force
'caution'. A profile can only RAISE risk, never label a reflash 'safe'. GUI
gates the confirmation (and the risk badge) on this derived value.
- Response checks use CONTIGUOUS subsequence matching + a hard '7F <sid>'
negative-response guard, so an NRC data byte (e.g. 0x7E) can't false-pass as a
positive response; applied to session/security/step checks.
- 0x78 (responsePending) is treated as in-progress, not terminal failure.
- controller.run_action restores slow ELM timing for the run (0x78 window).
- Tests: risk-cannot-be-downgraded, NRC false-positive rejected, pending handled.
Closes#7
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016yT89n4zR4qbrySoSiEyZs