docs: move root .md files into docs/ + update every reference

Picks up the file renames that landed alongside the previous commit
and fixes everything that pointed at the old root locations:

- README.md doc-map updated: every entry now points at docs/X.md,
  with a new "docs/" lead entry pointing at the guided-tour index.
- README inline cross-refs (ARCHITECTURE / INTEGRATION / SECURITY /
  BENCHMARKS / MES_INTEROP / PROOFS) repointed to docs/.
- README "Interop" section rewritten — used to mention only
  secsgem-py; now covers all four external validators (secsgem-py
  31 / secs4java8 55 / tshark 69 frames / libFuzzer 200 k+ runs)
  with a one-line summary each, plus pointers to interop/README.md
  and docs/VERIFICATION.md.
- README "Deferred follow-ups" cleaned: dropped the explanatory
  "Listed here so reviewers don't go looking for them in
  COMPLIANCE.md and find an 'out of scope' entry that sounds
  defensive" sentence — the section header speaks for itself.
- docs/00_index.md "Where the rest of the docs live" table: dropped
  every `../` prefix since the docs are now siblings.
- docs/01_what_is_secs_gem.md PROOFS reference updated to sibling.
- docs/02_the_cast.md INTEGRATION + MES_INTEROP refs updated to
  siblings; dropped the stale "at the repo root" wording.
- interop/README.md: VERIFICATION + PROOFS refs updated to
  ../docs/X.md; stale "~24 + 4 checks" updated to 31 (matches
  PROOFS.md and README).
- examples/pvd_tool/README.md: every doc cross-ref now points at
  ../../docs/X.md.
- Source / data / CI comments mentioning doc names (e.g.
  "INTEGRATION.md §3", "COMPLIANCE.md gap") rewritten to
  "docs/INTEGRATION.md §3" etc. — affects 9 files across
  include/, apps/, tests/, data/, examples/, .gitea/workflows/.

