Reports
What has been built, what was run, and what the results were. Every result on this page comes from simulators or simulated peers. Nothing here is a physical-hardware result.
Project status
| Item | Value |
|---|---|
| Version | 0.1.0, pre-alpha. No release published yet. |
| Specification | v0.1 draft; may change incompatibly before 1.0 |
| Milestones | M0 to M9 done (M7 to M9 pending review). M10 built, not published. M11+ planned. |
| Languages | Rust (gateway, engine, adapters), Python (SDK, Python adapters, examples, tools) |
| Interfaces | MCP over stdio, local JSON-RPC API, CLI, Python SDK |
| Platforms | Windows 11 and Linux (Ubuntu) tested; macOS arm64 configured in CI; macOS x86_64 untested |
| Physical hardware | Not yet tested by the project |
| Maintainer | Maintainer-led; see GOVERNANCE.md |
| License | Apache-2.0 |
M10: release readiness
Status: built and verified locally on Windows; not releasable until the blockers below are cleared. No release, PyPI upload or documentation site has been published. Source: M10 test report.
| Deliverable | Verified by | State |
|---|---|---|
| README rewrite with quickstart | Quickstart run from a release binary in PowerShell | done |
| Release binaries (cargo-dist, four targets) | Windows zip built, checksum matched, demo and quickstart ran from it | Windows only Linux and macOS never built |
| Python package | sdist and wheel built, twine check, installed in a clean venv, smoke test | not uploaded |
| Documentation site (mdBook) | Built: 80 pages, 2247 links checked offline, 0 errors | not deployed |
| Adapter registry | check_registry.py, 23 tests | done |
| Generated compatibility matrix | Generated from committed reports; checked in CI | done |
| Governance and community files | CONTRIBUTING, SECURITY, SUPPORT, CODE_OF_CONDUCT, GOVERNANCE, issue and PR templates, RFC template | done |
| Demo recording | Terminal SVG and transcript from a real run | video not rendered |
| Installation guide | Windows steps run; Linux and macOS steps written | partly tested |
Gate results on Windows
| Step | Result |
|---|---|
cargo fmt, cargo clippy -D warnings, cargo deny check | pass |
cargo test --workspace | pass 354 tests, 0 failed, 67 test binaries |
| Schema, registry, matrix and release-version checks | pass 78 schema documents, 11 registry entries, 9 reports |
| Python SDK tests and tool tests | pass |
| Documentation build with link check | pass 0 broken links |
Release blockers
- Nothing has run on Linux or macOS. Only the Windows build was made.
- CI has not run on the M10 work. Two new CI jobs have never executed.
- Owner actions: private vulnerability reporting, code-of-conduct contact, PyPI trusted publisher, GitHub Pages, repository settings.
- The demo video is not rendered.
- The
openmhsname on PyPI was free on 2026-10-25; that can change. - crates.io is blocked:
openmhs-typesembeds files fromspec/, which a published crate cannot reach.
Compatibility matrix
Generated by tools/gen_matrix.py from the adapter registry and the
conformance reports committed in conformance/reports/. CI fails if it is
stale. Source: docs/compatibility.md.
| Adapter | Protocol | Category | Evidence | Level reached | Checks | Result |
|---|---|---|---|---|---|---|
openmhs.http | HTTP | official | Integration-tested (simulated peer) | L3 (declares L2) | 46 pass, 0 fail, 4 n/a | Pass |
openmhs.modbus | Modbus TCP | official | Integration-tested (simulated peer) | L3 (declares L2) | 78 pass, 0 fail, 6 n/a | Pass |
openmhs.mqtt | MQTT | official | Integration-tested (simulated peer) | L3 (declares L2) | 56 pass, 0 fail, 4 n/a | Pass |
openmhs.scpi | SCPI | official | Integration-tested (simulated peer) | L3 (declares L2) | 73 pass, 0 fail, 6 n/a | Pass |
openmhs.py.psu-sim | other | official | Simulated | L3 (declares L3) | 66 pass, 0 fail, 6 n/a | Pass |
openmhs.sim.axis | built-in | official | Simulated | L3 (declares L3) | 51 pass, 0 fail, 4 n/a | Pass |
openmhs.sim.psu | built-in | official | Simulated | L3 (declares L3) | 66 pass, 0 fail, 6 n/a | Pass |
openmhs.sim.thermo | built-in | official | Simulated | L1 (declares L1) | 19 pass, 0 fail, 6 n/a | Pass |
openmhs.py.octoprint | HTTP | experimental | Integration-tested (simulated peer) | L1 (declares L1) | 34 pass, 0 fail, 6 n/a | Pass |
openmhs.py.opcua | OPC UA | experimental | Not verified | none on file (declares L1) | - | Not verified |
openmhs.py.ros2 | ROS 2 | experimental | Not verified | none on file (declares L1) | - | Not verified |
All reports: OpenMHS 0.1.0, Windows x86_64, 2026-10-24. Every report's source is "simulator".
Experiments: OctoPrint and ESP32
Experiment 01: read-only OctoPrint adapter
A read-only adapter for OctoPrint, the 3D-printer server, tested against a real OctoPrint 1.11.8 driving its Virtual Printer plugin. Simulated peer only; no physical printer. Full report.
| Check | Result |
|---|---|
| Adapter | 5 capabilities, 2 request paths, GET only, standard library only |
| Adapter tests | pass 42 run, 41 passed, 1 skipped (abstract base), 0 failed |
| Conformance | PASS L1 reached, declared L1, 34 pass, 0 fail, 0 untested |
| End-to-end demo | 11 steps, exit 0, 17 requests, all GET |
What the real OctoPrint showed that its documentation did not: right after the printer
connects, temperature fields are missing and then null before real numbers;
an unplugged printer is a 409 on one endpoint but a 200 on
another. The adapter now reports these honestly instead of serving a stale or malformed
value.
Experiment 02: ESP32 over MQTT, in QEMU
Real ESP-IDF firmware for an ESP32 node, run in Espressif's QEMU beside a real Mosquitto broker, driven through the stock MQTT adapter with state-changing commands. Simulated only; no physical ESP32. Full report.
| Situation | Gateway result | What the node did |
|---|---|---|
| Turn the LED on, with a grant | VERIFIED acknowledged, read back true | Applied and published state |
| Pulse twice (no readback declared) | UNVERIFIABLE device says applied; not confirmed | Counter 0 to 2 |
| No grant | DENIED nothing sent | Received nothing (0 messages) |
| Pulse count 11 (range 1 to 10) | DENIED out of range | Received nothing |
| Node frozen, write | UNKNOWN_OUTCOME timeout, not retried | Applied it after being released |
| Same command, reconciled later | RECONCILED_APPLIED readback matches | LED on |
| Node powered off, action | UNKNOWN_OUTCOME sent once, never retried | Nothing applied late |
| Broker stopped | Reads disconnected; command FAILED not sent | Reconnected by itself |
Tests: 18 passed of 18. Demo: 10 steps, audit chain
verified (53 records). The key finding: a node that stops answering may still
apply the command later. That is exactly what UNKNOWN_OUTCOME is for,
and why the gateway never retries: a retried pulse would have run twice.
Guided demo, step by step
Command: openmhs demo. A real gateway with three simulated devices
(sim.thermo-01, sim.psu-01, sim.axis-01), driven
over its API. Result: every step behaved as expected.
| # | What happens | Result |
|---|---|---|
| 1 | Gateway starts with three simulated devices, loopback only | ok |
| 2 | Operator issues a token for agent:demo | ok |
| 3 | Agent asks for 5 V with no grants | DENIED policy.denied.no_grant |
| 4 | Agent tries to grant itself access | refused only operators change policy |
| 5 | Operator grants read, power output, homing, and approval-gated moves | ok |
| 6 | Agent reads the temperature | GOOD fresh, timestamped, audited |
| 7 | Agent asks for 48 V on a 0 to 12 V supply | DENIED command.value.out_of_range |
| 8 | Agent sends a bare 5 with no unit | DENIED command.value.type_mismatch |
| 9 | Agent jumps from 0 V to 5 V (limit 2 V per second) | DENIED command.slew_exceeded |
| 10 | Agent ramps 2 V, 4 V, 5 V, one second apart | VERIFIED each by readback |
| 11 | Agent retries 5 V with the same idempotency key | ok original command returned, not run again |
| 12 | Supply telemetry goes stale; agent asks for 6 V | DENIED command.state.stale |
| 13 | Agent homes the axis | VERIFIED |
| 14 | Agent requests a hazardous move to 120 mm | AWAITING_APPROVAL nothing moved |
| 15 | Agent tries to approve its own move | refused agents cannot approve |
| 16 | Operator approves; preconditions re-checked; carriage moves | VERIFIED readback 120 mm |
| 17 | Supply applies 7 V but the acknowledgement is lost (3 s deadline) | UNKNOWN_OUTCOME not failed, not retried |
| 18 | Fault clears; agent reconciles by reading the device | RECONCILED_APPLIED readback 7 V |
| 19 | Supply adapter crashes while handling 6 V | UNKNOWN_OUTCOME, then RECONCILED_NOT_APPLIED readback still 7 V; gateway kept serving |
| 20 | Operator verifies the audit log | ok 89 records, hash chain intact |
Recorded on 26 October 2026 on Windows 11 with Rust 1.99.1, from
the latest main (openmhs 0.1.0).
Simulator conformance
Command: openmhs conformance, with all five faults injected
(link_down, no_response, lost_ack,
garbled, refuse). Same run, same date as the demo.
| Device | Declared | Reached | Pass | Fail | Untested | N/A | Time | Result |
|---|---|---|---|---|---|---|---|---|
sim.thermo-01 sensor | L1 | L1 | 19 | 0 | 0 | 6 | 0.03 s | PASS |
sim.psu-01 power supply | L3 | L3 | 66 | 0 | 0 | 6 | 17.6 s | PASS |
sim.axis-01 linear stage | L3 | L3 | 51 | 0 | 0 | 4 | 13.8 s | PASS |
The temperature sensor is read-only, so L1 is its correct ceiling.
Agent replanning run
Command: python examples/agent-loop/mock_agent.py. A scripted agent
connects over MCP, with no model and no API key.
| Task | What the gateway said | What the agent did | End |
|---|---|---|---|
| Set the supply to 5 V | Refused: slew limit. Suggested steps of at most 2 V, one second apart, with readback between. | Ramped 2 V, 4 V, 5 V, checking each step first | VERIFIED 5 V |
| Set the supply to 15 V | Refused: outside 0 to 12 V. Advised not to exceed the range to compensate. | Did not retry; reported to the human | DENIED as expected |
| Home the linear stage | Refused: no grant | Asked the human for permission | DENIED as expected |
Final setpoint 5 V; audit chain valid with 50 records. All tasks ended as expected. (Recorded 25 October 2026.)
Known limitations
The single list is docs/limitations.md. The main points:
- Not a safety system. A stop is a command, not a safety function. Emergency stops and interlocks belong to the hardware.
- No physical hardware tested. Passing against a simulator shows the contract and adapter agree, not that a real device works. The hardware guides are unverified.
- OPC UA is read-only, ROS 2 observation-only, and neither has a committed report. No Modbus RTU.
- Twin preflight has no physics. Plans run steps in order; there are no parallel steps.
- MCP is stdio only: no HTTP transport, resources or approval notifications.
- Single-user trust boundary. Any process running as your OS user can read the operator token. The adapter host has no OS sandbox.
- No signed descriptors or signed audit export. Rate and slew history, and simulator state, reset on restart.
Roadmap
| # | Milestone | Status |
|---|---|---|
| M0 | Research, positioning, naming, decision records | done |
| M1 | Specification v0.1: schemas, lifecycle, units, errors, authorization, example devices | done |
| M2 | Core engine, journal with crash recovery, audit, adapter trait, virtual power supply | done |
| M3 | Gateway, local API, CLI, three virtual devices, demo, CI on three systems | done |
| M4 | MCP server, Python SDK, replanning agent example | done |
| M5 | Conformance suite, adapter scaffolding, adapter author guide | done |
| M6 | Protocol adapters: Modbus TCP, MQTT, SCPI, HTTP | done |
| M7 | Out-of-process adapter host, Python adapter SDK, OPC UA and ROS 2, verified TLS | done pending review |
| M8 | Identity and trust: scoped credentials, approval records, signed manifests, threat model | done pending review |
| M9 | Capability graph, leases, plans with twin preflight, stop lane, L3 conformance | done pending review |
| M10 | Release readiness: binaries, PyPI, docs site, adapter registry, compatibility matrix, governance | built nothing published; see blockers |
| M11+ | Advanced track, design documents first: WASM-sandboxed adapters, OpenTelemetry, remote and federated gateways, fleets, assisted adapter generation, hardware-in-the-loop rigs, OPC UA, ros2_control and SiLA 2 bridges, device attestation | planned |
Source: docs/roadmap.md, docs/IMPLEMENTATION_STATUS.md and CHANGELOG.md.