Skip to main content

Why I Built a Robot Communication Standard (and Why It Now Handles EU Law)

7 min read By Craig Merry
RCAN OpenCastor Robotics EU AI Act Open Source Protocol Design

Today I’m shipping RCAN v2.1 — the first major version of the protocol I’ve been building for the past year. It also includes rcan-py 1.1.0, rcan-ts 1.1.0, OpenCastor v2026.3.26.1, and the live Robot Registry Foundation API. This post is about the why behind the design decisions, the scenarios that drove them, and what I think this all enables.

What RCAN actually is

RCAN stands for Robot Communication and Autonomy Network. It’s an open protocol for robot-to-anything messaging with built-in identity, safety invariants, and accountability. If that sounds abstract, here’s the concrete version: it’s the thing that makes sure a robot can’t be commanded by a random script, that safety stops always work regardless of who’s asking, and that six months from now you can prove exactly what the robot did and why.

The v1.x releases covered the basics — addressing, transport, identity, federation, commitment chains. v2.1 adds the things that make robots trustworthy at scale and in regulated industries.

Scenario 1: The firmware update goes wrong

You’re running a fleet of 20 robots at a logistics warehouse. Someone pushes a firmware update. Two hours later a robot starts behaving oddly. Did the update cause it? Which robots got it? What version is actually running?

With RCAN v2.1, every robot publishes a signed firmware manifest at /.well-known/rcan-firmware-manifest.json. Every message envelope carries firmware_hash — a SHA-256 of that manifest. So you can answer those questions from your message logs: look at the firmware_hash in messages sent before and after the incident, compare against the manifest archive, and you know exactly what was running at any point in time.

The manifest is Ed25519-signed by the manufacturer’s key registered in the Robot Registry Foundation. Third parties can verify it independently.

castor attest generate   # snapshot current packages
castor attest sign --key robot-private.pem

Scenario 2: 50 robots need to cooperate on a task

Multi-robot coordination is one of the hardest problems in applied robotics, partly for technical reasons and partly for authorization reasons. Who is allowed to command multiple robots at once? How do you prevent a compromised orchestrator from sending bad commands to your entire fleet?

M2M_TRUSTED (role level 6 in v2.1) is the answer. An orchestrator can’t self-assign this role — it must register with the Robot Registry Foundation, and every robot’s CREATOR must explicitly consent to being in the fleet. The RRF then issues short-lived JWTs (24h max) containing an explicit fleet_rrns list. No wildcards, no implicit inheritance.

The important constraint: ESTOP always works. No matter what role a token claims, emergency stops bypass all authorization checks. This is non-negotiable by design.

Any CREATOR can revoke consent at any time. Robots poll the RRF revocation list every 60 seconds when M2M_TRUSTED sessions are active — revoked sessions terminate within that window. This is a real-time consent layer, not just a permission you set and forget.

Scenario 3: A regulator comes knocking

The EU AI Act applies to providers of high-risk AI systems from August 2, 2026. Robots in healthcare, transport, and public spaces will qualify. Article 16(j) requires that providers cooperate with national competent authorities — meaning when a regulator asks for your audit records, you have to be able to produce them on demand.

RCAN v2.1 implements this at the protocol level with AUTHORITY_ACCESS (41) and AUTHORITY_RESPONSE (42). An authority registers with the RRF under an authority namespace, sends a signed AUTHORITY_ACCESS request specifying what they want (audit_chain, transparency_records, sbom, firmware_manifest), and the robot responds within the specified deadline.

The owner is always notified — this is a spec requirement, not a config option. Silent authority access is a protocol violation. The entire interaction is logged to the commitment chain.

# OpenCastor handles this automatically if authority_handler_enabled: true
# castor/authority.py:
handler = AuthorityRequestHandler(rrn=rrn, notify_fn=your_notify_fn)
response = handler.handle(authority_access_payload)

Scenario 4: Did this robot actually come from a trusted supply chain?

