Specification · section 7
Safety model
The safety model is the reason MHP exists as a separate protocol rather than a set of MCP tools. Every rule below is enforced in the server, on the device side of the network, so it holds even when the agent is wrong, compromised or has lost context.
7.1 Gate order
On every settings/write and actions/invoke the server evaluates, in order:
- State:
estop→EStopActive;fault→DeviceFault. - Approval:
forbid→Forbidden;confirmwithoutapproved:true→ApprovalRequired. - Interlocks: each named signal is read live and must be exactly
true; false, unreadable or stale →InterlockOpen. - Values: type (
InvalidValue), then limits (LimitViolation); for actions also declared, required and bounded parameters, then the driver's whole-requestvalidate_params. - Lease: another session holds an unexpired lease →
NotLeased; a watchdog device operated without the lease →NotLeased(lease_required). - Busy: an action while a non-concurrent job runs, or a setting not marked
during_jobwhile any job runs →DeviceBusy.
Only after all six pass does vendor code run. dryRun: true evaluates the same checks without touching the device; approval, lease and busy conditions come back as notes (needsApproval, needsLease, leaseHeldBy, busyNow) so a plan can show them.
7.2 Approval levels, elicitation and the trust boundary
confirm is the bridge between agent autonomy and human oversight, and it depends on one rule: the host is trusted, the model is not. approved: true is the host's statement that a person confirmed this exact request. A model asserting it is not approval.
- The model asks for
open_lid. The host sends the request without approval and getsApprovalRequired. - The host asks a person, showing the device, the action, its exact parameters and the descriptor's
notes. - Only on an explicit yes does the host send the same request again with
approved: true. The answer is logged.
The reference bridge does this through MCP elicitation, for direct tool calls and for every call a run script makes, and it ignores any approved value the model supplies. If the harness has no elicitation, the bridge has no trusted way to reach a person, so confirm-gated operations are unavailable and the refusal says so. The SDK and the CLI are host tooling: code or a person using them directly is the trusted party, and --approved is that person's own statement. Servers that can reach a person directly (a touchscreen on the instrument, a key switch) MAY implement elicitation/confirm as a server-initiated request.
Jobs can be paused (jobs/pause, jobs/resume) when the action declares pausable: true: the driver calls checkpoint() between steps, which blocks while paused and raises on cancel, so a person can step in without an emergency stop.
7.3 Fail closed
Any exception inside vendor code during a job, and any failure of a write after the command may have been sent, moves the device to fault with an unknown outcome and runs the driver's safe-state hook (by default the e-stop behaviour). fault and estop block all writes and invokes until safety/reset, which verifies recovery first. There is no automatic recovery. A request rejected before anything was sent does not change the device state.
7.4 Defence in depth
Descriptor limits protect setpoints and parameters. A value hidden inside a structured parameter (a 200 °C step inside an otherwise valid protocol) is caught by the driver's validate_params, which MUST run for dry runs as well as real runs, so no step executes before the whole program is known to be valid. The reference thermocycler validates every step this way.
7.5 What MHP does not do
MHP is not a functional-safety system in the IEC 61508 sense. Hard-wired e-stops, light curtains and PLC safety logic remain the primary layer; MHP is the layer that keeps an agent from asking for something unsafe, and gives it a standard way to stop everything when it sees something wrong.
7.6 Trust boundary and retries
Package code (driver.py, sim.py), recipes and mhp_run scripts are code the host executes. The runtime can refuse malformed or out-of-limit requests only while the driver and its descriptor are outside the model's authority: a model that can edit a package, or run arbitrary scripts in an unsandboxed host, can change what is enforced. Deployments SHOULD separate package authoring (a code review) from operation, and SHOULD sandbox scripts.
MHP operations are not idempotent. A request can reach a device even when its response is lost, and servers do not deduplicate requests. Clients MUST NOT retry writes or invokes automatically; after a lost response they SHOULD read state or list jobs to reconcile.