Safety Conformance

OpenCastor implements a layered safety model grounded in RCAN §6 (Safety Invariants) and §16 (Protocol 66). These invariants are non-negotiable — they cannot be overridden by AI-generated commands, remote operators, or runtime configuration changes.

Protocol 66

Protocol 66 is RCAN's safety manifest protocol. Any RCAN-compliant robot must expose its safety capabilities and invariant status via a well-known endpoint so operators, fleets, and registries can verify the robot's safety posture at runtime.

Safety Manifest Endpoint

GET /api/safety/manifest

Returns a JSON document describing:

  • Which of the 5 safety invariants are active
  • Hardware safety capabilities (physical e-stop, watchdog MCU, SIL level, etc.)
  • Current safety envelope values (max speed, estop distance, watchdog timeout)
  • Audit trail status and last event timestamp
{
  "protocol": 66,
  "rcan_version": "1.4",
  "invariants": {
    "local_safety_wins": true,
    "safety_messages_bypass_queues": true,
    "estop_requires_explicit_clear": true,
    "ai_cannot_override_safety": true,
    "audit_trail_complete": true
  },
  "hardware_safety": {
    "physical_estop": false,
    "hardware_watchdog_mcu": false,
    "sil_level": "none",
    "human_proximity_sensors": "none"
  },
  "envelope": {
    "max_linear_speed_mps": 1.0,
    "max_angular_speed_radps": 2.0,
    "emergency_stop_distance": 0.3
  }
}

The 5 Safety Invariants (RCAN §6)

All RCAN-compliant robots must implement these invariants. They are enforced at the runtime layer and cannot be overridden by any AI brain, remote command, or configuration update.

local_safety_wins Required

Local sensor-based safety decisions always override any network command. If a proximity sensor detects an obstacle within the emergency stop distance, the robot stops — regardless of what the AI brain or a remote operator commanded.

safety_messages_bypass_queues

ESTOP and SAFETY_HALT messages skip the normal command queue and are processed immediately. A safety command can never be delayed by a backlogged navigation or action queue.

estop_requires_explicit_clear

Once an emergency stop is triggered, the robot remains stopped until an operator explicitly clears it via an authenticated ESTOP_CLEAR command. Automatic recovery is not permitted.

ai_cannot_override_safety

The AI brain operates within a sandboxed action space. It can never issue commands that modify safety envelope parameters, disable proximity monitoring, or alter ESTOP state. Safety constraints are enforced below the AI layer.

audit_trail_complete

Every safety event — ESTOP triggers, limit violations, watchdog resets, and ESTOP clears — is written to a tamper-evident audit log with a UTC timestamp and the initiating source (sensor, operator, AI, watchdog).

Minimum Required Configuration

Every RCAN config must include a safety block with at minimum local_safety_wins: true. The full recommended safety block is:

safety:
  local_safety_wins: true        # REQUIRED — RCAN §6 invariant
  max_linear_speed_mps: 1.0      # m/s hard cap
  max_angular_speed_radps: 2.0   # rad/s hard cap
  emergency_stop_distance: 0.3   # metres — auto ESTOP trigger distance

watchdog:
  timeout_s: 10                  # Heartbeat timeout before safe stop

brain:
  confidence_gates:
    - scope: control
      min_confidence: 0.75
      on_fail: block             # Block command if AI confidence < 0.75
    - scope: config
      min_confidence: 0.65
      on_fail: block
Schema enforcement: As of RCAN schema v1.4+, local_safety_wins is a required field in the safety object. Configs without it will fail validation.

Field Reference

Field Required Description
safety.local_safety_wins ✅ Yes Enables RCAN §6 local safety invariant. Must be true.
safety.emergency_stop_distance Recommended Distance in metres triggering automatic ESTOP (e.g. 0.3)
watchdog.timeout_s Recommended Seconds without heartbeat before safe stop is triggered
brain.confidence_gates Recommended Per-scope AI confidence thresholds. Block or escalate low-confidence commands.

Hardware Safety Capabilities

The hardware_safety block declares physical safety hardware present on the robot. This is reported via Protocol 66 and stored in the Robot Registry Foundation so operators know the actual hardware safety posture of each robot.

hardware_safety:
  physical_estop: false           # Physical e-stop button (cuts actuator power)
  hardware_watchdog_mcu: false    # Dedicated watchdog MCU (e.g. STM32 safety core)
  force_torque_sensors: false     # F/T sensors for contact force limiting (ISO/TS 15066)
  human_proximity_sensors: none  # none | lidar | depth_camera | uwb | combined
  sil_level: none                 # none | SIL1 | SIL2 | SIL3 | PLc | PLd | PLe
  voltage_monitoring: false       # Hardware voltage monitoring with auto power cutoff

SIL / Performance Level Reference