Supply chain attacks are not hypothetical for robotics. A compromised dependency in a robot’s Python environment could mean the robot’s behavior is subtly different from what the manufacturer shipped.

The SBOM (Software Bill of Materials) layer in v2.1 uses the CycloneDX 1.5+ format with RCAN extensions. You generate it, push it to the RRF, and get back a countersignature. The countersig means the RRF has seen and recorded this exact software configuration at this exact time. It’s a chain-of-custody receipt for your software stack.

castor sbom generate
castor sbom publish --token <rrf-token>

The SBOM lives at /.well-known/rcan-sbom.json and the URL travels in every message envelope as attestation_ref. Anyone — a partner, an auditor, a regulator — can independently retrieve and verify it.

On the design of the role system

The v1.x LevelOfAssurance enum (ANONYMOUS/EMAIL_VERIFIED/HARDWARE_TOKEN) was always a placeholder. It described how a user authenticated, not what they’re authorized to do. v2.1 replaces it with a proper RBAC Role enum:

  • GUEST(1) — read-only status and discovery
  • OPERATOR(2) — control and teleoperation
  • CONTRIBUTOR(2.5) — submit training data
  • ADMIN(3) — configuration changes
  • M2M_PEER(4) — robot-to-robot, issued by ADMIN/CREATOR
  • CREATOR(5) — owns the robot, manages consent
  • M2M_TRUSTED(6) — RRF-issued fleet orchestration (see above)

The CONTRIBUTOR level at 2.5 is fractional intentionally — it needed to fit between OPERATOR and ADMIN without renumbering everything else. Yes, it’s a bit unusual for an enum. It reflects a real-world permission gradient.

LevelOfAssurance is kept as a backward-compat alias in both SDKs. Your existing code will import without changes. The values are different though, so if you were doing comparisons against specific numeric levels, those need updating.

On why this is a clean break

RCAN v2.1 is not backward compatible with v1.x. There’s no version negotiation. An OpenCastor running v2.1 will reject v1.x messages.

This was a deliberate choice. There are currently two robots in the RRF registry — both mine. When you have exactly zero external users depending on backward compat, maintaining it just adds complexity and makes the spec harder to reason about. I’d rather ship a clean break now than accumulate technical debt that makes the protocol worse for everyone who comes later.

The migration tool handles the upgrade path:

castor migrate --config robot.rcan.yaml

What this enables

The combination of these features — firmware attestation, SBOM, M2M_TRUSTED, authority access, and L5 conformance checks — creates a robot that can:

  1. Prove what it is: signed firmware manifest, verified at any time
  2. Prove where it came from: SBOM with RRF countersig
  3. Be commanded by trusted orchestrators: M2M_TRUSTED with multi-owner consent
  4. Cooperate with regulators: structured audit data on demand
  5. Be deployed in regulated industries: EU AI Act Art. 16 satisfaction at the protocol layer

That last point is the one I keep coming back to. The EU AI Act deadline is August 2, 2026. I’d rather robots be natively compliant by design than have compliance bolted on after the fact. A protocol that handles authority access the same way it handles any other message — with signing, logging, and verification — is better than a compliance add-on that lives outside the message flow.

What’s next

  • RRF production deploy — the API is built; needs a KV namespace and signing key provisioned via wrangler
  • RCAN Foundation — starting the California 501(c)(3) formation process to give the spec a governance home independent of me
  • Certification program — once the foundation is formed, Tier 1 self-attestation ($99/device) and Tier 2 verified ($499/device)
  • ISO/TC 299 liaison — the spec’s normative references page documents the ISO 13482 and ISO 10218-2 mappings; formal liaison application is the logical next step

The spec is at rcan.dev. The SDKs are at github.com/continuonai. OpenCastor is at opencastor.com.

If you’re building robots and any of this resonates, open an issue or reach out. The whole point of making this a protocol rather than a product is that it’s more useful when more robots speak it.