<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title>ROBOT.md Spec v1 — Format Specification</title>
  <meta name="description"
    content="The ROBOT.md format specification — v1. YAML frontmatter schema, required fields, body sections, validation rules, and RCAN 3.0+ conformance requirements.">
  <meta name="theme-color" content="#F4EFE6">

  <meta property="og:title" content="ROBOT.md Spec v1">
  <meta property="og:description"
    content="ROBOT.md format specification — one file per robot, YAML + markdown, RCAN 3.0+ conformant.">
  <meta property="og:url" content="https://robotmd.dev/spec/">
  <meta property="og:type" content="website">
  <meta name="twitter:card" content="summary_large_image">

  <link rel="canonical" href="https://robotmd.dev/spec/">

  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link
    href="https://fonts.googleapis.com/css2?family=Inter+Tight:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600&family=Fraunces:ital,wght@1,400;1,600&display=swap"
    rel="stylesheet">

  <link rel="stylesheet" href="/css/design.css">

  <style>
    /* ============================================================
       SPEC PAGE — two-column layout with sidebar
       ============================================================ */
    .spec-layout {
      display: grid;
      grid-template-columns: 220px 1fr;
      gap: 48px;
      padding: 48px 0 80px;
      align-items: start;
    }
    @media (max-width: 900px) {
      .spec-layout { grid-template-columns: 1fr; gap: 32px }
    }

    /* ---- Sidebar ---- */
    .spec-sidebar {
      position: sticky;
      top: 72px;
    }
    @media (max-width: 900px) {
      .spec-sidebar { position: static }
    }

    .spec-sidebar .sidebar-label {
      font-family: var(--mono);
      font-size: 10px;
      letter-spacing: .18em;
      text-transform: uppercase;
      color: var(--accent);
      margin-bottom: 12px;
    }

    .spec-sidebar .ver-block {
      border: 1px solid var(--rule);
      background: var(--paper-2);
      padding: 16px;
      margin-bottom: 24px;
    }

    .spec-sidebar .ver-block .ver-current {
      font-family: var(--mono);
      font-size: 13px;
      font-weight: 600;
      color: var(--ink);
      display: flex;
      align-items: center;
      gap: 8px;
      margin-bottom: 8px;
    }
    .spec-sidebar .ver-block .ver-badge {
      font-size: 9px;
      letter-spacing: .12em;
      text-transform: uppercase;
      background: var(--ok);
      color: var(--paper);
      padding: 2px 6px;
      border-radius: 2px;
    }

    .spec-sidebar .ver-block ul {
      margin: 0;
      padding: 0;
      list-style: none;
    }
    .spec-sidebar .ver-block ul li {
      font-family: var(--mono);
      font-size: 12px;
      color: var(--ink-3);
      padding: 3px 0;
      border-top: 1px solid var(--rule);
    }
    .spec-sidebar .ver-block ul li a {
      color: var(--ink-3);
      border: none;
    }
    .spec-sidebar .ver-block ul li a:hover { color: var(--accent) }

    .spec-sidebar nav.toc ul {
      margin: 0;
      padding: 0;
      list-style: none;
      display: flex;
      flex-direction: column;
      gap: 2px;
    }
    .spec-sidebar nav.toc ul li a {
      font-family: var(--mono);
      font-size: 11.5px;
      color: var(--ink-3);
      border: none;
      padding: 3px 0;
      display: block;
    }
    .spec-sidebar nav.toc ul li a:hover { color: var(--accent) }
    .spec-sidebar nav.toc ul li.toc-sub a {
      padding-left: 14px;
      font-size: 11px;
      color: var(--ink-4);
    }

    .spec-sidebar .schema-link {
      display: block;
      font-family: var(--mono);
      font-size: 11px;
      letter-spacing: .06em;
      background: var(--ink);
      color: var(--paper);
      text-align: center;
      padding: 9px 12px;
      border: none;
      margin-top: 20px;
      transition: background .15s;
    }
    .spec-sidebar .schema-link:hover { background: var(--accent) }

    .spec-sidebar .validate-hint {
      margin-top: 12px;
      font-family: var(--mono);
      font-size: 11px;
      color: var(--ink-4);
      background: var(--paper-2);
      border: 1px solid var(--rule);
      padding: 10px 12px;
      line-height: 1.5;
    }
    .spec-sidebar .validate-hint code {
      color: var(--accent-ink);
      background: none;
    }

    /* ---- Spec body ---- */
    .spec-body h2 {
      font-family: var(--sans);
      font-weight: 600;
      font-size: clamp(20px, 2.4vw, 28px);
      letter-spacing: -0.018em;
      line-height: 1.15;
      margin: 48px 0 12px;
      padding-top: 8px;
      border-top: 2px solid var(--rule);
      color: var(--ink);
    }
    .spec-body h2:first-child { margin-top: 0; border-top: none }

    .spec-body h3 {
      font-family: var(--mono);
      font-size: 14px;
      font-weight: 600;
      letter-spacing: .04em;
      margin: 28px 0 8px;
      color: var(--ink);
    }
    .spec-body h3 code {
      font-family: var(--mono);
      font-size: 14px;
      background: var(--paper-2);
      padding: 2px 7px;
      border-radius: 2px;
    }

    .spec-body p {
      font-size: 15px;
      color: var(--ink-2);
      line-height: 1.65;
      margin: 0 0 14px;
    }

    .spec-body ul, .spec-body ol {
      margin: 0 0 14px;
      padding-left: 22px;
    }
    .spec-body li {
      font-size: 14.5px;
      color: var(--ink-2);
      line-height: 1.6;
      margin-bottom: 4px;
    }
    .spec-body li code {
      font-family: var(--mono);
      font-size: 12.5px;
      background: var(--paper-2);
      padding: 1px 5px;
      border-radius: 2px;
    }

    .spec-body code {
      font-family: var(--mono);
      font-size: 13px;
      background: var(--paper-2);
      padding: 1px 5px;
      border-radius: 2px;
    }

    .spec-body pre {
      background: var(--ink);
      color: #E8E3D3;
      font-family: var(--mono);
      font-size: 13px;
      line-height: 1.6;
      padding: 18px 20px;
      margin: 8px 0 20px;
      overflow-x: auto;
      border-radius: 2px;
      border: 1px solid var(--rule);
    }
    .spec-body pre code {
      background: none;
      padding: 0;
      font-size: 13px;
      color: inherit;
    }

    .spec-body table {
      width: 100%;
      border-collapse: collapse;
      margin: 12px 0 20px;
      font-size: 13.5px;
    }
    .spec-body th {
      font-family: var(--mono);
      font-size: 11px;
      letter-spacing: .1em;
      text-transform: uppercase;
      color: var(--ink-3);
      text-align: left;
      padding: 8px 12px;
      border-bottom: 2px solid var(--rule);
      background: var(--paper-2);
    }
    .spec-body td {
      padding: 8px 12px;
      border-bottom: 1px solid var(--rule);
      color: var(--ink-2);
      vertical-align: top;
      line-height: 1.5;
    }
    .spec-body td code {
      font-family: var(--mono);
      font-size: 12px;
      background: var(--paper-2);
      padding: 1px 4px;
      border-radius: 2px;
    }
    .spec-body tr:last-child td { border-bottom: none }
  </style>
