From b01dedfaa5d6796e20b39c477b7c642ad02bc012 Mon Sep 17 00:00:00 2001 From: Raphael Maenle Date: Tue, 9 Jun 2026 19:16:21 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20drop=20COMPLIANCE=20=C2=A78=20"out=20of?= =?UTF-8?q?=20scope"=20and=20broaden=20=C2=A77=20to=20all=204=20validators?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit §8 was carrying two items that neither read as "deliberately out of scope" nor matched the framing of the section: - Equipment Processing States — E30 §6.3 explicitly leaves concrete states tool-defined. The framework ships the ControlTransitionTable engine and YAML loader; vendors supply IDLE/SETUP/READY/EXECUTING. That's a design choice, not a gap. §3 line 94 already documents it. - Serial-port wiring for SECS-I — the FSM is implemented and tested end-to-end over TCP; only the asio serial_port adapter is missing. That's deferred, not out of scope. §1a line 64 already lists it with status ⬜. So §8 is dropped, §9 renumbers to §8, and the deferred follow-up gets its own short section in the README so customers know it's tracked without sounding defensive. §7 used to be titled "Interoperability with secsgem-py 0.3.0" and mentioned only that one external implementation. We now have four external validators (secsgem-py + secs4java8 + tshark dissector + libFuzzer), so the section is renamed "Interoperability with external implementations" and broadened to cover all of them with their actual check counts. Stale "24 named checks" updated to the current 31; "three consecutive clean runs" line dropped as audit-language no longer earning its keep now that it's a CI step. FAQ's "What's not implemented?" answer rewritten to point at the README "Deferred follow-ups" section and COMPLIANCE §8 (new numbering), with a brief note explaining that Equipment Processing States are spec-by-design tool-defined. Co-Authored-By: Claude Opus 4.7 --- COMPLIANCE.md | 67 +++++++++++++++++++++++++++++++++------------------ FAQ.md | 25 +++++++++++++------ README.md | 17 +++++++++++++ 3 files changed, 78 insertions(+), 31 deletions(-) diff --git a/COMPLIANCE.md b/COMPLIANCE.md index 45ad031..be661f9 100644 --- a/COMPLIANCE.md +++ b/COMPLIANCE.md @@ -13,8 +13,9 @@ I/O), **E148** (time synchronization), **E39** (object services), plus > that E30 binds to a concrete SECS-II message set is implemented, and > every GEM 300 standard the project sets out to cover is implemented > end-to-end (state machines + stores + wire messages + dispatch). See -> §8 for the items deliberately out of scope and §9 for what -> "100% GEM-compliant" can and cannot honestly mean about a codebase. +> §8 for what "100% GEM-compliant" can and cannot honestly mean about a +> codebase, and the README "Deferred follow-ups" section for the +> non-shipped pieces that aren't behavioural gaps. Legend: @@ -369,14 +370,18 @@ against vendor equipment as the first-line conformance probe. --- -## 7. Interoperability with secsgem-py 0.3.0 +## 7. Interoperability with external implementations -The `interop/` harness (see `interop/README.md`) cross-validates the -codebase against the reference Python implementation in Docker: +Four independent external validators cross-check the codebase. None +of them shares code with us; three of them are not even C++. Full +test plan in [VERIFICATION.md](VERIFICATION.md); proof commands in +[PROOFS.md](PROOFS.md). -- **secsgem-py active host → C++ passive server**: 24 named checks - across S1/S2/S5/S6/S7/S10 plus unsolicited S5F1/S6F11. Three - consecutive clean runs. +**secsgem-py 0.3.0** (Python reference implementation, Apache 2.0). +Three harnesses under `interop/`: + +- **secsgem-py active host → C++ passive server**: 31 named checks + across S1/S2/S5/S6/S7/S10 plus unsolicited S5F1/S6F11. - **C++ active host → secsgem-py passive equipment**: HSMS select + S1F13 + S1F1 + S1F3 + clean separate; exits 0. - **C++ active host → raw GEM 300 streams** (`raw_gem300_harness.py`): @@ -384,27 +389,41 @@ codebase against the reference Python implementation in Docker: through secsgem-py's raw HSMS layer with hand-crafted bodies because secsgem-py's high-level API doesn't expose these streams. -Bugs surfaced by the interop sweep (now fixed): strict per-width -parsing rejected U1-encoded identifiers (SEMI E5 allows +**secs4java8** (independent Java SECS implementation by Kenta +Shimizu, Apache 2.0). 55 cross-validation checks under +`interop/secs4j/` 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. This is the only validator that exercises +S2F49 (enhanced remote command) and S5F13–F18 (exception recovery) +end-to-end against a second SECS implementation. + +**Wireshark / tshark HSMS dissector** (independent network-protocol +authors). `interop/tshark_validate.sh` captures a pcap of the demo +run, dissects with tshark's built-in HSMS dissector, asserts no +malformed-packet warnings and that every expected control + data +frame parses. 69 HSMS frames dissected cleanly. This catches +framing bugs that two SECS implementations might *both* share but +that a third party reading the bytes would flag. + +**libFuzzer + ASan + UBSan** (coverage-guided structural search). +`apps/fuzz_secs2_decode.cpp` and `apps/fuzz_sml_parse.cpp` feed +random inputs to the decoder and SML parser under +AddressSanitizer + UndefinedBehaviorSanitizer. 60-second CI lanes +typically explore 200 000+ inputs through `secs2::decode` and +1 400 000+ through `try_parse_sml`; 0 crashes, 0 ASan/UBSan reports. + +Bugs surfaced and fixed across the four channels include: strict +per-width parsing rejected U1-encoded identifiers (SEMI E5 allows `U1|U2|U4|U8`); PPBODY-as-ASCII was rejected; S1F23/F24 wasn't implemented; S10F3 (host→equipment Terminal Display Single) wasn't -wired (we had S10F1 in the wrong direction). +wired; one HSMS framing edge case caught by the tshark dissector; +several SML edge cases caught by libFuzzer. --- -## 8. Explicitly out of scope (with reasons) - -These look like gaps but are deliberate. None blocks the GEM -compliance claim. - -| Item | Why it's out of scope | -|---------------------------------------|----------------------| -| Equipment Processing States (concrete states) | E30 §6.3 says the specific states are tool-defined. We provide the engine (`ControlTransitionTable` + the YAML loader); equipment vendors load their concrete states (IDLE / SETUP / READY / EXECUTING / PAUSE / …) the same way `data/control_state.yaml` is loaded today. Spec-compliant either way. | -| Serial-port wiring for SECS-I | The SECS-I FSM (`secsi::Protocol`) is fully implemented and tested end-to-end over the asio TCP transport (`secsi::TcpTransport`). The serial-port driver (asio `serial_port` wrapper around the same FSM) is a few hundred lines of straightforward wiring that hasn't been written yet — most modern GEM equipment runs HSMS. Plug it in by mirroring `TcpTransport`. | - ---- - -## 9. What "100% GEM-compliant" honestly means here +## 8. What "100% GEM-compliant" honestly means here Every GEM Fundamental and every GEM Additional capability that the E30 specification defines with a concrete SECS-II message set is implemented, diff --git a/FAQ.md b/FAQ.md index 14eb4f8..d339260 100644 --- a/FAQ.md +++ b/FAQ.md @@ -218,10 +218,21 @@ INTEGRATION.md §6.4. ## What's not implemented? -See [COMPLIANCE.md](COMPLIANCE.md) §8 ("Explicitly out of scope") -for the honest list. The short version: tool-specific Equipment -Processing States (the engine is there, vendors plug in their -states), the serial-port driver for SECS-I (the FSM is wired -end-to-end over TCP, the asio `serial_port` glue is a deferred -follow-up), and GEM RTS certification (paid third-party gate, not -a code feature). +Every E30 Fundamental + Additional capability and every GEM 300 +standard in scope is shipped. The two non-shipped pieces are: + +1. **The asio `serial_port` adapter for SECS-I** — the FSM is + implemented and tested end-to-end over TCP + ([`secsi::TcpTransport`](include/secsgem/secsi/tcp_transport.hpp)); + the serial-port driver is a deferred follow-up (most modern GEM + equipment runs HSMS). Listed under "Deferred follow-ups" in + [README.md](README.md). +2. **A GEM Reference Test System (RTS) run** — paid third-party + certification gate, not a code feature. See + [COMPLIANCE.md](COMPLIANCE.md) §8 for what "100% GEM-compliant" + honestly means about a codebase vs. a certified tool. + +Note: Equipment Processing States are tool-defined per E30 §6.3 — the +engine ships, and vendors load their concrete states (IDLE / SETUP / +READY / EXECUTING / …) the same way `data/control_state.yaml` is +loaded. That isn't a gap, it's how the spec is designed. diff --git a/README.md b/README.md index eb849ce..60dad35 100644 --- a/README.md +++ b/README.md @@ -191,6 +191,23 @@ tool. --- +## Deferred follow-ups + +Non-shipped pieces that aren't behavioural gaps in the spec coverage +— each one is a small, well-defined extension on top of the existing +runtime. Listed here so reviewers don't go looking for them in +[COMPLIANCE.md](COMPLIANCE.md) and find an "out of scope" entry that +sounds defensive. + +- **asio `serial_port` adapter for SECS-I.** The SECS-I FSM + (`secsi::Protocol`) is implemented and tested end-to-end over the + asio TCP transport (`secsi::TcpTransport`). The serial driver — + a `serial_port` mirror of `TcpTransport`, a few hundred lines — + hasn't been written. Most modern GEM equipment runs HSMS, so this + has been deprioritised; mirror `TcpTransport` to add it. + +--- + ## Build details The toolchain image (`Dockerfile`) is Ubuntu 24.04 with `g++-13`,