Verified: full build under docker passes, 445/445 test cases pass,
2 753/2 753 assertions pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-09 19:36:27 +02:00
parent 60fa164626
commit fc3422a4a9
14 changed files with 108 additions and 92 deletions
+1 -1
View File
@@ -70,7 +70,7 @@ jobs:
python3 python3-yaml
# Debug + -fsanitize=thread. Catches data races in the
# io_context strand contract documented in INTEGRATION.md §3.
# io_context strand contract documented in docs/INTEGRATION.md §3.
# halt_on_error=1 makes TSan-flagged races fail the job, not
# just print a warning.
- name: Configure (TSan)
+51 -41
View File
@@ -31,17 +31,18 @@ through the data model. Watch the logs interleave.
## Documentation map
| File | What it covers |
|-----------------------------------------------|-------------------------------------------------------------------------|
| [COMPLIANCE.md](COMPLIANCE.md) | Per-capability audit against every SEMI standard implemented |
| [INTEGRATION.md](INTEGRATION.md) | Vendor-side tutorial: YAML → callbacks → production deploy |
| [ARCHITECTURE.md](ARCHITECTURE.md) | How the pieces fit + how to extend (new store / FSM / message) |
| [PROOFS.md](PROOFS.md) | The eight commands that prove the feature-completeness claim |
| [VERIFICATION.md](VERIFICATION.md) | Test plan for the external validators behind the proof table |
| [BENCHMARKS.md](BENCHMARKS.md) | Performance envelope (throughput, latency, memory) + how to re-run |
| [MES_INTEROP.md](MES_INTEROP.md) | Day-1 punch list to run against your commercial MES (59 test IDs) |
| [SECURITY.md](SECURITY.md) | Concrete configs: nftables, stunnel, minisign, SIEM audit-log schema |
| [GLOSSARY.md](GLOSSARY.md) | SEMI vocabulary: SVID, CEID, PPID, ALCD, HCACK, T-timers, … |
| [FAQ.md](FAQ.md) | Common questions and their canonical answers |
|------------------------------------------------------------|-------------------------------------------------------------------------|
| [docs/](docs/00_index.md) | Guided-tour tutorial series — teach-from-zero across the protocol and the codebase |
| [docs/COMPLIANCE.md](docs/COMPLIANCE.md) | Per-capability audit against every SEMI standard implemented |
| [docs/INTEGRATION.md](docs/INTEGRATION.md) | Vendor-side tutorial: YAML → callbacks → production deploy |
| [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | How the pieces fit + how to extend (new store / FSM / message) |
| [docs/PROOFS.md](docs/PROOFS.md) | The eight commands that prove the feature-completeness claim |
| [docs/VERIFICATION.md](docs/VERIFICATION.md) | Test plan for the external validators behind the proof table |
| [docs/BENCHMARKS.md](docs/BENCHMARKS.md) | Performance envelope (throughput, latency, memory) + how to re-run |
| [docs/MES_INTEROP.md](docs/MES_INTEROP.md) | Day-1 punch list to run against your commercial MES (59 test IDs) |
| [docs/SECURITY.md](docs/SECURITY.md) | Concrete configs: nftables, stunnel, minisign, SIEM audit-log schema |
| [docs/GLOSSARY.md](docs/GLOSSARY.md) | SEMI vocabulary: SVID, CEID, PPID, ALCD, HCACK, T-timers, … |
| [docs/FAQ.md](docs/FAQ.md) | Common questions and their canonical answers |
| [examples/pvd_tool/](examples/pvd_tool/) | Worked example: a realistic fictional PVD tool, YAML + C++ wiring |
| [LICENSE](LICENSE) | Proprietary license terms |
@@ -57,7 +58,7 @@ secsgem-py (31 checks) and secs4java8 (55 checks), a 100 000-op
soak property test, YAML config validation, Wireshark's HSMS
dissector on a recorded pcap (69 frames, 0 malformed), and libFuzzer
(ASan + UBSan, 0 crashes). Each command, exit code, and the
external-vs-internal breakdown live in [PROOFS.md](PROOFS.md).
external-vs-internal breakdown live in [docs/PROOFS.md](docs/PROOFS.md).
CI runs the full suite plus a separate ThreadSanitizer lane on
every push to `main` ([Gitea Actions](.gitea/workflows/ci.yml));
@@ -107,8 +108,8 @@ YAML; the C++ is the engine that reads them.
secsgem::metrics Prometheus exporter (Registry + HTTP server).
```
See [ARCHITECTURE.md](ARCHITECTURE.md) for how to extend it (new
store / FSM / message).
See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for how to extend
it (new store / FSM / message).
---
@@ -162,21 +163,22 @@ Run `--validate-config` after every YAML edit.
## Production deployment
See [INTEGRATION.md](INTEGRATION.md) for the full vendor-side
tutorial — wiring sensors, plugging FSMs into the tool, persistence
layout, monitoring/observability, HSMS-GS multi-MES setup.
See [docs/INTEGRATION.md](docs/INTEGRATION.md) for the full
vendor-side tutorial — wiring sensors, plugging FSMs into the tool,
persistence layout, monitoring/observability, HSMS-GS multi-MES
setup.
See [SECURITY.md](SECURITY.md) for concrete nftables / stunnel /
minisign / SIEM configs.
See [docs/SECURITY.md](docs/SECURITY.md) for concrete nftables /
stunnel / minisign / SIEM configs.
See [BENCHMARKS.md](BENCHMARKS.md) for the performance envelope —
roughly **140 k req/s S1F1**, **79 k req/s S1F3 (32 SVIDs)**, **572
k S6F11/s push**, **~450 bytes per PJ+CJ pair**. Three orders of
magnitude above typical fab tool load.
See [docs/BENCHMARKS.md](docs/BENCHMARKS.md) for the performance
envelope — roughly **140 k req/s S1F1**, **79 k req/s S1F3 (32
SVIDs)**, **572 k S6F11/s push**, **~450 bytes per PJ+CJ pair**.
Three orders of magnitude above typical fab tool load.
See [MES_INTEROP.md](MES_INTEROP.md) for the day-1 punch list to run
against your commercial MES before promoting from staging to a real
tool.
See [docs/MES_INTEROP.md](docs/MES_INTEROP.md) for the day-1 punch
list to run against your commercial MES before promoting from
staging to a real tool.
### Operational runbook (starter)
@@ -193,18 +195,11 @@ 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.
hasn't been written. Mirror `TcpTransport` to add it.
---
@@ -227,15 +222,30 @@ TSAN_OPTIONS=halt_on_error=1 build-tsan/secsgem_tests
```
Runs as a separate lane in CI. Catches data races in the io_context
strand contract documented in INTEGRATION.md §3.
strand contract documented in [docs/INTEGRATION.md](docs/INTEGRATION.md) §3.
---
## Interop
`interop/` contains the secsgem-py 0.3.0 cross-validation harness —
secsgem-py active host driving our C++ passive server, our C++
active host probing secsgem-py's passive equipment, and a raw GEM-300
harness that round-trips S3 (E87), S14 (E94), S16 (E40), S12 (wafer
maps) through hand-crafted `SecsStreamFunction` subclasses. See
[`interop/README.md`](interop/README.md).
Four independent external validators cross-check the codebase:
- **secsgem-py 0.3.0** (Python reference impl) — three harnesses
under `interop/`: secsgem-py active host driving our C++ passive
server (31 checks), C++ active host probing secsgem-py's passive
equipment, and a raw GEM 300 harness round-tripping S3 / S14 /
S16 / S12 through hand-crafted `SecsStreamFunction` subclasses.
- **secs4java8** (independent Java SECS implementation) — 55
cross-validation checks covering S1/S2/S3/S5/S6/S7/S10/S14/S16,
full-body GEM 300 shapes, S2F49 enhanced commands, S5F13F18
exception recovery.
- **Wireshark / tshark HSMS dissector** (independent network-protocol
authors) — 69 HSMS frames dissected on a recorded pcap, no
malformed-packet warnings.
- **libFuzzer + ASan + UBSan** — 200 000+ inputs through
`secs2::decode` and 1.4 M+ through `try_parse_sml` per 60 s lane,
0 crashes.
See [`interop/README.md`](interop/README.md) for harness-by-harness
detail and [docs/VERIFICATION.md](docs/VERIFICATION.md) for the test
plan rationale.
+1 -1
View File
@@ -8,7 +8,7 @@
//
// Run: secs_conformance --host <addr> --port 5000 --device 0
//
// The check list deliberately mirrors COMPLIANCE.md so that anything
// The check list deliberately mirrors docs/COMPLIANCE.md so that anything
// the audit claims as ✅ has a runnable assertion behind it here. The
// pass criterion is the spec-mandated reply *function code* — we don't
// require any particular ACK value, since the harness has no equipment
+1 -1
View File
@@ -12,7 +12,7 @@ device:
# Reported on S1F19 -> S1F20 (Get GEM Compliance). CCODE values follow
# E30 Appendix A; CDESC is implementer-defined. Keep this list honest:
# it should reflect what the equipment actually implements (see
# COMPLIANCE.md for the audit).
# docs/COMPLIANCE.md for the audit).
capabilities:
- {code: 1, name: "Establish Communications"}
- {code: 2, name: "Dynamic Event Report Configuration"}
+1 -1
View File
@@ -134,7 +134,7 @@ messages:
# capabilities it supports; equipment replies with its SOFTREV, an
# implementer-defined equipment-type string, and a (CCODE, CDESC) list
# per E30 Appendix A. Closes the "Documentation" Fundamental capability
# by letting the equipment self-report its own COMPLIANCE.md status.
# by letting the equipment self-report its own docs/COMPLIANCE.md status.
- id: S1F19
stream: 1
function: 19
+18 -18
View File
@@ -172,9 +172,9 @@ new behaviour you have to add. Budget: as long as the integration
takes.
**"I'm auditing for compliance / signing off on a deployment."**
Read [`../COMPLIANCE.md`](../COMPLIANCE.md) first. Then read each
Part 2 chapter for the standards in scope. Cross-check the code
references against [`../PROOFS.md`](../PROOFS.md).
Read [`COMPLIANCE.md`](COMPLIANCE.md) first. Then read each Part 2
chapter for the standards in scope. Cross-check the code references
against [`PROOFS.md`](PROOFS.md).
---
@@ -216,7 +216,7 @@ access can cross-check.
- **Not a substitute for the SEMI standards** if you're certifying
for production. We aim for accuracy, but if you're shipping into
a fab, buy the official PDFs.
- **Not a GEM RTS run.** [`../COMPLIANCE.md`](../COMPLIANCE.md) §8
- **Not a GEM RTS run.** [`COMPLIANCE.md`](COMPLIANCE.md) §8
explains the difference between "spec-implementing codebase" and
"third-party-certified compliant equipment."
- **Not a replacement for `../PROOFS.md`.** The proof table is the
@@ -226,22 +226,22 @@ access can cross-check.
## Where the rest of the docs live
Existing root-level docs are reference / audit artifacts. This guide
is the *tutorial path* that ties them together.
The other docs in this directory are reference / audit artifacts;
this guide is the *tutorial path* that ties them together.
| Root doc | What it is | When to read |
|-----------------------------------------|-------------------------------------------------------------|--------------|
| Doc | What it is | When to read |
|--------------------------------------------------|-------------------------------------------------------------|--------------|
| [`../README.md`](../README.md) | One-page project summary + quick start | First contact |
| [`../PROOFS.md`](../PROOFS.md) | The eight commands that prove feature-completeness | Verifying claims |
| [`../COMPLIANCE.md`](../COMPLIANCE.md) | Per-capability audit against every SEMI standard | Compliance review |
| [`../ARCHITECTURE.md`](../ARCHITECTURE.md) | One-page architecture overview | Quick mental model |
| [`../INTEGRATION.md`](../INTEGRATION.md) | Vendor-side integration tutorial | Going to production |
| [`../VERIFICATION.md`](../VERIFICATION.md) | External validator test plan | Verification deep dive |
| [`../BENCHMARKS.md`](../BENCHMARKS.md) | Performance envelope | Capacity planning |
| [`../MES_INTEROP.md`](../MES_INTEROP.md) | Day-1 punch list for commercial MES integration | Pre-flight before MES connect |
| [`../SECURITY.md`](../SECURITY.md) | Concrete nftables / stunnel / minisign / SIEM configs | Production hardening |
| [`../GLOSSARY.md`](../GLOSSARY.md) | SEMI vocabulary cheat sheet | Quick term lookup |
| [`../FAQ.md`](../FAQ.md) | Common questions, canonical answers | Stuck? Check here first |
| [`PROOFS.md`](PROOFS.md) | The eight commands that prove feature-completeness | Verifying claims |
| [`COMPLIANCE.md`](COMPLIANCE.md) | Per-capability audit against every SEMI standard | Compliance review |
| [`ARCHITECTURE.md`](ARCHITECTURE.md) | One-page architecture overview | Quick mental model |
| [`INTEGRATION.md`](INTEGRATION.md) | Vendor-side integration tutorial | Going to production |
| [`VERIFICATION.md`](VERIFICATION.md) | External validator test plan | Verification deep dive |
| [`BENCHMARKS.md`](BENCHMARKS.md) | Performance envelope | Capacity planning |
| [`MES_INTEROP.md`](MES_INTEROP.md) | Day-1 punch list for commercial MES integration | Pre-flight before MES connect |
| [`SECURITY.md`](SECURITY.md) | Concrete nftables / stunnel / minisign / SIEM configs | Production hardening |
| [`GLOSSARY.md`](GLOSSARY.md) | SEMI vocabulary cheat sheet | Quick term lookup |
| [`FAQ.md`](FAQ.md) | Common questions, canonical answers | Stuck? Check here first |
| [`../examples/pvd_tool/`](../examples/pvd_tool/) | A complete fictional PVD tool — YAML + main.cpp | Concrete reference deployment |
---
+1 -1
View File
@@ -215,7 +215,7 @@ The separation matters because:
139 tests for the E5 codec alone, 34 for HSMS, 27 for SECS-I,
71 for E30 behaviour, and dozens per GEM 300 standard. None of
the codec tests need a transport; none of the transport tests
need a behaviour. See [PROOFS.md](../PROOFS.md) for the
need a behaviour. See [PROOFS.md](PROOFS.md) for the
per-standard test counts.
---
+17 -12
View File
@@ -108,15 +108,19 @@ from `main.cpp` directly — each section is independently usable.
- **Persistence.** The demo server's `--spool-dir` flag is the
pattern to copy. Add `model->spool.enable_persistence(...)` etc.
at startup before binding the port. See INTEGRATION.md §5.
at startup before binding the port. See
[`docs/INTEGRATION.md`](../../docs/INTEGRATION.md) §5.
- **E84 handshake timers.** No load-port AMHS wiring; see
INTEGRATION.md §4.6 for the `E84AsioTimers` adapter.
[`docs/INTEGRATION.md`](../../docs/INTEGRATION.md) §4.6 for the
`E84AsioTimers` adapter.
- **Real I/O bridges.** Sensor values come from a random-walk
simulator. A real PVD tool would have a PLC/serial driver
module-bridge feeding `model->svids.set_value(...)` from real
hardware.
- **Production deployment hardening** — SECURITY.md (nftables,
stunnel, minisign signing) and INTEGRATION.md §7 (HA pattern).
- **Production deployment hardening** —
[`docs/SECURITY.md`](../../docs/SECURITY.md) (nftables, stunnel,
minisign signing) and
[`docs/INTEGRATION.md`](../../docs/INTEGRATION.md) §7 (HA pattern).
## What you'd change for *your* tool
@@ -141,13 +145,14 @@ classes. ~1,100 lines of vendor code on top of the library.
## Cross-references
- [INTEGRATION.md](../../INTEGRATION.md) — the conceptual tutorial
this example concretizes
- [ARCHITECTURE.md](../../ARCHITECTURE.md) — how stores compose, how
to extend
- [BENCHMARKS.md](../../BENCHMARKS.md) — what the throughput
envelope looks like
- [SECURITY.md](../../SECURITY.md) — production hardening configs
- [apps/secs_server.cpp](../../apps/secs_server.cpp) — the demo
- [`docs/INTEGRATION.md`](../../docs/INTEGRATION.md) — the conceptual
tutorial this example concretizes
- [`docs/ARCHITECTURE.md`](../../docs/ARCHITECTURE.md) — how stores
compose, how to extend
- [`docs/BENCHMARKS.md`](../../docs/BENCHMARKS.md) — what the
throughput envelope looks like
- [`docs/SECURITY.md`](../../docs/SECURITY.md) — production hardening
configs
- [`apps/secs_server.cpp`](../../apps/secs_server.cpp) — the demo
server's fully-loaded Router (every handler PVD inherits + a
few more)
+2 -2
View File
@@ -20,7 +20,7 @@
// fork this single file as a starting template.
//
// What's *not* here that production deployment needs:
// - SECURITY.md: nftables, stunnel, minisign signing.
// - docs/SECURITY.md: nftables, stunnel, minisign signing.
// - The other router handlers (S5/S6/S7/S10/S14/S16) — apps/
// secs_server.cpp has them all. We register the ones a demo
// host actually exercises here.
@@ -109,7 +109,7 @@ constexpr uint32_t kAlarmCleaningNeeded = 10;
// - Wafer counters, EPT hours: on-event, not polled
//
// All updates marshal onto the io_context via asio::post — that's
// the thread-safety contract documented in INTEGRATION.md §3.
// the thread-safety contract documented in docs/INTEGRATION.md §3.
struct Simulator {
asio::io_context& io;
@@ -52,7 +52,7 @@ class EquipmentConstantStore {
// Validates against min/max for numeric formats (only when min_str and
// max_str parse cleanly). Returns Denied_UnknownEcid / Denied_OutOfRange
// per S2F16 EAC. This is the rule that closes the COMPLIANCE.md gap
// per S2F16 EAC. This is the rule that closes the docs/COMPLIANCE.md gap
// about "EC range validation against min/max".
EquipmentAck set_value(uint32_t id, s2::Item value) {
auto it = by_id_.find(id);
+5 -4
View File
@@ -5,14 +5,15 @@ take our word for it. Each one validates our C++ codec / framing /
dispatch against an **independent third-party implementation** that
read the SEMI standards without talking to us.
See [`../VERIFICATION.md`](../VERIFICATION.md) for the full test plan
and the honest accounting of which proofs are external vs internal.
See [`../docs/VERIFICATION.md`](../docs/VERIFICATION.md) for the full
test plan and the honest accounting of which proofs are external vs
internal.
## What's here
| Validator | Independence | Coverage |
|--------------------------------------------|---------------------------------------------|---------------------------------------------------------------------------------------------------------------------|
| `host_vs_cpp_server.py` + `passive_equipment.py` | secsgem-py 0.3.0 — Python reference impl | ~24 + 4 checks: S1, S2, S5, S6, S7, S10 happy paths |
| `host_vs_cpp_server.py` + `passive_equipment.py` | secsgem-py 0.3.0 — Python reference impl | 31 checks: S1, S2, S5, S6, S7, S10 happy paths + unsolicited S6F11 / S5F1 |
| `raw_gem300_harness.py` | secsgem-py with hand-crafted SecsStreamFunctions | 3 checks: S3F17, S16F5, S16F27 (limited by SFDL grammar) |
| `secs4j/Secs4jHostHarness.java` | secs4java8 — Apache 2.0 Java impl by kenta-shimizu | **55 checks** across S1/S2/S3/S5/S6/S7/S10/S14/S16, including the full E40 body that defeated secsgem-py and unsolicited S6F11/S5F1 observation |
| `tshark_validate.sh` | Wireshark's built-in HSMS dissector | 69 captured frames dissected with no malformed-packet warnings |
@@ -125,7 +126,7 @@ is consistent:
non-Python validators).
2. Wired into `.gitea/workflows/ci.yml` as a separate job.
3. Listed in this README's table + in `../VERIFICATION.md`.
4. Surfaced in [`../PROOFS.md`](../PROOFS.md) if it adds a
4. Surfaced in [`../docs/PROOFS.md`](../docs/PROOFS.md) if it adds a
meaningful new dimension.
Bug reports from a new validator → file at
+1 -1
View File
@@ -35,7 +35,7 @@ TEST_CASE("ECID set rejects unknown id and out-of-range values") {
CHECK(ecids.get(10)->value == s2::Item::u4(uint32_t{50}));
CHECK(ecids.set_value(999, s2::Item::u4(uint32_t{1})) == EquipmentAck::Denied_UnknownEcid);
// Out-of-range rejected (closes COMPLIANCE.md gap).
// Out-of-range rejected (closes docs/COMPLIANCE.md gap).
CHECK(ecids.set_value(10, s2::Item::u4(uint32_t{5000})) == EquipmentAck::Denied_OutOfRange);
CHECK(ecids.get(10)->value == s2::Item::u4(uint32_t{50})); // unchanged
}
+2 -2
View File
@@ -4,8 +4,8 @@
// its own router + selected handler + send path.
//
// This is the "two MES, one tool" pattern that the codebase advertises
// in COMPLIANCE.md §1 ("HSMS-GS (general-session) ✅") and that
// INTEGRATION.md §7 mentions. Until now there was no end-to-end test
// in docs/COMPLIANCE.md §1 ("HSMS-GS (general-session) ✅") and that
// docs/INTEGRATION.md §7 mentions. Until now there was no end-to-end test
// covering the Server/Client integration — only direct Connection
// wire tests in test_hsms_gs.cpp.
+1 -1
View File
@@ -2,7 +2,7 @@
//
// EquipmentDataModel is single-threaded by design — there are zero
// locks anywhere in the store hierarchy. The contract documented in
// INTEGRATION.md §3 is: all access (reads from the dispatcher, writes
// docs/INTEGRATION.md §3 is: all access (reads from the dispatcher, writes
// from the application) must run on the io_context that drives the
// HSMS connection. Cross-thread updates marshal through `asio::post`.
//