</head>

<body>

  <!-- ===== SITE NAV ===== -->
  <header class="site-nav" role="banner">
    <div class="wrap site-nav-inner">
      <a class="wordmark" href="/" aria-label="ROBOT.md home">
        ROBOT<span class="dot">.</span><span class="md">md</span>
      </a>
      <nav aria-label="Site navigation">
        <a href="/spec/" class="current" aria-current="page">Spec</a>
        <a href="/agents/">Agents</a>
        <a href="/mcp/">MCP</a>
        <a href="/registry/">Registry</a>
        <a href="/compliance/">Compliance</a>
        <a href="/managed-agents/">Managed Agents</a>
        <a href="/robots">Robots</a>
        <a href="https://github.com/RobotRegistryFoundation/robot-md" aria-label="GitHub repository">GitHub</a>
      </nav>
    </div>
  </header>

  <!-- ===== PAGE HEADER ===== -->
  <header class="page-header">
    <div class="wrap">
      <div class="page-eyebrow">
        <span>Specification · v1</span>
        <span class="rule-line" aria-hidden="true"></span>
        <span>Draft · 2026-04-17</span>
      </div>
      <h1 class="page-heading">
        ROBOT<span style="color:var(--accent)">.</span><span style="font-family:var(--serif);font-weight:400;font-style:italic;color:var(--ink-3)">md</span>
        <b>Format</b> Specification
      </h1>
      <p class="page-lede">
        One file — YAML frontmatter + markdown prose — so a planning LLM can
        safely operate a single robot. Validated against a JSON Schema.
        Conformant with RCAN 3.0+.
      </p>
    </div>
  </header>

  <!-- ===== TWO-COLUMN LAYOUT ===== -->
  <div class="wrap">
    <div class="spec-layout">

      <!-- ---- SIDEBAR ---- -->
      <aside class="spec-sidebar" aria-label="Spec navigation">

        <div class="sidebar-label">Spec versions</div>
        <div class="ver-block">
          <div class="ver-current">
            <span>v1</span>
            <span class="ver-badge">Current</span>
          </div>
          <ul>
            <li><a href="/spec/v0.2-design.md">v0.2-design (historical)</a></li>
            <li><a href="/spec/v0.1-mcp-design.md">v0.1-mcp-design (historical)</a></li>
          </ul>
        </div>

        <div class="sidebar-label">On this page</div>
        <nav class="toc" aria-label="Table of contents">
          <ul>
            <li><a href="#overview">1. Overview</a></li>
            <li><a href="#file-structure">2. File structure</a></li>
            <li><a href="#required-fields">3. Frontmatter — required fields</a></li>
            <li class="toc-sub"><a href="#rcan-version">3.1 rcan_version (string, required)</a></li>
            <li class="toc-sub"><a href="#metadata">3.2 metadata (map, required)</a></li>
            <li class="toc-sub"><a href="#physics">3.3 physics (map, required)</a></li>
            <li class="toc-sub"><a href="#drivers">3.4 drivers (array, required)</a></li>
            <li class="toc-sub"><a href="#safety">3.5 safety (map, required)</a></li>
            <li><a href="#conditional-fields">4. Frontmatter — conditionally required</a></li>
            <li class="toc-sub"><a href="#capabilities">4.1 capabilities (array of strings, required if physics.dof &gt; 0)</a></li>
            <li class="toc-sub"><a href="#network">4.2 network (map, required for network-addressable robots)</a></li>
            <li class="toc-sub"><a href="#brain">4.3 brain (map, required if the robot uses an LLM planner)</a></li>
            <li class="toc-sub"><a href="#compliance">4.4 compliance (map, required for EU-deployed robots)</a></li>
            <li><a href="#body-required">5. Body — required sections</a></li>
            <li><a href="#body-planner">6. Body — planner usage</a></li>
            <li><a href="#extensions">7. Extensions</a></li>
            <li><a href="#validation">8. Validation</a></li>
            <li><a href="#versioning">9. Versioning</a></li>
            <li><a href="#references">10. References</a></li>
          </ul>
        </nav>

        <a class="schema-link" href="/schema/v1/robot.schema.json">
          JSON Schema v1 →
        </a>

        <div class="validate-hint">
          Validate a local file:<br>
          <code>robot-md validate ROBOT.md</code>
        </div>

      </aside>

      <!-- ---- SPEC BODY ---- -->
      <article class="spec-body" aria-label="ROBOT.md Format Specification v1">
