๐ WIA Delivery Robot Standard Ebook | Chapter 8 of 8
The previous seven chapters covered what WIA ROB-010 v1.0.0 actually specifies: the Phase 1 schemas, the Phase 2 REST surface, the Phase 3 navigation contract, the Phase 4 fleet integration, and the evidence you need to claim a conformance tier. This last chapter looks at the edges of the standard. The project README advertises five capabilities โ robot identification, mission manifests, telemetry framing, hand-off events and incident reporting โ and the stub OpenAPI file exposes /mission, /telemetry/{robotId} and /incident. Several of those capabilities are only partly defined in the four normative PHASE documents, and some are not defined at all. An implementer who ships a product today has to decide what to do about that.
The chapter therefore has three jobs. First, it states the gaps precisely, so that you know which parts of your system are standard and which are your own. Second, it offers concrete shapes for the missing pieces, built on the Phase 1 objects you already use. Everything in Sections 8.2 and 8.3 that is not a quoted Phase 1โ4 field is an author proposal, not standard text. Each proposed JSON example carries a $comment saying so, and you should keep that marker if you reuse the examples. Third, it explains how the standard is meant to evolve, which technologies are likely to push on the data contract, and how an operator can adopt ROB-010 step by step.
The README summarizes WIA-ROBOT-005 โ the alias under which the README and api/openapi.yaml publish WIA ROB-010 โ as a "cross-vendor data and protocol layer" covering identification, mission manifests, telemetry framing, hand-off events, incident reporting and conformance tiers. The PHASE documents were clearly written against a slightly different outline: they are organized around robot state, packages, routes, navigation behaviour and fleet services. The overlap is large but not complete. The table below compares each README feature with the normative text.
| README feature | What Phases 1โ4 define | What is missing | Coverage |
|---|---|---|---|
| Robot identification (stable IDs, device class, build digest, manifest signing key) | robot_id as a UUID in RobotState (Phase 1) and in every API path (Phase 2) | No device-class vocabulary, no software build digest, no key material, no registration endpoint | Partial |
| Mission manifest (origin, destination, payload class, route policy) | Package with pickup_location/dropoff_location; Route with route_preference and navigation_constraints; task assignment in Phase 4 | No single object tying robot, packages and route together; no payload_class; /mission in OpenAPI has no schema | Partial |
| Telemetry framing (pose, velocity, battery, sensor health) | RobotState fields position, heading, speed, battery_level, sensors, errors; MQTT topic fleet/robots/{robot_id}/state (Phase 4) | No envelope with sequence numbers; Error is referenced but never defined; /telemetry/{robotId} has no request schema | Mostly covered |
| Hand-off events (pickup, custody chain, delivery, exception) | Package status lifecycle; Phase 2 tracking_events with timestamp and event; access_control options | No actor on either side of a transfer, no verification result, no evidence, no tamper-evident ordering | Weak |
| Incident reporting (collision, theft, environmental hazard) | Emergency-stop triggers and failure modes (Phase 3); predictive-maintenance alert (Phase 4) | No incident object, no taxonomy, no broadcast format; CAP 1.2 appears only in the README; /incident has no schema | Absent |
| Conformance tiers (Surface, Verified, Anchored) | Annex G describes test vectors and the evidence package | Tier definitions live only in the README; Annex E refers to an "Annex A" that does not exist | Covered in Chapter 7 |
Two observations follow from the table. The first is that the gaps sit almost entirely at the boundaries between parties. The internal life of a robot โ where it is, how full its battery is, which mode it is in โ is well specified. What is thin is everything that happens when responsibility moves: when a merchant hands a parcel to a robot, when the robot hands it to a recipient, when something goes wrong in public and people other than the operator need to know. Those are exactly the moments that carry legal and commercial weight, which is why they deserve care even while the standard is silent.
The second is about conformance. A conformance claim covers only normative requirements. If you add a mission manifest or an incident endpoint, you are extending the standard, and your evidence package (Chapter 7) should say so. A practical rule is to put every extension under a clearly private namespace โ for example an OpenAPI tag named x-extensions and schema $id values under your own domain rather than under wiastandards.com โ and to list the extensions in the manifest that accompanies your test-vector matrix. That way an auditor scoring you at the Surface or Verified tier can see immediately which endpoints are in scope and which are yours.
Not every gap needs filling in every deployment. A single-tenant campus operator that runs one vendor's robots and handles incidents through a phone call to security may reasonably skip incident broadcast. A multi-vendor operator in a residential district, where parcels change hands several times and complaints must be traced, will almost certainly need hand-off events. The deciding questions are simple: does another organization consume this data, and would a dispute about it end up in front of someone who was not there? If the answer to either is yes, define the object carefully and sign it.
The proposals in this section follow three design rules so that they sit comfortably next to the Phase 1 schemas. They reuse existing Phase 1 objects by reference โ a UUID or the Phase 1 Position โ instead of redefining them. They carry a SemVer version field exactly as Phase 1 ยง6.2 requires of every payload. And they never contain secrets: the Phase 1 access_code is a credential, so a hand-off record says that a code was verified, never which code.
Phase 1 gives every robot a UUID, which is enough to route telemetry but not enough to establish trust. The README asks for a device class, a software build digest and a manifest signing key. Together those let a fleet platform answer three questions: what kind of machine is this, exactly what software is it running, and which key should its signed records verify against. A minimal record might look like this:
{
"$comment": "NON-NORMATIVE author proposal - not part of WIA ROB-010 v1.0.0",
"robot_id": "550e8400-e29b-41d4-a716-446655440000",
"device_class": "sidewalk-wheeled",
"manufacturer": "ExampleRobotics",
"model": "SW-2",
"software_build": {
"version": "4.2.1",
"digest": "sha256:b28be4727d287329e7f066ef3723c8acb2eae169e137adaf866669b2aaf25809",
"sbom_ref": "https://evidence.example.com/sw-2/4.2.1/sbom.cdx.json"
},
"manifest_signing_key": {
"kty": "OKP",
"crv": "Ed25519",
"x": "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo",
"kid": "robot-550e8400-2026a"
},
"version": "1.0.0"
}
A few choices deserve explanation. The digest field is a content hash of the deployed build, written with an algorithm prefix so that the hash function can change later without a schema change. The sbom_ref points at the SBOM that Chapter 7's evidence package already requires, which connects runtime identity to supply-chain evidence. The signing key is expressed as a JSON Web Key; the example uses an Ed25519 public key (the x value is the sample key from RFC 8037), but any algorithm your signing stack supports will do. Only the public half ever appears in this record โ the private key belongs in the robot's secure element or equivalent protected storage.
The device_class vocabulary is the part most likely to cause trouble if every vendor invents its own. Until the standard defines one, keep the list short and descriptive (for example sidewalk-wheeled, indoor-wheeled, legged) and publish it alongside your OpenAPI document. Avoid encoding speed or weight classes in the name: those depend on local rules, and the standard does not define such classes.
Update the identity record whenever an OTA update (Chapter 6) changes the build. Because Phase 4 forbids applying updates while a robot is navigating, the natural moment is right after a successful update at a charging station, before the robot accepts its next task. The fleet manager can then refuse to dispatch any robot whose reported digest does not match an approved release.
In v1.0.0 a delivery is spread across three objects: one or more Packages, a Route, and an assignment decision in the fleet manager. That is workable inside one platform, but when a merchant system, a fleet platform and a robot vendor are three different companies, each needs a single document that says "this robot will carry these packages from here to there under these rules". The README's mission manifest is that document. The proposal below composes it almost entirely from Phase 1 material:
{
"$comment": "NON-NORMATIVE author proposal - not part of WIA ROB-010 v1.0.0",
"mission_id": "751cec2d-5f3b-4d26-8ac7-835d1b024628",
"version": "1.0.0",
"created_at": "2026-09-25T09:12:00Z",
"robot_id": "550e8400-e29b-41d4-a716-446655440000",
"origin": {
"location_ref": "WAREHOUSE-001",
"position": { "latitude": 37.5665, "longitude": 126.9780 }
},
"destination": {
"location_ref": "BLDG-7-LOBBY",
"position": { "latitude": 37.5689, "longitude": 126.9812 }
},
"payload_class": "parcel-S",
"package_ids": ["7c9e6679-7425-40de-944b-e07fc1f90ae7"],
"route_id": "3b241101-e2bb-4255-8caf-4136c566a962",
"route_policy": {
"route_preference": "safest",
"navigation_constraints": {
"max_speed_ms": 1.5,
"sidewalk_only": true,
"elevator_allowed": true
}
},
"deadline": "2026-09-25T10:00:00Z"
}
The table shows where each manifest field comes from, which is the whole point of the design: a manifest should add linkage, not new meaning.
| Manifest field | Source in v1.0.0 | Note |
|---|---|---|
mission_id | New | UUID, same convention as robot_id and route_id |
robot_id | Phase 1 RobotState | Set when the Phase 4 assignment is confirmed |
origin, destination | Package pickup_location / dropoff_location | Location is undefined in Phase 1; this proposal uses a reference string plus a Phase 1 Position |
payload_class | New (README) | Coarse size class for compartment matching; the README value parcel-S is illustrative |
package_ids | Package package_id | Must be UUIDs โ not the pkg-โฆ strings shown in Phase 2 examples |
route_id | Route route_id | May be absent until the route is calculated |
route_policy | Route route_preference + navigation_constraints | Copied verbatim so a robot can plan without fetching the Route first |
deadline | Package estimated_delivery (related) | A commitment rather than an estimate; used by the assignment cost function |
Why keep payload_class when Package already has weight_kg and dimensions_cm? Because dispatch decisions are made before exact measurements are known, and because a compartment either fits a class or it does not. A small, published class list (for example S, M and L with the dimensions each accepts) lets the Phase 4 assignment algorithm filter robots by capacity without doing geometry. Keep the measured dimensions on the Package; the class is a routing hint, not a replacement.
The manifest should be immutable once the robot has accepted it. If the destination or the package list changes, issue a new manifest with a new mission_id and cancel the old one. That rule makes the hand-off chain in the next section unambiguous: every custody event refers to exactly one version of the plan.
Phase 2 returns tracking_events such as created, assigned_to_robot and picked_up. Those are useful for a tracking page, but they record only that something happened. They do not say who gave the parcel to whom, how the recipient was verified, what evidence was captured, or whether any event has been removed or reordered after the fact. For a delivery that is later disputed โ "the robot never arrived", "the box was empty" โ those are the questions that matter.
The proposed hand-off event adds exactly that information:
{
"$comment": "NON-NORMATIVE author proposal - not part of WIA ROB-010 v1.0.0",
"event_id": "ae5ad7e2-24e8-4974-9fd6-621cd72443fd",
"package_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"mission_id": "751cec2d-5f3b-4d26-8ac7-835d1b024628",
"sequence": 3,
"event_type": "delivery",
"timestamp": "2026-09-25T09:41:27Z",
"robot_id": "550e8400-e29b-41d4-a716-446655440000",
"from_party": { "role": "robot", "id": "550e8400-e29b-41d4-a716-446655440000" },
"to_party": { "role": "recipient", "id": "recipient-ref-5c1f" },
"position": { "latitude": 37.5689, "longitude": 126.9812, "accuracy": 3.0, "source": "fused" },
"verification": {
"method": "access_code",
"result": "verified",
"attempts": 1
},
"evidence": [
{ "type": "compartment_sensor", "value": "door_closed_empty" },
{ "type": "photo", "digest": "sha256:5cfa92ddf11aab50f8215dc7e1b1f803b68729093e39d01ff21b333bc975bae2" }
],
"resulting_status": "delivered",
"prev_event_digest": "sha256:be58b58954771fc6f9bc09cd6ec360d0b400889683581e233d7fc4578b2fd27d",
"version": "1.0.0"
}
Four event types cover the README's list: pickup (a sender or merchant loads the robot), custody_transfer (a robot hands over to another robot, a locker or a human courier), delivery (the recipient takes the parcel), and exception (anything that stops the normal flow, with a reason code such as recipient_absent, verification_failed or compartment_fault). Each event names the resulting Phase 1 package status, so a platform that only understands v1.0.0 can still update its state machine.
Hand-off event_type | Typical resulting_status (Phase 1) | Verification examples |
|---|---|---|
pickup | picked_up | Merchant QR scan; compartment weight change |
custody_transfer | in_transit (unchanged) | Both parties sign the same event |
delivery | delivered | access_code, qr_code, signature, or biometric check as set in access_control |
exception | failed or returned | Reason code plus the last verification attempt |
The verification block records the method and the outcome, never the credential. Logging the four-to-eight digit code, even hashed, would make it trivially recoverable by brute force, so the record says only "method": "access_code", "result": "verified". The recipient is referenced by an opaque identifier that the merchant can resolve; the robot-side record does not need a name or phone number.
Evidence is stored by digest. A photograph of the closed, empty compartment is strong evidence of delivery, but it is also personal data if a face or a door number appears in it. Storing only the hash in the event, and the image itself in a separate store with its own retention rules, lets the custody chain be kept for as long as disputes may arise while the image can be deleted on the shorter privacy schedule that Phase 4 ยง7.2 describes. Chapter 6 made the same point about telemetry retention and audit retention running on different clocks.
Finally, sequence and prev_event_digest turn the list of events into a hash chain. Each event includes the digest of the previous one, so removing or editing an earlier event breaks every later link. Signing each event with the robot's manifest signing key from 8.2.1 โ for example inside a DSSE envelope, the same format Annex G uses for the evidence manifest โ adds origin authentication. The verification logic is short:
import hashlib, json
def canonical(event: dict) -> bytes:
# Deterministic serialization: sorted keys, no whitespace, UTF-8.
# (A production system should adopt RFC 8785 JCS instead.)
body = {k: v for k, v in event.items() if k != "signature"}
return json.dumps(body, sort_keys=True, separators=(",", ":"),
ensure_ascii=False).encode("utf-8")
def digest(event: dict) -> str:
return "sha256:" + hashlib.sha256(canonical(event)).hexdigest()
def verify_chain(events: list[dict]) -> list[str]:
problems = []
events = sorted(events, key=lambda e: e["sequence"])
for i, ev in enumerate(events):
if ev["sequence"] != i + 1:
problems.append(f"gap before sequence {ev['sequence']}")
if i == 0:
if ev.get("prev_event_digest") is not None:
problems.append("first event must not reference a predecessor")
elif ev.get("prev_event_digest") != digest(events[i - 1]):
problems.append(f"broken link at sequence {ev['sequence']}")
return problems
Two cautions apply. Hash chains only work if every party serializes the event the same way; the sketch uses sorted keys and compact separators, but a production system should adopt a published canonicalization scheme such as the JSON Canonicalization Scheme (RFC 8785). And a chain proves ordering and integrity, not truth: a robot with a faulty compartment sensor will produce a perfectly chained, perfectly signed record of a wrong observation. Evidence is only as good as the sensor behind it, which is one reason the identity record ties each event to a specific build.
Telemetry is the gap closest to being filled. RobotState already carries pose, velocity, battery and sensor data, and Phase 4 names the MQTT topic. What is missing is a thin frame around each RobotState so that consumers can detect loss and reordering and know which schema version they are reading. Because MQTT QoS 1 is at-least-once (Chapter 6), a sequence number also makes duplicate removal cheaper than comparing timestamps:
{
"$comment": "NON-NORMATIVE author proposal - not part of WIA ROB-010 v1.0.0",
"frame_version": "1.0.0",
"robot_id": "550e8400-e29b-41d4-a716-446655440000",
"seq": 18422,
"sent_at": "2026-09-25T09:30:05.120Z",
"content_type": "application/json",
"schema": "https://wiastandards.com/schemas/delivery-robot/v1/robot-state.json",
"payload": { "...": "one RobotState object (Chapter 3)" }
}
The same frame suits the stub endpoint POST /telemetry/{robotId}, whose 202 Accepted fits asynchronous ingestion. Do not smuggle new fields into payload; define missing objects such as Error in your own $defs and propose them upstream (Section 8.4).
The README states that ROB-010 is interoperable with the OASIS Common Alerting Protocol (CAP) 1.2 for incident broadcast, but no PHASE document says how. CAP is an XML format for public warnings, widely used by emergency-alerting systems. It is a good fit for one class of robot incident โ conditions that other people need to avoid โ and a poor fit for others. This section separates the internal incident record from the public broadcast and shows how to map one onto the other.
Every incident should first become an internal record, whatever happens next. The proposed shape below reuses the Phase 1 Position and links to the mission, so an investigator can join it with telemetry and hand-off events:
{
"$comment": "NON-NORMATIVE author proposal - not part of WIA ROB-010 v1.0.0",
"incident_id": "205fd89a-4338-4bd5-bfd2-9770eac853d7",
"incident_type": "environmental_hazard",
"subtype": "sidewalk_blocked",
"detected_at": "2026-09-25T09:18:40Z",
"robot_id": "550e8400-e29b-41d4-a716-446655440000",
"mission_id": "751cec2d-5f3b-4d26-8ac7-835d1b024628",
"position": { "latitude": 37.5671, "longitude": 126.9791, "accuracy": 2.5, "source": "fused" },
"severity": "moderate",
"robot_response": "rerouted",
"description": "Construction barrier fully blocks the sidewalk; no passable gap for wheelchairs.",
"media": [
{ "type": "photo", "digest": "sha256:9d13f91c65a4d32a22b9ec535fe33ec4e9908fd218a56cc9d9eff11af350205a", "faces_blurred": true }
],
"broadcast": { "cap_scope": "Public", "cap_identifier": "urn:example:wia-rob:incident:205fd89a" },
"version": "1.0.0"
}
A small taxonomy covers the README's three categories and connects them to Phase 3 behaviour:
incident_type | Example subtypes | Related Phase 3/4 mechanism | Broadcast via CAP? |
|---|---|---|---|
collision | contact with person, contact with object, contact with vehicle | Emergency stop, telemetry snapshot, operator alert | Usually no โ internal and, where required, to authorities through their own channels |
theft_or_tamper | forced compartment, robot lifted or carried, repeated failed codes | Tipping/skidding e-stop trigger; access-control failures | Restricted scope only (operator security, police liaison) |
environmental_hazard | sidewalk blocked, flooding, ice, fallen tree, broken signal | Stuck timer, rerouting, crosswalk protocol | Yes, when the hazard affects the public |
robot_fault | sensor failure, comms loss, battery critical | Failure-mode table | Only if the stopped robot itself obstructs the way |
The last column matters. A fleet is a network of moving sensors on public sidewalks: broadcasting everything would be intrusive, broadcasting nothing wastes information that could help pedestrians. A reasonable rule is to publish only hazards to people other than the operator, stripped of anything that identifies a person.
A CAP message has an alert element carrying message-level metadata, one or more info blocks describing the event, and area blocks inside each info describing where it applies. The mapping from the internal record is direct:
| Incident record | CAP 1.2 element | Guidance |
|---|---|---|
incident_id | alert/identifier | Use a stable URI; later updates and cancellations refer to it in references |
| Operator contact | alert/sender, info/senderName | The operator, never an individual robot |
| Publication time | alert/sent | CAP requires an explicit offset (for example +09:00, or -00:00 for UTC); a trailing Z is not allowed |
broadcast.cap_scope | alert/scope | Public for hazards; Restricted with a restriction text for theft or tamper |
incident_type/subtype | info/category, info/event | Sidewalk obstruction fits Transport or Safety; flooding fits Met or Env |
severity | info/severity, urgency, certainty | A robot that saw the hazard directly reports Observed |
robot_response | info/responseType, instruction | Describe what people should do, not what the robot did |
position | area/circle or polygon | Circle is "lat,lon radius" with the radius in kilometres |
The resulting message for the blocked-sidewalk example:
<?xml version="1.0" encoding="UTF-8"?>
<alert xmlns="urn:oasis:names:tc:emergency:cap:1.2">
<identifier>urn:example:wia-rob:incident:205fd89a</identifier>
<sender>fleet-ops@example.com</sender>
<sent>2026-09-25T18:19:05+09:00</sent>
<status>Actual</status>
<msgType>Alert</msgType>
<scope>Public</scope>
<info>
<language>en-US</language>
<category>Transport</category>
<event>Sidewalk obstruction</event>
<responseType>Avoid</responseType>
<urgency>Expected</urgency>
<severity>Minor</severity>
<certainty>Observed</certainty>
<senderName>Example Campus Delivery Operations</senderName>
<headline>Sidewalk blocked by construction barrier</headline>
<description>A construction barrier blocks the full width of the sidewalk. There is no step-free gap.</description>
<instruction>Wheelchair and stroller users should use the opposite sidewalk.</instruction>
<expires>2026-09-25T21:00:00+09:00</expires>
<parameter>
<valueName>detectedBy</valueName>
<value>autonomous-delivery-robot</value>
</parameter>
<area>
<areaDesc>North sidewalk between Gate 2 and Building 7</areaDesc>
<circle>37.5671,126.9791 0.03</circle>
</area>
</info>
</alert>
Notice what the message leaves out: the robot's UUID, the mission, the photo, and anything about the parcel or its recipient. The parameter element says only that an autonomous robot detected the hazard, which is useful context for a reader deciding how much to trust it. When the hazard is cleared, the operator sends a second message with msgType set to Cancel and a references element naming the original; if the situation changes, Update does the same. The expires element is a safety net for the case where nobody remembers to cancel.
Phase 4 ยง7.2 requires face blurring before upload and data minimization. For public broadcast, apply a stricter filter as a separate, testable step in the pipeline, and treat the following as release criteria:
resource link, not the raw capture.Restricted scope, and a documented rule for which incident types may be published without review.Build test vectors for this filter just as Chapter 7 did for the schemas: a positive vector for a well-formed hazard alert, and negative vectors for alerts that leak an identifier. A filter that is not tested tends to fail silently the first time someone adds a field to the internal record.
Each PHASE document ends with an Annex F adoption roadmap that sorts its content into three stability tiers. These are distinct from the conformance tiers of Chapter 7: conformance tiers describe how strongly an implementation proves itself, while roadmap tiers describe how likely the standard's own text is to change.
| Roadmap tier | What it covers (Annex F) | Change rule | What an implementer should do |
|---|---|---|---|
| Stable | Normative sections marked MUST / MUST NOT | SemVer; a breaking change needs a major version and at least 90 days of overlap with the previous major on WIA-published reference implementations | Build against it; pin the major version; plan migrations inside the overlap window |
| Provisional | The annex material itself | May be promoted to normative status without a major version bump if community feedback supports it | Implement where useful, but isolate it behind configuration so that a promotion with changed wording is cheap to absorb |
| Reference | Test vectors, simulator behaviour, the reference TypeScript SDK | Versioned independently, so mistakes can be corrected without amending the PHASE document | Record the exact reference version you tested against in the evidence package |
Two practical consequences follow. First, the 90-day overlap is a minimum on WIA's side, not a promise about your partners. If a merchant integration or a vendor's firmware lags behind, you may need to accept both major versions for longer. The version field that Phase 1 puts in every payload is what makes that possible: route by major version at the edge and keep separate validators for each.
Second, the Provisional tier is where your extensions can enter the standard. Annex F says that comments on the roadmap are accepted through the GitHub issues tracker of the WIA-Official organization and that promotions are announced through release notifications. A proposal is far more likely to be accepted if it arrives as a package: the schema, positive and negative test vectors in the Annex G layout, a short rationale linking it to the README feature it fulfils, and evidence that it has run in a real deployment. The proposals in Section 8.2 were written in that spirit โ built from existing Phase 1 objects so that promoting them would be additive.
Be aware of loose ends in the current text when you read the annexes. Annex F refers to an "Annex D" and Annex E to an "Annex A", and neither exists in any PHASE file. Annex F also says review outcomes are recorded in a version-history table at the start of each document, but v1.0.0 has only a version, status and date header. Annex E's statement that renaming or removing a field needs only a minor version bump contradicts Phase 1 ยง6.2; as Chapter 3 recommended, treat any rename or removal as breaking and bump the major version. Filing these as issues is a useful first contribution.
The standard is a data and protocol layer, so the question to ask of each technology trend is not whether it will make robots better but which fields it will strain. The table summarizes the likely pressure points; each is discussed below. All suggested additions are non-normative.
| Trend | Affected element in v1.0.0 | Pressure on the contract | Possible addition |
|---|---|---|---|
| Indoor and elevator delivery | navigation_constraints.elevator_allowed; Position.altitude | Floors are not altitudes; elevator use needs a call-and-ride protocol | Building and floor identifiers in Position; an elevator-session object |
| V2X and smart crosswalks | Phase 3 crosswalk protocol (perception-based signal check) | Signal state may arrive as a message rather than an observation | Signal-state source and trust level recorded in decision logs |
| Solid-state LiDAR and new sensors | SensorReadings lidar, cameras, ultrasonic, imu | Different fields of view and failure behaviour; health matters more than raw data | Per-sensor health and calibration status; extensible sensor list |
| Edge compute on the robot | SensorReadings guidance (detections and image_url, not raw frames) | More processing on board means fewer raw uploads and more derived data | Model and build identity on each derived record |
| Learned planners | Phase 3 priority order and state machine | Decisions are harder to explain after the fact | Decision records with reason codes, confidence and model version |
Phase 1 already anticipates buildings: navigation_constraints includes elevator_allowed. But a boolean only grants permission. To actually ride an elevator, a robot needs a building identifier, a floor, a way to call the car and confirm the door is open, and a rule about sharing the car with people. Altitude in metres, which Phase 1 Position offers, is not a substitute for a floor number: floor heights vary, basements have negative floors, and many buildings skip numbers. A future revision would benefit from optional building_id and floor fields on Position and from an elevator-session object recording call, boarding, travel and exit. Until then, keep these in your own extension and never overload altitude.
The Phase 3 crosswalk protocol assumes the robot checks the signal by perception. Where intersections publish signal phase and timing electronically, a robot could know the state before it can see the lamp. That is useful, but it introduces a new question for the data contract: when the robot crossed, what did it believe, and why? A decision log should record the signal source (observed, broadcast, or both) and whether the two agreed. Phase 3's priority order still applies โ a broadcast "walk" does not override an observed vehicle โ and the log is what lets an investigator confirm that it did.
The Phase 1 SensorReadings object is organized by sensor type, which ages quickly as new modalities appear. The more durable information for a fleet platform is sensor health: whether each sensor is producing plausible data, when it was last calibrated, and whether the robot has degraded its behaviour because of it (the Phase 3 failure-mode table, for instance, reduces speed when LiDAR is lost). As more perception runs on the robot, the cloud receives detections instead of raw data, which is good for bandwidth and privacy. The price is that each detection now depends on a model; recording the model and build identity alongside derived records keeps them interpretable after an update.
Chapter 5 described A* and DWA, whose behaviour can be reconstructed from their cost terms. Planners that learn from data are harder to audit after the fact. The standard does not need to take a position on planning methods, but the data contract can require that whatever the method, a robot leaves a trace: which state it was in, which constraint was binding, what confidence it assigned to the relevant detections, and which model version made the decision. That trace is what makes Phase 3's priority order โ safety first, then rule compliance, task completion, efficiency and user experience โ testable for a learned system as well as a classical one.
Delivery robots operate in space that was built for people, and the most important ethical questions are about sharing that space fairly. A data standard cannot settle these questions, but it can make good behaviour easier to specify, measure and audit.
Accessibility. Sidewalks are primary routes for wheelchair users, people with low vision, older pedestrians and parents with strollers. Phase 3 already asks robots to keep a larger margin around wheelchairs and strollers and never to block ramps or doorways. The incident taxonomy in Section 8.3 adds a way to turn a robot's observations into something useful for those same people โ for example, reporting an obstruction that removes the only step-free route. Operators should test behaviour with disabled users, not only with able-bodied staff, and should treat a robot that stops on a narrow sidewalk as an accessibility failure even when it is technically "safe".
Public trust and legibility. People are more comfortable around machines whose intentions they can read. Phase 3's crosswalk protocol asks robots to signal intent with lights or sound; the same idea applies elsewhere. Clear markings identifying the operator and a way to report a problem, together with the hand-off and incident records proposed here, make it possible to answer a complaint with facts rather than assurances.
Camera privacy. A robot's cameras see bystanders who have not agreed to anything. Phase 4 requires face blurring before upload, data minimization and retention limits, and privacy law such as the GDPR or Korea's Personal Information Protection Act will impose its own obligations. The design choices in this chapter โ evidence stored by digest, public broadcasts stripped of identifiers, short retention for images and longer retention for integrity records โ are meant to make those obligations easier to meet.
Work and labour. Loading, remote supervision, maintenance and exception handling all still require people. Whether automation displaces or supports workers is a policy question this book does not try to answer; the standard can at least make that human work explicit and measurable rather than hidden behind an average success rate.
The steps below summarize the book as a sequence an operator or vendor can follow. Each step produces an artefact that the next one depends on, and each points to the chapter that explains it.
| # | Step | Output | Chapter |
|---|---|---|---|
| 1 | Fix identifiers and conventions: UUIDs for robots, packages and routes; heading and coordinate frames; SemVer in every payload | Written conventions note shared with all partners | 1โ3 |
| 2 | Adopt the Phase 1 schemas and define the referenced-but-missing objects (CargoStatus, ActiveRoute, Error, Contact, Location) | Schema bundle with your own $defs, documented | 3 |
| 3 | Validate at every boundary: robot to cloud, cloud to partner, partner to cloud | Validators in CI and at ingestion, with rejection metrics | 3, 7 |
| 4 | Implement the Phase 2 REST surface with OAuth 2.0 scopes and the error envelope | Full OpenAPI 3.1 document for the Phase 2 paths | 4 |
| 5 | Implement the Phase 3 state machine, emergency stop and failure-mode timers, with a mapping to the Phase 1 mode enum | Behaviour specification and logged timers | 5 |
| 6 | Connect the fleet: MQTT telemetry with de-duplication, task assignment, charging and signed OTA updates | Running fleet pipeline with clock synchronization | 6 |
| 7 | Decide on extensions (identity, mission manifest, hand-off, incident) and put them in a private namespace | Extension list declared in the OpenAPI document and manifest | 8 |
| 8 | Build positive and negative test vectors for every requirement you claim, including extensions and the privacy filter | Vector matrix with no unexplained skips | 7, 8 |
| 9 | Assemble and sign the evidence package: SBOM, OpenAPI document, vector matrix, signed manifest | Surface-tier claim; readiness for a Verified audit | 7 |
| 10 | Automate re-publication every quarter and feed gaps back to the standard through GitHub issues | Continuous evidence stream suitable for the Anchored tier | 7, 8 |
Start step 3 earlier than feels necessary: boundary validation is the cheapest way to discover that two partners read the same field differently. And keep the conformance claim honest. A Surface-tier claim that is accurate is worth more to a partner than an Anchored-tier aspiration that the evidence does not support, and the standard's own Annex G says that a test skipped without recorded justification counts as a failure.
A delivery robot standard is ultimately about trust between companies that must share one sidewalk, one fleet platform and one customer. The schemas make the data understandable; the evidence makes the claims checkable. The rest depends on how carefully each implementer treats the moments when a parcel, or a person's safety, passes from one party to another.
โ Chapter 7: Testing, Conformance and Certification โ Surface, Verified, Anchored | Back to Index