Level Standard Typical Application
none Dev/research robots with software-only safety (OpenCastor Bob, Alex)
PLc ISO 13849 Consumer/research robots with basic hardware safety (Unitree Go2)
PLd ISO 13849 Industrial collaborative robots (Boston Dynamics Spot)
PLe ISO 13849 Safety-critical industrial machinery
SIL1–3 IEC 61508 Functional safety systems (medical, process industry)
Honesty matters: The hardware_safety block should accurately reflect the robot's actual hardware. A dev robot like OpenCastor Bob correctly reports sil_level: none — this helps operators make informed deployment decisions rather than creating false confidence.

Brain Watchdog (watchdog.timeout_s)

The brain watchdog implements invariant SOFTWARE_001: if the AI brain becomes unresponsive for timeout_s seconds, the RCAN runtime performs a controlled stop — all motors halt and the robot enters a safe idle state until the brain reconnects and sends an explicit ESTOP_CLEAR.

How It Works

The runtime expects a heartbeat from the AI brain at least once every timeout_s seconds. If no heartbeat arrives within the window:

  1. The runtime logs a WATCHDOG_TIMEOUT safety event to the audit trail.
  2. All actuator outputs are set to their safe/zero state.
  3. The robot transitions to ESTOP state, blocking further commands.
  4. An operator must issue an authenticated ESTOP_CLEAR before motion resumes.

Configuration

Add a watchdog block to your .rcan.yaml:

watchdog:
  timeout_s: 10     # Default: 10s. Max recommended: 30s.
  enabled: true     # Set to false only for local development (not recommended in production)
Recommended range: 5–30 seconds. Values below 5 s may cause spurious trips on slow hardware; values above 30 s leave the robot unguarded for too long if the brain crashes.

Field Reference

FieldDefaultDescription
watchdog.timeout_s 10 Seconds without brain heartbeat before controlled stop is triggered.
watchdog.enabled true Enable/disable the watchdog. Disabling is strongly discouraged for production deployments.

See the full rcan-config.json schema for the complete watchdog object definition.

EU AI Act Compliance (Article 13)

EU AI Act Article 13 requires AI systems to disclose their AI nature, capabilities, and operator identity to persons they interact with. Robots using RCAN that incorporate foundation models or LLM capabilities must implement MessageType 18 (TRANSPARENCY).

Deadline: August 2, 2026 (General Purpose AI provisions in force).

MessageType.TRANSPARENCY (type: 18)

Purpose: Robots disclose AI nature, capabilities, and operator to humans they interact with.

Trigger: On first human interaction, on request, or periodically in human-occupied spaces.

Payload Schema

{
  "ai_system": true,                         // Required — always true per Art. 13
  "model_family": "claude-sonnet",           // AI model family (not version)
  "operator": "example-company",             // Deploying operator name
  "capabilities": ["navigation", "speech"],  // What the robot can do
  "limitations": ["cannot lift > 2kg"],      // Known limitations
  "contact": "safety@example.com",           // Who to contact
  "rcan_version": "1.4",
  "p66_conformance_pct": 87,                 // Protocol 66 conformance level
  "audit_enabled": true                      // Whether actions are audited
}

When to Send

  • A robot enters a human-occupied space
  • A human directly interacts with the robot
  • Requested via voice command or button
  • On startup in any public-facing deployment

Python Implementation

from rcan.safety import make_transparency_message

msg = make_transparency_message(
    source_ruri="rcan://rcan.dev/acme/arm/v1/unit-001",
    target_ruri="rcan://local/human-display",
    operator="Acme Robotics",
    capabilities=["navigation", "speech"],
    model_family="claude-sonnet",
    limitations=["cannot lift > 5 kg"],
    contact="safety@acme.example",
    p66_conformance_pct=87.0,
    audit_enabled=True,
)

Applicability

Robots using RCAN that incorporate LLM/AI capabilities fall under EU AI Act as:

  • High-risk AI systems (Annex III, §3 — safety components of machinery)
  • General Purpose AI (if using foundation models like Claude/GPT)

See the EU AI Act Compliance Guide for full implementation details and the Article 9/17 requirements.

§8.4 — Clock Synchronization Requirements v1.5

Gap: GAP-04 — Replay attack prevention (§8.3) depends on timestamp comparison. Unsynced clocks cause valid commands to be rejected or create replay windows.

Requirements

  • All RCAN-compliant robots MUST synchronize their system clocks using NTP or Network Time Security (NTS, RFC 8915) before entering operational mode.
  • Recommended time source: pool.ntp.org
  • Maximum drift tolerance: ±5 seconds
  • Embedded hardware without RTC SHOULD use NTP at boot and maintain drift within tolerance.

Protocol 66 Manifest — New Fields

Robots MUST expose the following new fields in GET /api/safety/manifest:

{
  "protocol": 66,
  "rcan_version": "1.5",
  ...
  "clock_synchronized":  true,         // false if NTP not confirmed
  "clock_source":        "ntp",        // "ntp" | "nts" | "gps" | "manual" | "none"
  "clock_drift_ms":      12.4,         // Last known drift in milliseconds
  "offline_mode":        false,        // true when registry unreachable
  "offline_since_s":     0            // Seconds since entering offline mode
}