<p><strong>Status:</strong> Draft (v0.1)
<strong>Date:</strong> 2026-04-17
<strong>Authors:</strong> craigm26 et al.
<strong>License:</strong> Apache-2.0 (same as repo)</p>
<h2 id="overview">1. Overview</h2>
<p><code>ROBOT.md</code> is a single file that declares what a robot <strong>is</strong> and what it <strong>can do</strong>, in a form that both machines (JSON Schema + RCAN validators) and LLM planners (Claude Opus 4.7, Sonnet, etc.) can consume directly.</p>
<p>The file is markdown with a leading YAML frontmatter block:</p>
<ul>
<li>The <strong>frontmatter</strong> is the machine-readable declaration: identity, physics, drivers, safety, capabilities, compliance. Validated against <code>schema/v1/robot.schema.json</code>.</li>
<li>The <strong>body</strong> is human/LLM prose: identity narrative, capabilities explained, safety gates described, task-routing guidance. Read by the planner at session start.</li>
</ul>
<p>This parallels <code>CLAUDE.md</code>'s role for codebases: a single file, read at session start, that orients the planner.</p>
<h2 id="file-structure">2. File structure</h2>
<pre><code>---
&lt;YAML frontmatter&gt;
---

&lt;Markdown body&gt;
</code></pre>
<p>The frontmatter delimiters MUST be exactly three hyphens (<code>---</code>) on their own lines. The frontmatter MUST be valid YAML 1.1 (compatible with PyYAML <code>safe_load</code>). The body MAY be empty but MUST be present (at minimum a single <code># &lt;robot_name&gt;</code> H1).</p>
<h2 id="required-fields">3. Frontmatter — required fields</h2>
<h3 id="rcan-version">3.1 <code>rcan_version</code> (string, required)</h3>
<p>The RCAN protocol version this ROBOT.md conforms to. MUST be one of:</p>
<ul>
<li><code>"3.0"</code> — current (recommended)</li>
<li><code>"2.2"</code>, <code>"2.1"</code> — accepted via OpenCastor compatibility mode but operators should migrate</li>
<li>Future <code>3.x</code> versions (forward-compatible per <code>castor.compliance.is_accepted_version</code>)</li>
</ul>
<p>Rejected: <code>"1.x"</code> (EU AI Act compliance gap; ROBOT.md requires v2.1+).</p>
<h3 id="metadata">3.2 <code>metadata</code> (map, required)</h3>
<table>
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>robot_name</code></td>
<td>string</td>
<td>✅</td>
<td>Short display name (e.g., <code>bob</code>)</td>
</tr>
<tr>
<td><code>rrn</code></td>
<td>string</td>
<td>recommended</td>
<td>RRF-assigned RRN, or empty string until registered</td>
</tr>
<tr>
<td><code>rrn_uri</code></td>
<td>string</td>
<td>recommended</td>
<td>Canonical URI form of the RRN</td>
</tr>
<tr>
<td><code>ruri</code></td>
<td>string</td>
<td>recommended</td>
<td>Gateway URL (e.g., <code>rcan://robot.local:8001/bob</code>)</td>
</tr>
<tr>
<td><code>manufacturer</code></td>
<td>string</td>
<td>optional</td>
<td>Vendor or operator</td>
</tr>
<tr>
<td><code>model</code></td>
<td>string</td>
<td>optional</td>
<td>Model identifier</td>
</tr>
<tr>
<td><code>version</code></td>
<td>string</td>
<td>optional</td>
<td>Firmware/deployment version</td>
</tr>
<tr>
<td><code>license</code></td>
<td>string</td>
<td>optional</td>
<td>SPDX license identifier</td>
</tr>
</tbody>
</table>
<h3 id="physics">3.3 <code>physics</code> (map, required)</h3>
<table>
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>type</code></td>
<td>string</td>
<td>✅</td>
<td><code>arm</code> | <code>wheeled</code> | <code>tracked</code> | <code>legged</code> | <code>arm+camera</code> | <code>humanoid</code> | <code>other</code></td>
</tr>
<tr>
<td><code>dof</code></td>
<td>int</td>
<td>✅</td>
<td>Degrees of freedom (0 for purely sensory robots)</td>
</tr>
<tr>
<td><code>kinematics</code></td>
<td>array</td>
<td>optional</td>
<td>Per-joint entries (required if <code>type</code> is arm-based and <code>dof &gt; 0</code>)</td>
</tr>
</tbody>
</table>
<p>Each kinematics entry:</p>
<pre><code class="language-yaml">- id: shoulder_pan
  axis: x | y | z
  limits_deg: [min, max]   # or limits_mm for prismatic joints
  length_mm: 60            # link length downstream of this joint
</code></pre>
<h3 id="drivers">3.4 <code>drivers</code> (array, required)</h3>
<p>A list of hardware drivers the robot uses. At least one entry is required. Each driver declares <code>id</code> and <code>protocol</code>; additional fields are protocol-specific.</p>
<pre><code class="language-yaml">drivers:
  - id: arm_servos
    protocol: feetech       # feetech | dynamixel | pca9685 | gpio | ros2 | ...
    port: /dev/ttyUSB0
    baud_rate: 1000000
    model: STS3215
    count: 6
  - id: camera
    protocol: depthai
    model: OAK-D
</code></pre>
<p>Recognized protocols match <code>castor.drivers.&lt;name&gt;</code> in OpenCastor (full list: <code>spec/rationale.md</code>).</p>
<h3 id="safety">3.5 <code>safety</code> (map, required)</h3>
<table>
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>p66_enabled</code></td>
<td>bool</td>
<td>recommended</td>
<td>P66 safety manifest active</td>
</tr>
<tr>
<td><code>loa_enforcement</code></td>
<td>bool</td>
<td>recommended</td>
<td>RCAN Level-of-Assurance enforcement</td>
</tr>
<tr>
<td><code>max_joint_velocity_dps</code></td>
<td>number</td>
<td>if applicable</td>
<td>Max degrees/sec across all joints</td>
</tr>
<tr>
<td><code>max_linear_velocity_ms</code></td>
<td>number</td>
<td>if applicable</td>
<td>Max m/s (wheeled/tracked)</td>
</tr>
<tr>
<td><code>payload_kg</code></td>
<td>number</td>
<td>if applicable</td>
<td>Max payload</td>
</tr>
<tr>
<td><code>estop</code></td>
<td>map</td>
<td>✅</td>
<td>E-stop configuration — see below</td>
</tr>
<tr>
<td><code>hitl_gates</code></td>
<td>array</td>
<td>recommended</td>
<td>Human-in-the-loop gate scopes</td>
</tr>
</tbody>
</table>
<p>The <code>estop</code> map:</p>
<pre><code class="language-yaml">estop:
  hardware: false           # dedicated physical button?
  software: true            # software interrupt supported
  response_ms: 100          # time from trigger to motion-halt
</code></pre>
<p>At minimum, <code>software: true</code> with <code>response_ms</code> is required.</p>
<h2 id="conditional-fields">4. Frontmatter — conditionally required</h2>
<h3 id="capabilities">4.1 <code>capabilities</code> (array of strings, required if <code>physics.dof &gt; 0</code>)</h3>
<p>Named skills the robot exposes. Each name SHOULD map to a skill registered in the deploying runtime's <code>SkillRegistry</code>. Standard namespaces:</p>
<ul>
<li><code>nav.*</code> — navigation (move, stop, go_to)</li>
<li><code>arm.*</code> — manipulation (pick, place, reach, grip)</li>
<li><code>vision.*</code> — perception (describe, detect, track)</li>
<li><code>status.*</code> — introspection (report, health)</li>
<li><code>system.*</code> — lifecycle (shutdown, reboot, calibrate)</li>
</ul>
<p>Vendor-specific skills MAY use their own namespace (e.g., <code>bosdyn.crouch</code>).</p>
<h3 id="network">4.2 <code>network</code> (map, required for network-addressable robots)</h3>
<table>
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>rrf_endpoint</code></td>
<td>URL</td>
<td><code>https://robotregistryfoundation.org</code> or self-hosted RRF</td>
</tr>
<tr>
<td><code>port</code></td>
<td>int</td>
<td>Gateway port</td>
</tr>
<tr>
<td><code>signing_alg</code></td>
<td>string</td>
<td><code>pqc-hybrid-v1</code> (required at RCAN 3.0 L2+); <code>ml-dsa-65</code>; or <code>ed25519</code> (L1 only, sunset in 3.x)</td>
</tr>
<tr>
<td><code>transports</code></td>
<td>array</td>
<td><code>[http, mqtt, ws]</code> etc.</td>
</tr>
</tbody>
</table>
<h3 id="brain">4.3 <code>brain</code> (map, required if the robot uses an LLM planner)</h3>
<table>
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>planning</code></td>
<td>map</td>
<td>LLM provider + model + confidence gate</td>
</tr>
<tr>
<td><code>reactive</code></td>
<td>map</td>
<td>Optional low-latency layer (e.g., VLA model)</td>
</tr>
<tr>
<td><code>task_routing</code></td>
<td>map</td>
<td>RCAN task-category routing overrides</td>
</tr>
</tbody>
</table>
<p>Example:</p>
<pre><code class="language-yaml">brain:
  planning:
    provider: anthropic
    model: claude-opus-4-7
    confidence_gate: 0.60
  reactive:
    provider: local
    model: openvla-7b
  task_routing:
    sensor_poll: fast_only
    safety: planner_always
    navigation: periodic
    reasoning: planner
</code></pre>
<h3 id="compliance">4.4 <code>compliance</code> (map, required for EU-deployed robots)</h3>
<table>
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>fria_ref</code></td>
<td>URL or null</td>
<td>Signed Fundamental Rights Impact Assessment document URI (RCAN §27). <code>null</code> = placeholder pending <code>castor fria generate</code>.</td>
</tr>
<tr>
<td><code>iso_42001</code></td>
<td>map</td>
<td><code>{ self_assessed: bool, level: 1-5 }</code></td>
</tr>
<tr>
<td><code>eu_ai_act</code></td>
<td>map</td>
<td><code>{ audit_retention_days: int }</code> (≥ 365 for Annex III systems)</td>
</tr>
</tbody>
</table>
<h2 id="body-required">5. Body — required sections</h2>
<p>The markdown body MUST contain:</p>
<ol>
<li><code># &lt;metadata.robot_name&gt;</code> — H1 matching <code>metadata.robot_name</code> (case-insensitive)</li>
<li><code>## Identity</code> — 1-2 paragraphs describing the robot</li>
<li><code>## What &lt;robot_name&gt; Can Do</code> — prose capability narrative</li>
<li><code>## Safety Gates</code> — which actions gated, how E-stop works</li>
</ol>
<p>Optional sections:</p>
<ul>
<li><code>## Task Routing</code> — expands on <code>brain.task_routing</code></li>
<li><code>## Extension Points</code> — how to add skills/drivers</li>
<li><code>## References</code> — links to spec, runtime, RRF entry</li>
</ul>
<h2 id="body-planner">6. Body — planner usage</h2>
<p>A Claude session with this ROBOT.md in context at startup is expected to:</p>
<ol>
<li>Cite the robot by name in its first response</li>
<li>Respect <code>safety.hitl_gates</code> without prompting</li>
<li>Route tasks according to <code>brain.task_routing</code></li>
<li>Refuse capabilities NOT listed in <code>capabilities[]</code></li>
<li>Honor <code>compliance</code> flags (e.g., extra caution for <code>eu_ai_act.audit_retention_days &gt; 0</code>)</li>
</ol>
<h2 id="extensions">7. Extensions</h2>
<p>Vendor-specific extensions MUST use the <code>extensions:</code> block with namespaced keys:</p>
<pre><code class="language-yaml">extensions:
  x-opencastor:
    harness_ref: /etc/opencastor/harness.yaml
  x-boston-dynamics:
    spot_config_version: &quot;3.2&quot;
</code></pre>
<p>Unknown <code>extensions.x-*</code> keys MUST NOT cause validation failure.</p>
<h2 id="validation">8. Validation</h2>
<p>A ROBOT.md is <strong>valid</strong> if and only if:</p>
<ol>
<li>Frontmatter parses as YAML without error</li>
<li>Frontmatter validates against <code>schema/v1/robot.schema.json</code></li>
<li><code>rcan_version</code> passes <code>castor.compliance.is_accepted_version</code> (or equivalent — see rationale)</li>
<li>Required body sections are present</li>
<li><code>capabilities</code> values match <code>nav.*</code>, <code>arm.*</code>, <code>vision.*</code>, <code>status.*</code>, <code>system.*</code>, or vendor <code>&lt;prefix&gt;.*</code> patterns</li>
</ol>
<p>The <code>robot-md validate</code> CLI returns exit codes:</p>
<ul>
<li><code>0</code> — valid</li>
<li><code>1</code> — file not found or parse error</li>
<li><code>2</code> — schema violation</li>
<li><code>3</code> — RCAN conformance violation</li>
<li><code>4</code> — missing required body section</li>
</ul>
<h2 id="versioning">9. Versioning</h2>
<p>The spec version is <code>v1</code>. Future versions:</p>
<ul>
<li><code>v1.x</code> — backward-compatible additions (new optional fields, new optional sections)</li>
<li><code>v2</code> — breaking changes (field renames, required→optional changes that affect validation)</li>
</ul>
<p>Breaking changes live at a new schema URL (<code>schema/v2/robot.schema.json</code>) and the spec file is renamed accordingly. Both served indefinitely.</p>
<h2 id="references">10. References</h2>
<ul>
<li>RCAN protocol: <a href="https://rcan.dev/spec/">https://rcan.dev/spec/</a></li>
<li>Robot Registry Foundation: <a href="https://robotregistryfoundation.org/">https://robotregistryfoundation.org/</a></li>
<li>OpenCastor runtime: <a href="https://github.com/craigm26/OpenCastor">https://github.com/craigm26/OpenCastor</a></li>
<li>JSON Schema spec: <a href="https://json-schema.org/draft/2020-12/">https://json-schema.org/draft/2020-12/</a></li>
</ul>
      </article>

    </div>
  </div>

  <!-- ===== FOOTER ===== -->
  <footer class="wrap foot">
    <div>ROBOT.md · © 2026 Craig Merry · <a href="https://www.craigmerry.com">craigmerry.com</a></div>
    <div>
      <a href="/">Home</a> ·
      <a href="/spec/">Spec</a> ·
      <a href="/registry/">Registry</a> ·
      <a href="/compliance/">Compliance</a> ·
      <a href="/robots">Robots</a> ·
      <a href="/status">Status</a> ·
      <a href="/report.html">Report issue</a> ·
      <a href="https://github.com/RobotRegistryFoundation/robot-md">GitHub</a>
    </div>
  </footer>

</body>

</html>
