docs: drop COMPLIANCE §8 "out of scope" and broaden §7 to all 4 validators

§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 <noreply@anthropic.com>
This commit is contained in:
2026-06-09 19:16:21 +02:00
parent c8e8e80735
commit b01dedfaa5
3 changed files with 78 additions and 31 deletions
+43 -24
View File
@@ -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 > 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 > every GEM 300 standard the project sets out to cover is implemented
> end-to-end (state machines + stores + wire messages + dispatch). See > end-to-end (state machines + stores + wire messages + dispatch). See
> §8 for the items deliberately out of scope and §9 for what > §8 for what "100% GEM-compliant" can and cannot honestly mean about a
> "100% GEM-compliant" can and cannot honestly mean about a codebase. > codebase, and the README "Deferred follow-ups" section for the
> non-shipped pieces that aren't behavioural gaps.
Legend: 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 Four independent external validators cross-check the codebase. None
codebase against the reference Python implementation in Docker: 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 **secsgem-py 0.3.0** (Python reference implementation, Apache 2.0).
across S1/S2/S5/S6/S7/S10 plus unsolicited S5F1/S6F11. Three Three harnesses under `interop/`:
consecutive clean runs.
- **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 + - **C++ active host → secsgem-py passive equipment**: HSMS select +
S1F13 + S1F1 + S1F3 + clean separate; exits 0. S1F13 + S1F1 + S1F3 + clean separate; exits 0.
- **C++ active host → raw GEM 300 streams** (`raw_gem300_harness.py`): - **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 through secsgem-py's raw HSMS layer with hand-crafted bodies because
secsgem-py's high-level API doesn't expose these streams. secsgem-py's high-level API doesn't expose these streams.
Bugs surfaced by the interop sweep (now fixed): strict per-width **secs4java8** (independent Java SECS implementation by Kenta
parsing rejected U1-encoded identifiers (SEMI E5 allows 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 S5F13F18 (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 `U1|U2|U4|U8`); PPBODY-as-ASCII was rejected; S1F23/F24 wasn't
implemented; S10F3 (host→equipment Terminal Display Single) 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) ## 8. What "100% GEM-compliant" honestly means here
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
Every GEM Fundamental and every GEM Additional capability that the E30 Every GEM Fundamental and every GEM Additional capability that the E30
specification defines with a concrete SECS-II message set is implemented, specification defines with a concrete SECS-II message set is implemented,
+18 -7
View File
@@ -218,10 +218,21 @@ INTEGRATION.md §6.4.
## What's not implemented? ## What's not implemented?
See [COMPLIANCE.md](COMPLIANCE.md) §8 ("Explicitly out of scope") Every E30 Fundamental + Additional capability and every GEM 300
for the honest list. The short version: tool-specific Equipment standard in scope is shipped. The two non-shipped pieces are:
Processing States (the engine is there, vendors plug in their
states), the serial-port driver for SECS-I (the FSM is wired 1. **The asio `serial_port` adapter for SECS-I** the FSM is
end-to-end over TCP, the asio `serial_port` glue is a deferred implemented and tested end-to-end over TCP
follow-up), and GEM RTS certification (paid third-party gate, not ([`secsi::TcpTransport`](include/secsgem/secsi/tcp_transport.hpp));
a code feature). 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.
+17
View File
@@ -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 ## Build details
The toolchain image (`Dockerfile`) is Ubuntu 24.04 with `g++-13`, The toolchain image (`Dockerfile`) is Ubuntu 24.04 with `g++-13`,