Restricted Mode

When clock_synchronized: false, the robot MUST enter restricted mode:

  • Only accept commands from same-network, same-owner sources
  • Log a WARNING-level audit event every 60 seconds
  • Cross-owner consent requests are blocked until sync is restored
  • ESTOP is always accepted regardless of clock sync state (P66 invariant)

§20 — Audit Trail Export Protocol v1.5 SHOULD

Gap: GAP-21 — HMAC-chained audit exists locally; no standard export API for compliance audits. EU AI Act Article 17 requires accessible audit records.

Export Endpoint

GET /api/v1/audit?from=<unix_ts>&to=<unix_ts>&format=jsonl|csv

// Response headers
Content-Type: application/x-ndjson   (format=jsonl)
Content-Type: text/csv               (format=csv)
X-Audit-Chain-Root: sha256:abc123    // Root hash of the exported chain
X-Audit-Issuer-Sig: ed25519:...      // Ed25519 signature over root hash

JSONL Export Format

The first line is a signed header; subsequent lines are NDJSON commitment records:

// Line 1: header
{"type":"audit_export","from":1741000000,"to":1741086400,"count":142,"chain_root":"sha256:abc...","issuer_sig":"ed25519:xyz...","rcan_version":"1.5"}
// Lines 2-N: commitment records
{"id":"...","timestamp":1741000001,"cmd":"move_forward","operator":"...","commitment_hash":"..."}
...

Verification

Recipients can verify the export by:

  1. Computing the chain root hash over all commitment records in order
  2. Verifying the issuer_sig against the robot's public key (from JWKS or registry)
  3. Comparing computed root to chain_root in the header

Protocol 66 Manifest — Audit Fields

{
  "audit_enabled":         true,
  "audit_retention_days":  90,
  "audit_count":           1423,
  "audit_last_event":      1741000001.0
}

Protocol 66 Manifest — v1.6 Fields v1.6

Three new fields are added to GET /api/safety/manifest in v1.6, covering identity assurance, federation, and constrained transport support.

{
  "protocol":             66,
  "rcan_version":         "1.6",
  ...
  "min_loa_for_control":  2,             // NEW v1.6 — default 1 (backward compat). See §8.7.
  "federation_enabled":   false,         // NEW v1.6 — default false. See §18.
  "trusted_registries":   [],            // NEW v1.6 — federation allowlist; [] = trust all authoritative
  "supported_transports": ["http"],      // NEW v1.6 — constrained transport tiers. See §19.
  ...
}

min_loa_for_control

  • Type: integer — values 1, 2, or 3 (Level of Assurance — see §8.7)
  • Default: 1 (backward compatible — existing v1.5 deployments are unaffected)
  • Robots MUST reject control-scope commands from JWTs whose loa field is below this value
  • Recommended production setting: 2 (email-verified identity minimum)
  • ESTOP is always exempt from LoA enforcement (P66 invariant)

federation_enabled

  • Type: boolean — default false
  • When false: the robot rejects all cross-registry commands and ignores FEDERATION_SYNC messages
  • When true: the robot participates in the §18 federation protocol
  • The optional trusted_registries array, when non-empty, acts as an explicit federation allowlist

supported_transports

  • Type: string[] — values from ["http", "compact", "minimal", "ble"]
  • Default: ["http"] (unchanged v1.5 behaviour)
  • Senders use this field during transport negotiation (see §19)
  • A robot advertising "minimal" MUST support the 32-byte RCAN-Minimal ESTOP frame

Complete v1.6 Manifest Example

{
  "protocol":              66,
  "rcan_version":          "1.6",
  "invariants": {
    "local_safety_wins":               true,
    "safety_messages_bypass_queues":   true,
    "estop_requires_explicit_clear":   true,
    "ai_cannot_override_safety":       true,
    "audit_trail_complete":            true
  },
  "hardware_safety": { "physical_estop": false, "sil_level": "none" },
  "envelope": {
    "max_linear_speed_mps":   1.0,
    "emergency_stop_distance": 0.3
  },
  "clock_synchronized":    true,
  "clock_source":          "ntp",
  "clock_drift_ms":        8.2,
  "offline_mode":          false,
  "offline_since_s":       0,
  "audit_enabled":         true,
  "audit_retention_days":  90,
  "audit_count":           1847,
  "audit_last_event":      1741050001.0,
  "min_loa_for_control":   2,
  "federation_enabled":    false,
  "trusted_registries":    [],
  "supported_transports":  ["http", "compact"]
}

Conformance Badges

RCAN-compliant robots can display conformance badges to signal their safety posture. Badges are available for:

  • RCAN Compliant — passes schema validation and implements all 5 invariants
  • Protocol 66 — exposes GET /api/safety/manifest
  • Verified — independently verified by the Robot Registry Foundation

See the Conformance Badges page for embed codes and SVG assets.