C1: ExceptionStateMachine FSM + ExceptionStore
Per-EXID exception lifecycle for E5 §9. States mirror the wire flow: Posted equipment sent S5F9, awaiting host or autonomous clear Recovering host's S5F13 accepted; equipment running recovery RecoverFailed S5F15 reported a failed result; host may retry Cleared terminal — store removes the row Events: Created synthetic NoState->Posted observer signal Recover host's S5F13 (Posted/RecoverFailed -> Recovering) RecoveryComplete equipment internal (Recovering -> Cleared) RecoveryFailed equipment internal (Recovering -> RecoverFailed) RecoveryAbort host's S5F17 (Recovering -> Posted) Clear equipment internal (Posted/RecoverFailed -> Cleared) ExceptionStore mirrors ProcessJobStore: per-EXID FSMs heap-allocated via unique_ptr, non-movable to keep `this`-captures safe, synthetic Created fires after the row lands so observers can decide whether to emit S5F9 out of band. on_recover validates EXRECVRA against the candidates the post advertised. The store joins EquipmentDataModel alongside process_jobs / control_jobs. S5F9-F18 server-side dispatch lands in C2. Tests (12 cases) cover FSM transitions including retry, abort, and autonomous clear, plus store-level duplicate-rejection, EXRECVRA validation, and Cleared-removes-the-row semantics. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -53,6 +53,7 @@ add_library(secsgem
|
||||
src/gem/communication_state.cpp
|
||||
src/gem/process_job_state.cpp
|
||||
src/gem/control_job_state.cpp
|
||||
src/gem/exception_state.cpp
|
||||
src/gem/host_handler.cpp
|
||||
src/config/loader.cpp
|
||||
src/endpoint.cpp
|
||||
@@ -96,6 +97,7 @@ add_executable(secsgem_tests
|
||||
tests/test_loader.cpp
|
||||
tests/test_process_jobs.cpp
|
||||
tests/test_control_jobs.cpp
|
||||
tests/test_exceptions.cpp
|
||||
)
|
||||
target_link_libraries(secsgem_tests PRIVATE secsgem doctest::doctest)
|
||||
target_compile_definitions(secsgem_tests PRIVATE
|
||||
|
||||
Reference in New Issue
Block a user