A large gap had opened between the docs and the code: the README and INTEGRATION guide did not mention the gRPC daemon or the Python client at all (the entire vendor surface), ARCHITECTURE still described secs_server as the ~1200-line canonical wiring example (it is a ~110-line thin main over EquipmentRuntime), and test counts across six files were stale (445/2753 -> 473/3087 core + the separate 125-assertion daemon suite). - README: new "Integrating your tool (pick a tier)" section — Python client / any-language gRPC / embedded C++ — plus daemon tests and tools/run_interop.sh in the Testing section. - ARCHITECTURE: layer diagram gains the vendor-surface and EquipmentRuntime/default_handlers tiers; stale wiring row fixed. - INTEGRATION: three-tier chooser up front (this guide = the C++ tier). - ch30 tour: secs_gemd + secs_gemd_tests in the binaries table. - ch31: example alarm used a nonexistent `alcd:` field with bit 7 set (which the validator forbids) -> real `category:`/`name:` fields, and the roles: block documented. - ch35: handler-location note now points at default_handlers.cpp's 15 per-capability register_* functions. - ch40: built-artifacts list + sample output counts. - ch50: secsgem::gem runtime/default_handlers/handler_slot/name_index includes + new secsgem::daemon namespace section. - PROOFS: test-count table gains the runtime/handlers/daemon row so the tally adds up; daemon suite noted. VERIFICATION/COMPLIANCE counts. - interop/README: the one-command runner + the two daemon-track harnesses (daemon_interop, pyclient_interop). Audited via a docs-vs-code sweep (the audit itself under-reported: it validated counts textually; reality was 473/3087). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
6.9 KiB
Proofs
Eight commands. If they all exit zero on a fresh clone, the codebase implements what COMPLIANCE.md claims.
| # | Command | What it proves |
|---|---|---|
| 1 | docker compose run --rm tests |
473 test cases / 3 087 assertions pass: every store, FSM, codec, parser, persistence path |
| 2 | docker compose run --rm builder /app/build/secs_conformance --host server --port 5000 |
47 wire-level conformance checks PASS against a live passive equipment |
| 3 | docker compose run --rm interop python3 /app/interop/host_vs_cpp_server.py --host server |
31 interop checks PASS against secsgem-py 0.3.0 (the Python reference impl) |
| 4 | SECSGEM_ROBUSTNESS_SOAK=1 docker compose run --rm builder /app/build/secsgem_tests -tc='*soak*' |
100 000 random tool operations execute with all invariants and persistence round-trips holding |
| 5 | docker compose run --rm builder /app/build/secs_server --validate-config --config /app/data/equipment.yaml --state-table /app/data/control_state.yaml --pj-state-table /app/data/process_job_state.yaml --cj-state-table /app/data/control_job_state.yaml |
Every shipped YAML config passes structural + referential validation |
| 6 | docker compose run --rm builder bash /app/interop/tshark_validate.sh |
69 HSMS frames dissected by Wireshark's HSMS dissector (independent third codec) with no malformed packets |
| 7 | bash interop/secs4j_validate.sh |
55 cross-validation checks PASS against secs4java8 (independent Java implementation), covering S1/S2/S3/S5/S6/S7/S10/S14/S16, the full E40 PJ body, dynamic event reports + unsolicited S6F11 / S5F1 observation, alarm management, spool, PP management, terminal services, limits, trace, E39, and the GEM 300 streams secsgem-py couldn't easily drive |
| 8 | cmake -B build-fuzz -DSECSGEM_FUZZ=ON && build-fuzz/fuzz_secs2_decode -max_total_time=60 |
200 000+ random inputs through secs2::decode, 1.4 M+ through try_parse_sml per 60 s lane, ASan + UBSan + libFuzzer coverage, 0 crashes |
CI (Gitea Actions) runs a Release build +
full suite and a separate -fsanitize=thread lane on every push to
main. All 473 cases / 3 087 assertions pass under TSan clean.
Per-standard test coverage
Every claimed standard has dedicated tests. Counts are
grep -c TEST_CASE; cross-cutting tests (e.g. test_robustness_fuzz,
test_gem300_scenario) exercise multiple standards in concert.
| Standard | Test files | Cases |
|---|---|---|
| E5 — SECS-II encoding | test_secs2, test_sml, test_messages, test_e5_kat, test_identifier_wildcards, test_fuzz |
139 |
| E5 §13 — exceptions | test_exceptions, test_exception_persistence |
16 |
| E4 — SECS-I transport | test_secsi, test_secsi_timers, test_secsi_tcp |
27 |
| E37 — HSMS (SS + GS) | test_hsms, test_hsms_connection, test_hsms_timers, test_hsms_s9, test_hsms_gs, test_hsms_gs_integration, test_s9_fallback, test_concurrency |
34 |
| E30 — GEM core | test_control_state, test_communication_state, test_host_handler, test_data_model, test_loader, test_config_validate |
71 |
| E40 — process jobs | test_process_jobs |
21 |
| E94 — control jobs | test_control_jobs |
9 |
| E42 — formatted PP | test_e42_formatted_pp |
6 |
| E87 — carriers + load ports | test_carriers, test_carrier_state, test_carrier_persistence, test_e87_wire_scenarios |
27 |
| E90 — substrate tracking | test_substrates, test_substrate_persistence |
21 |
| E116 — EPT | test_ept |
7 |
| E120 / E39 — common equip / object service | test_cem_objects |
3 |
| E157 — module process tracking | test_modules |
5 |
| E84 — parallel I/O + timers | test_e84, test_e84_ports, test_e84_timers, test_e84_asio_timers |
27 |
| Persistence + cross-cutting | test_job_persistence, test_persistence_upgrade, test_wire_ceid_emission, test_gem300_scenario, test_live_gem300, test_thread_safety, test_metrics_prometheus, test_robustness_fuzz |
32 |
| Runtime / handlers / daemon glue | test_runtime, test_default_handlers, test_handler_conformance (53-handler sweep + golden frames), test_name_index, loader/validator additions |
28 |
| Total | 473 |
docker compose run --rm builder /app/build/secsgem_tests --list-test-cases | wc -l
currently reports 473. The gRPC daemon has its own binary on top:
secs_gemd_tests (in-process gRPC service tests, 125 assertions, also run
under ThreadSanitizer in CI).
Categories of evidence
The eight commands split into four kinds:
- Internal (#1, #2, #4, #5) — unit suite, conformance harness, soak property test, config validator. Necessary but not independent.
- External, second implementation (#3, #7) — secsgem-py (Python) and secs4java8 (Java). Two independent SECS implementations agree on every frame.
- External, third codec (#6) — Wireshark's HSMS dissector, written by network-protocol authors with no shared code. Catches framing bugs the implementations might share.
- External, structural search (#8) — libFuzzer + ASan + UBSan over the decoder and SML parser surface.
VERIFICATION.md covers each external validator in detail.