<?xml version="1.0" encoding="UTF-8"?>
  <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
  <!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.36 (Ruby 3.2.3) -->


<!DOCTYPE rfc  [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">

]>


<rfc ipr="trust200902" docName="draft-sunyi-hacp-protocol-00" category="info" tocInclude="true" sortRefs="true" symRefs="true">
  <front>
    <title abbrev="HACP">HACP: A Capability-Contract Protocol for AI Agents and Edge Hardware</title>

    <author initials="Y." surname="Sun" fullname="Yi Sun">
      <organization>Independent Contributor</organization>
      <address>
        <email>syqust@gmail.com</email>
        <uri>https://github.com/hearthworks</uri>
      </address>
    </author>

    <date year="2026" month="May" day="01"/>

    <area>Internet</area>
    <workgroup>Independent Submission</workgroup>
    <keyword>AI agent</keyword> <keyword>LLM</keyword> <keyword>edge computing</keyword> <keyword>hardware abstraction</keyword> <keyword>IoT</keyword> <keyword>audit</keyword>

    <abstract>


<?line 52?>

<t>HACP (Hardware Agent Capability Protocol) is a JSON-RPC 2.0 transport-
agnostic protocol that lets a Large Language Model (LLM) agent — or any
program acting on its behalf — discover, plan, execute, observe, and
audit operations on physical edge hardware (GPIO, I2C, UART, sensors,
system telemetry, files) through a single, stable, security-checked
surface.</t>

<t>HACP sits below higher-level agent protocols such as the Model Context
Protocol and above the operating system. It is designed to make
heterogeneous edge devices interoperable with diverse AI agent
implementations without requiring either side to know the details of
the other.</t>

<t>This document specifies the HACP wire format, core methods, lifecycle,
error model, security requirements, and audit semantics. Streaming,
attestation, and MCP-bridge profiles are sketched as optional or
preview.</t>



    </abstract>



  </front>

  <middle>


<?line 72?>

<section anchor="introduction"><name>Introduction</name>

<t>LLM-based agents are increasingly asked to operate on physical
hardware: read sensors, set GPIO lines, query system telemetry, manage
files. Today, each agent framework reinvents this surface, often by
shelling out to operating-system primitives. The result is fragile,
unauditable, non-portable, and hard to secure.</t>

<t>HACP defines a small, stable JSON-RPC 2.0 protocol that an agent or an
agent-side framework speaks to a host-side daemon. The daemon owns the
hardware, enforces security policy, and emits an audit trail. The
agent owns the intent, the planning, and the natural-language surface.</t>

<t>Goals:</t>

<t><list style="numbers" type="1">
  <t>Capability contract, not a driver API. HACP describes what an
agent may ask for (read this GPIO, list I2C buses, write this file
under a safe path). It does not describe how the daemon talks to
silicon.</t>
  <t>Safe by construction. Every operation passes through an
allowlist, a path guard, a per-tool risk level, and an audit log.
Agents cannot escape into a shell.</t>
  <t>Plannable, not just callable. A request expresses an intent and
an ordered list of steps; the server executes them as a single
task with one task identifier, one status, and one audit trail.</t>
  <t>Transport-neutral. The wire encoding is JSON-RPC 2.0 framed by
line-delimited JSON; the carrier may be a Unix domain socket, a
TCP socket over mutual TLS, an SSH stream, or a WebSocket.</t>
  <t>Portable across edge boards. A capability name (e.g.
"gpio.set", "hw.i2c.list", "sys.thermal") means the same thing on
different physical platforms.</t>
  <t>Forward-compatible. New methods, new tools, and new fields can
be added without breaking existing clients.</t>
</list></t>

<t>Non-goals: HACP does not prescribe an agent SDK shape, a hardware
description schema, a deployment manifest format, or an internal bus
between daemons. Those are the subject of separate companion
specifications outside this document's scope.</t>

<section anchor="conventions-and-definitions"><name>Conventions and Definitions</name>

<t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>

<?line -18?>

<t>The following terms are used:</t>

<dl>
  <dt>Agent:</dt>
  <dd>
    <t>The component that initiates HACP requests.  Typically an
LLM-based program or a framework on its behalf.</t>
  </dd>
  <dt>Server:</dt>
  <dd>
    <t>The host-side component that owns hardware access and serves HACP.
Also called the "daemon" in this document.</t>
  </dd>
  <dt>Tool:</dt>
  <dd>
    <t>A single named capability registered at server startup. A tool has
a name, a risk level, a JSON Schema for its arguments, and a
validate/execute pair on the server side.</t>
  </dd>
  <dt>Task:</dt>
  <dd>
    <t>An intent plus an ordered list of steps. Each step invokes a single
tool. A task has exactly one identifier and one terminal status.</t>
  </dd>
  <dt>Session:</dt>
  <dd>
    <t>An authenticated context between an agent and a server, identified
by a server-generated session identifier.</t>
  </dd>
</dl>

<t>A conformant server is one that implements the methods marked
"Required" in <xref target="core-methods"/> and obeys the framing, error, and
lifecycle rules in <xref target="wire-format"/> and <xref target="lifecycle"/>.</t>

<t>A conformant client is one that issues only well-formed requests per
<xref target="wire-format"/>, honors the lifecycle in <xref target="lifecycle"/>, and treats
unknown optional fields as defined in <xref target="forward-compat"/>.</t>

</section>
</section>
<section anchor="wire-format"><name>Wire format</name>

<section anchor="json-rpc-20"><name>JSON-RPC 2.0</name>

<t>HACP <bcp14>MUST</bcp14> use JSON-RPC 2.0 <xref target="JSONRPC"/> over UTF-8 encoded JSON
<xref target="RFC8259"/>. Every request is a JSON object with at least:</t>

<figure><sourcecode type="json"><![CDATA[
{ "jsonrpc": "2.0", "id": 7, "method": "tool.list",
  "params": { "session_id": "..." } }
]]></sourcecode></figure>

<t>Every response is either a result:</t>

<figure><sourcecode type="json"><![CDATA[
{ "jsonrpc": "2.0", "id": 7, "result": { ... } }
]]></sourcecode></figure>

<t>or an error (see <xref target="error-model"/>):</t>

<figure><sourcecode type="json"><![CDATA[
{ "jsonrpc": "2.0", "id": 7,
  "error": { "code": -32602, "message": "Invalid params" } }
]]></sourcecode></figure>

</section>
<section anchor="framing"><name>Framing</name>

<t>The default framing is line-delimited JSON: each request and response
is a single JSON document followed by exactly one LF (0x0A). Clients
<bcp14>MUST NOT</bcp14> split a single document across multiple LF boundaries.
Servers <bcp14>MUST</bcp14> accept arbitrary whitespace between documents.</t>

<t>Alternative framings (Content-Length headers, WebSocket frames) <bcp14>MAY</bcp14>
be negotiated by transport binding documents (see
<xref target="transport-bindings"/>).</t>

</section>
<section anchor="identifiers"><name>Identifiers</name>

<t><list style="symbols">
  <t><spanx style="verb">id</spanx> — JSON-RPC request identifier; <bcp14>MUST</bcp14> be unique per connection
while outstanding. Strings, integers, or <spanx style="verb">null</spanx> are allowed; <spanx style="verb">null</spanx>
indicates a notification (no response expected).</t>
  <t><spanx style="verb">session_id</spanx> — opaque server-generated string returned by
<spanx style="verb">session.open</spanx>. <bcp14>MUST</bcp14> be at most 64 bytes drawn from
<spanx style="verb">[0-9a-zA-Z_-]</spanx>.</t>
  <t><spanx style="verb">task_id</spanx> — opaque server-generated string returned by
<spanx style="verb">task.submit</spanx>. Same constraints as <spanx style="verb">session_id</spanx>.</t>
</list></t>

</section>
<section anchor="encoding"><name>Encoding</name>

<t>UTF-8 only. Numbers fit in IEEE 754 double precision unless
explicitly declared otherwise in a method's schema. Binary payloads
(for example <spanx style="verb">file.read</spanx> contents) <bcp14>MUST</bcp14> be encoded using base64 as
defined in <xref target="RFC4648"/>.</t>

</section>
<section anchor="forward-compat"><name>Forward compatibility</name>

<t>Servers <bcp14>MUST</bcp14> ignore unknown fields in <spanx style="verb">params</spanx>. Clients <bcp14>MUST</bcp14> ignore
unknown fields in <spanx style="verb">result</spanx>. New error codes <bcp14>MUST</bcp14> be additive (no
re-purposing of existing numbers). Tool authors <bcp14>SHOULD</bcp14> version
breaking-change tools by appending <spanx style="verb">.v2</spanx> (for example <spanx style="verb">gpio.set.v2</spanx>)
rather than mutating the original.</t>

</section>
</section>
<section anchor="core-methods"><name>Core methods</name>

<t>The following methods make up the HACP Core and <bcp14>MUST</bcp14> be implemented
by every conformant server.</t>

<texttable>
      <ttcol align='left'>Method</ttcol>
      <ttcol align='left'>Required</ttcol>
      <ttcol align='left'>Purpose</ttcol>
      <c><spanx style="verb">session.open</spanx></c>
      <c>Yes</c>
      <c>Establish an authenticated session</c>
      <c><spanx style="verb">session.close</spanx></c>
      <c>Yes</c>
      <c>Tear down a session</c>
      <c><spanx style="verb">tool.list</spanx></c>
      <c>Yes</c>
      <c>Enumerate capabilities available</c>
      <c><spanx style="verb">task.submit</spanx></c>
      <c>Yes</c>
      <c>Submit an intent and ordered steps</c>
      <c><spanx style="verb">task.get</spanx></c>
      <c>Yes</c>
      <c>Poll a task's status and per-step results</c>
      <c><spanx style="verb">task.cancel</spanx></c>
      <c>Yes</c>
      <c>Request cooperative cancellation</c>
</texttable>

<t>Optional method namespaces:</t>

<texttable>
      <ttcol align='left'>Namespace</ttcol>
      <ttcol align='left'>Optional</ttcol>
      <ttcol align='left'>Purpose</ttcol>
      <c><spanx style="verb">task.events</spanx></c>
      <c><bcp14>SHOULD</bcp14></c>
      <c>Server-sent task progress (see <xref target="streaming"/>)</c>
      <c><spanx style="verb">attest.*</spanx></c>
      <c><bcp14>MAY</bcp14></c>
      <c>Device or agent attestation (see <xref target="future"/>)</c>
      <c><spanx style="verb">mcp.*</spanx></c>
      <c><bcp14>MAY</bcp14></c>
      <c>MCP-bridge introspection (see <xref target="transports"/>)</c>
</texttable>

<section anchor="sessionopen"><name>session.open</name>

<t>Establish a session. The server <bcp14>MUST</bcp14> allocate a fresh <spanx style="verb">session_id</spanx>
and <bcp14>MAY</bcp14> advertise capability flags.</t>

<t>Request <spanx style="verb">params</spanx>:</t>

<texttable>
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Required</ttcol>
      <ttcol align='left'>Notes</ttcol>
      <c><spanx style="verb">client_name</spanx></c>
      <c>string</c>
      <c><bcp14>SHOULD</bcp14></c>
      <c>Free-form e.g. <spanx style="verb">"ai-shell"</spanx></c>
      <c><spanx style="verb">client_version</spanx></c>
      <c>string</c>
      <c><bcp14>SHOULD</bcp14></c>
      <c>Semantic version</c>
      <c><spanx style="verb">protocol_version</spanx></c>
      <c>string</c>
      <c><bcp14>MAY</bcp14></c>
      <c>Highest HACP version supported</c>
</texttable>

<t>Result:</t>

<figure><sourcecode type="json"><![CDATA[
{
  "session_id": "01J9...XYZ",
  "capabilities": ["CAP_GPIO_RW", "CAP_FILE_READ"],
  "protocol_version": "0.1.0"
}
]]></sourcecode></figure>

<t>The server <bcp14>MAY</bcp14> reject <spanx style="verb">session.open</spanx> with <spanx style="verb">RPC_PERMISSION_DENIED</spanx> if
authentication fails. Authentication is transport-bound (see
<xref target="transport-bindings"/>).</t>

</section>
<section anchor="sessionclose"><name>session.close</name>

<t>Request <spanx style="verb">params</spanx>: <spanx style="verb">{ "session_id": "..." }</spanx></t>

<t>Result: <spanx style="verb">{ "ok": true }</spanx></t>

<t>Closing a session <bcp14>MUST</bcp14> cancel any tasks still owned by it.</t>

</section>
<section anchor="toollist"><name>tool.list</name>

<t>Request <spanx style="verb">params</spanx>: <spanx style="verb">{ "session_id": "..." }</spanx></t>

<t>Result:</t>

<figure><sourcecode type="json"><![CDATA[
{
  "tools": [
    {
      "name": "gpio.set",
      "version": 1,
      "risk_level": 2,
      "timeout_ms": 1000,
      "supports_rollback": true,
      "description": "Set a GPIO line to 0 or 1.",
      "params_schema": { "type": "object" }
    }
  ]
}
]]></sourcecode></figure>

<t><spanx style="verb">risk_level</spanx> is one of:</t>

<texttable>
      <ttcol align='left'>Level</ttcol>
      <ttcol align='left'>Name</ttcol>
      <ttcol align='left'>Meaning</ttcol>
      <c>0</c>
      <c><spanx style="verb">safe</spanx></c>
      <c>Pure read; no side effects</c>
      <c>1</c>
      <c><spanx style="verb">low</spanx></c>
      <c>Local mutation, easily reversible</c>
      <c>2</c>
      <c><spanx style="verb">medium</spanx></c>
      <c>Physical actuation or cross-process effect</c>
      <c>3</c>
      <c><spanx style="verb">high</spanx></c>
      <c>Irreversible, destructive, or safety-critical</c>
</texttable>

<t>Clients <bcp14>MUST</bcp14> treat unknown additional tool fields as opaque and
preserve them when forwarding.</t>

</section>
<section anchor="tasksubmit"><name>task.submit</name>

<t>A task is an intent plus an ordered list of steps. Each step is a
single tool invocation. Steps run sequentially within a task. Two
tasks in the same session <bcp14>MAY</bcp14> run concurrently if the server supports
it.</t>

<t>Request <spanx style="verb">params</spanx>:</t>

<figure><sourcecode type="json"><![CDATA[
{
  "session_id": "...",
  "task": {
    "intent": "Read sensor and toggle status LED",
    "steps": [
      { "tool": "i2c.read",
        "args": { "bus": 1, "addr": "0x48", "reg": "0x00", "len": 2 } },
      { "tool": "gpio.set",
        "args": { "line": 17, "value": 1 } }
    ],
    "constraints": {
      "max_duration_ms": 5000,
      "abort_on_step_failure": true,
      "max_risk_level": 2
    }
  }
}
]]></sourcecode></figure>

<t>Result:</t>

<figure><sourcecode type="json"><![CDATA[
{ "task_id": "01J9...ABC", "status": "QUEUED" }
]]></sourcecode></figure>

<t>The server <bcp14>MUST</bcp14> validate every step's tool name and argument schema
before returning. If any step fails validation, the entire submission
is rejected with <spanx style="verb">RPC_INVALID_PARAMS</spanx> and no step is executed.</t>

<t>The server <bcp14>MUST</bcp14> reject any step whose tool's <spanx style="verb">risk_level</spanx> exceeds the
session's permitted maximum (default 2; configurable via
<spanx style="verb">constraints.max_risk_level</spanx> only if the session is permitted to
relax it).</t>

</section>
<section anchor="taskget"><name>task.get</name>

<t>Request <spanx style="verb">params</spanx>: <spanx style="verb">{ "session_id": "...", "task_id": "..." }</spanx></t>

<t>Result:</t>

<figure><sourcecode type="json"><![CDATA[
{
  "task_id": "01J9...ABC",
  "status": "SUCCESS",
  "intent": "...",
  "steps": [
    { "tool": "i2c.read", "status": "SUCCESS",
      "result": { "data": "ABcd" }, "latency_ms": 4 },
    { "tool": "gpio.set", "status": "SUCCESS",
      "result": { "line": 17, "value": 1 }, "latency_ms": 1 }
  ]
}
]]></sourcecode></figure>

<t>Task <spanx style="verb">status</spanx> is one of: <spanx style="verb">QUEUED</spanx>, <spanx style="verb">RUNNING</spanx>, <spanx style="verb">SUCCESS</spanx>, <spanx style="verb">FAILED</spanx>,
<spanx style="verb">CANCELLED</spanx>. Step <spanx style="verb">status</spanx> uses the same enum (without <spanx style="verb">QUEUED</spanx>).</t>

<t>A failed step <bcp14>MUST</bcp14> include an <spanx style="verb">"error"</spanx> string. The whole task fails
fast unless <spanx style="verb">abort_on_step_failure: false</spanx> was set.</t>

</section>
<section anchor="taskcancel"><name>task.cancel</name>

<t>Request <spanx style="verb">params</spanx>: <spanx style="verb">{ "session_id": "...", "task_id": "..." }</spanx></t>

<t>Result: <spanx style="verb">{ "task_id": "...", "status": "CANCELLING" }</spanx></t>

<t>Cancellation is cooperative. Steps in progress are signaled; the
task moves to <spanx style="verb">CANCELLED</spanx> only after the current step yields. Servers
<bcp14>MUST NOT</bcp14> force-kill a step that has begun a hardware transaction
(for example, an in-flight I2C write) just because cancel arrived.</t>

</section>
</section>
<section anchor="capability-namespaces-informative"><name>Capability namespaces (informative)</name>

<t>Tool names are dot-separated. The first segment is a namespace; the
rest is implementation-defined. The following namespaces are
reserved by this specification:</t>

<texttable>
      <ttcol align='left'>Namespace</ttcol>
      <ttcol align='left'>Purpose</ttcol>
      <ttcol align='left'>Examples</ttcol>
      <c><spanx style="verb">hw.*</spanx></c>
      <c>Read-only hardware discovery</c>
      <c><spanx style="verb">hw.gpio.list</spanx>, <spanx style="verb">hw.i2c.list</spanx></c>
      <c><spanx style="verb">gpio.*</spanx></c>
      <c>GPIO read/write</c>
      <c><spanx style="verb">gpio.get</spanx>, <spanx style="verb">gpio.set</spanx></c>
      <c><spanx style="verb">i2c.*</spanx></c>
      <c>I2C transactions</c>
      <c><spanx style="verb">i2c.read</spanx>, <spanx style="verb">i2c.write</spanx></c>
      <c><spanx style="verb">uart.*</spanx></c>
      <c>Serial / UART</c>
      <c><spanx style="verb">uart.write</spanx>, <spanx style="verb">uart.read</spanx></c>
      <c><spanx style="verb">file.*</spanx></c>
      <c>Path-guarded filesystem</c>
      <c><spanx style="verb">file.read</spanx>, <spanx style="verb">file.write</spanx></c>
      <c><spanx style="verb">sys.*</spanx></c>
      <c>Linux system telemetry</c>
      <c><spanx style="verb">sys.cpuinfo</spanx>, <spanx style="verb">sys.thermal</spanx></c>
      <c><spanx style="verb">proc.*</spanx></c>
      <c>Process control</c>
      <c><spanx style="verb">proc.exec</spanx>, <spanx style="verb">proc.signal</spanx></c>
</texttable>

<t>Vendors <bcp14>SHOULD</bcp14> prefix custom namespaces with their reverse-DNS, for
example <spanx style="verb">com.acme.modbus.read</spanx>, to avoid collisions.</t>

</section>
<section anchor="lifecycle"><name>Lifecycle</name>

<t>A session begins with <spanx style="verb">session.open</spanx> and ends with <spanx style="verb">session.close</spanx> or
an idle timeout. While a session is active, an agent <bcp14>MAY</bcp14> submit any
number of tasks. Each task progresses through:</t>

<figure><artwork><![CDATA[
QUEUED -> RUNNING -> { SUCCESS | FAILED | CANCELLED }
]]></artwork></figure>

<t>Idle sessions <bcp14>SHOULD</bcp14> be reaped after a server-defined time-to-live
(default 300 seconds); reaping <bcp14>MUST</bcp14> run <spanx style="verb">session.close</spanx> semantics,
including cancelling any in-flight tasks.</t>

<t>A server <bcp14>MUST</bcp14> reject any post-close request that uses the closed
session identifier with <spanx style="verb">RPC_SESSION_INVALID</spanx>.</t>

</section>
<section anchor="error-model"><name>Error model</name>

<t>HACP reuses the JSON-RPC 2.0 standard codes:</t>

<texttable>
      <ttcol align='left'>Code</ttcol>
      <ttcol align='left'>Name</ttcol>
      <ttcol align='left'>Meaning</ttcol>
      <c><spanx style="verb">-32700</spanx></c>
      <c>Parse error</c>
      <c>Malformed JSON</c>
      <c><spanx style="verb">-32600</spanx></c>
      <c>Invalid Request</c>
      <c>Not a valid request object</c>
      <c><spanx style="verb">-32601</spanx></c>
      <c>Method not found</c>
      <c>Unknown method</c>
      <c><spanx style="verb">-32602</spanx></c>
      <c>Invalid params</c>
      <c>Missing/wrong params</c>
      <c><spanx style="verb">-32603</spanx></c>
      <c>Internal error</c>
      <c>Server bug</c>
</texttable>

<t>Plus HACP-specific codes (range -32099 to -32000):</t>

<texttable>
      <ttcol align='left'>Code</ttcol>
      <ttcol align='left'>Name</ttcol>
      <ttcol align='left'>Meaning</ttcol>
      <c><spanx style="verb">-32000</spanx></c>
      <c><spanx style="verb">RPC_SESSION_INVALID</spanx></c>
      <c>session_id unknown or expired</c>
      <c><spanx style="verb">-32001</spanx></c>
      <c><spanx style="verb">RPC_TASK_NOT_FOUND</spanx></c>
      <c>task_id unknown for session</c>
      <c><spanx style="verb">-32002</spanx></c>
      <c><spanx style="verb">RPC_TOOL_NOT_FOUND</spanx></c>
      <c>Step references unregistered tool</c>
      <c><spanx style="verb">-32003</spanx></c>
      <c><spanx style="verb">RPC_PERMISSION_DENIED</spanx></c>
      <c>Allowlist or risk guard rejected</c>
      <c><spanx style="verb">-32004</spanx></c>
      <c><spanx style="verb">RPC_RESOURCE_BUSY</spanx></c>
      <c>Hardware contention</c>
</texttable>

<t>Implementations <bcp14>MAY</bcp14> add codes in -32099 to -32005. They <bcp14>MUST NOT</bcp14>
re-use the codes above with different meaning.</t>

<t>The optional <spanx style="verb">error.data</spanx> field <bcp14>MAY</bcp14> carry a structured detail object:</t>

<figure><sourcecode type="json"><![CDATA[
{ "code": -32003, "message": "Permission denied",
  "data": { "tool": "gpio.set",
            "reason": "max_risk_level=1 < tool=2" } }
]]></sourcecode></figure>

</section>
<section anchor="audit"><name>Audit semantics</name>

<t>Every accepted <spanx style="verb">task.submit</spanx>, every step start, every step finish,
and every <spanx style="verb">session.open</spanx> and <spanx style="verb">session.close</spanx> <bcp14>MUST</bcp14> generate an audit
event.</t>

<t>The recommended event shape is illustrative; a full audit log format
is the subject of a separate companion document:</t>

<figure><sourcecode type="json"><![CDATA[
{
  "ts":         "2026-04-19T22:48:01.234Z",
  "event":      "task.step.finish",
  "session_id": "...",
  "task_id":    "...",
  "step_index": 0,
  "tool":       "gpio.set",
  "status":     "SUCCESS",
  "latency_ms": 1,
  "args_hash":  "sha256:..."
}
]]></sourcecode></figure>

<t>Audit logs <bcp14>SHOULD</bcp14> be append-only and rotation-friendly (newline-
delimited JSON). Implementations <bcp14>MAY</bcp14> chain consecutive records
cryptographically (for example, by including the SHA-256 hash of the
previous record in the next record) to provide tamper evidence.</t>

</section>
<section anchor="streaming"><name>Streaming extension (optional)</name>

<t>The polling pattern (<spanx style="verb">task.submit</spanx> followed by repeated <spanx style="verb">task.get</spanx>)
is sufficient but verbose. A server <bcp14>MAY</bcp14> advertise the
<spanx style="verb">CAP_STREAMING_TASK_EVENTS</spanx> capability in <spanx style="verb">session.open</spanx>. If
present, clients <bcp14>MAY</bcp14> call:</t>

<figure><sourcecode type="json"><![CDATA[
{ "method": "task.events.subscribe",
  "params": { "session_id": "...", "task_id": "..." } }
]]></sourcecode></figure>

<t>The server then sends one or more notifications (JSON-RPC objects
with no <spanx style="verb">id</spanx>):</t>

<figure><sourcecode type="json"><![CDATA[
{ "jsonrpc": "2.0", "method": "task.event",
  "params": { "task_id": "...", "step_index": 0,
              "phase": "start",
              "ts": "2026-04-19T22:48:01.234Z" } }
]]></sourcecode></figure>

<t>Phases: <spanx style="verb">start</spanx>, <spanx style="verb">progress</spanx>, <spanx style="verb">finish</spanx>, <spanx style="verb">task_finish</spanx>. The
subscription ends implicitly when the task reaches a terminal status.</t>

</section>
<section anchor="versioning"><name>Versioning</name>

<t>The protocol uses Semantic Versioning <xref target="SEMVER"/> as <spanx style="verb">MAJOR.MINOR.PATCH</spanx>:</t>

<t><list style="symbols">
  <t>PATCH: clarifications and editorial fixes only.</t>
  <t>MINOR: additive — new methods, fields, or error codes. Older
clients still work.</t>
  <t>MAJOR: breaking. Servers <bcp14>MAY</bcp14> support multiple majors side by side
via <spanx style="verb">protocol_version</spanx> in <spanx style="verb">session.open</spanx>.</t>
</list></t>

<t>Servers <bcp14>MUST</bcp14> advertise their highest supported version in the
<spanx style="verb">session.open</spanx> result.</t>

</section>
<section anchor="transport-bindings"><name>Transport bindings</name>

<section anchor="transports"><name>Unix Domain Socket (default)</name>

<t><list style="symbols">
  <t>Default path: implementation-defined; the reference implementation
uses <spanx style="verb">/run/hearth/hearth.sock</spanx> when started as a system service or
<spanx style="verb">/tmp/hearth/hearth.sock</spanx> for unprivileged use.</t>
  <t>Permissions: <spanx style="verb">0660</spanx> owned by the server's user, with a dedicated
group. Adding a user to that group is the authentication act.</t>
  <t>Framing: line-delimited JSON.</t>
</list></t>

</section>
<section anchor="mcp-bridge-informative"><name>MCP bridge (informative)</name>

<t>A small adapter <bcp14>MAY</bcp14> present a HACP server as an MCP server <xref target="MCP"/>.
Mapping:</t>

<texttable>
      <ttcol align='left'>MCP</ttcol>
      <ttcol align='left'>HACP</ttcol>
      <c><spanx style="verb">tools/list</spanx></c>
      <c><spanx style="verb">session.open</spanx> then <spanx style="verb">tool.list</spanx></c>
      <c><spanx style="verb">tools/call</spanx></c>
      <c><spanx style="verb">task.submit</spanx> (single step)</c>
      <c>MCP error</c>
      <c>HACP error per <xref target="error-model"/></c>
</texttable>

</section>
<section anchor="tcp-plus-mutual-tls-informative"><name>TCP plus mutual TLS (informative)</name>

<t>For multi-host deployments, HACP <bcp14>MAY</bcp14> be served over TCP wrapped in
mutual TLS. Authentication is by client certificate; the
certificate's subject is mapped to a session policy. The same
line-delimited framing applies.</t>

</section>
</section>
<section anchor="future"><name>Future Considerations</name>

<t>Future revisions of this specification may explore:</t>

<t><list style="symbols">
  <t>Remote operation across network boundaries with stronger
authentication and confidentiality requirements.</t>
  <t>Mutual authentication and authorization between agents and
capability providers based on hardware identities.</t>
  <t>Hardware-backed attestation of capability providers (for example,
via TPM 2.0 quotes binding the running daemon binary, the kernel,
and the device identity to a client-supplied nonce).</t>
  <t>Catalog versioning and capability negotiation evolution as the
agent ecosystem matures.</t>
</list></t>

<t>The detailed mechanisms are out of scope for this document.</t>

</section>
<section anchor="security-considerations"><name>Security Considerations</name>

<t>HACP exposes physical hardware to programs that act on behalf of
LLMs.  This is inherently security-sensitive.</t>

<t>A conformant server <bcp14>MUST</bcp14>:</t>

<t><list style="numbers" type="1">
  <t>Allowlist tools at startup. The set of registered tools is fixed
per process; agents cannot install new tools at runtime over HACP.</t>
  <t>Path-guard every filesystem operation. <spanx style="verb">file.*</spanx> and any tool that
accepts a path <bcp14>MUST</bcp14> consult a configured read/write allowlist;
reject with <spanx style="verb">RPC_PERMISSION_DENIED</spanx> on miss.</t>
  <t>Enforce per-tool risk caps. A session <bcp14>MUST NOT</bcp14> execute a tool
whose <spanx style="verb">risk_level</spanx> exceeds the session's configured maximum.</t>
  <t>Audit every accepted task (<xref target="audit"/>).</t>
  <t>Bound resource use. Server <bcp14>MUST</bcp14> reject <spanx style="verb">task.submit</spanx> when
internal queues are full.</t>
</list></t>

<t>A conformant server <bcp14>SHOULD</bcp14>:</t>

<t><list style="symbols">
  <t>Run as an unprivileged user, joining only the groups required for
the buses it exposes.</t>
  <t>Apply rate limits per (session_id, tool) pair.</t>
  <t>Apply per-tool timeouts.</t>
  <t>Drop privileges and apply syscall filtering before serving.</t>
</list></t>

<t>Servers <bcp14>MUST NOT</bcp14> expose a <spanx style="verb">proc.exec</spanx>-style escape hatch in the
default tool set. Operators that need shell access <bcp14>MUST</bcp14> opt in
explicitly and <bcp14>MUST</bcp14> flag such tools as <spanx style="verb">risk_level: 3</spanx>.</t>

<t>The default Unix Domain Socket transport relies on filesystem
permissions for authentication. Operators deploying HACP over
network transports <bcp14>MUST</bcp14> apply mutual TLS or an equivalent
authentication mechanism, as the JSON-RPC envelope itself carries no
confidentiality or integrity protection.</t>

<t>The audit log is the primary mechanism for detecting and
investigating abuse. Operators <bcp14>SHOULD</bcp14> store audit logs on
append-only media or use cryptographic chaining (<xref target="audit"/>) to
detect tampering after the fact.</t>

<t>A malicious or compromised agent that gains a HACP session is
limited by the configured tool allowlist, risk cap, and path guard.
HACP does not protect against an attacker who can reconfigure the
server itself (for example, by editing its configuration file as
root); operators are expected to apply standard host hardening to
the server's runtime environment.</t>

</section>
<section anchor="privacy-considerations"><name>Privacy Considerations</name>

<t>The audit log records the full sequence of operations performed on
behalf of an agent, including a hash of arguments. Operators
<bcp14>SHOULD</bcp14> treat audit logs as sensitive: they may incidentally
correlate hardware events with user activity (for example, motion
sensor reads taken at specific times). Standard log retention,
access control, and minimization practices apply.</t>

<t>HACP itself does not transmit personally identifiable information as
part of the protocol envelope. Implementations that expose tools
returning personal data (for example, a microphone capture tool)
<bcp14>MUST</bcp14> classify those tools at an appropriate <spanx style="verb">risk_level</spanx> and <bcp14>SHOULD</bcp14>
require explicit operator opt-in.</t>

</section>
<section anchor="iana-considerations"><name>IANA Considerations</name>

<t>This document has no IANA actions.</t>

<t>A future revision may register a media type for line-delimited HACP
framing and a default port number for the optional TCP transport. No
registrations are requested at this time.</t>

</section>
<section anchor="implementation-status"><name>Implementation Status</name>

<t>A reference implementation, the HEARTH project <xref target="HEARTH"/>, includes
a server (<spanx style="verb">hearthd</spanx>, written in C) and an agent client (<spanx style="verb">ai-shell</spanx>).
The reference implementation covers all six core methods, the audit
log format, the Unix Domain Socket transport, and the MCP bridge.
Streaming task events and attestation are partial.</t>

<t>This section is intended to be removed by the RFC Editor before
publication.</t>

</section>


  </middle>

  <back>


<references title='References' anchor="sec-combined-references">

    <references title='Normative References' anchor="sec-normative-references">



<reference anchor="RFC2119">
  <front>
    <title>Key words for use in RFCs to Indicate Requirement Levels</title>
    <author fullname="S. Bradner" initials="S." surname="Bradner"/>
    <date month="March" year="1997"/>
    <abstract>
      <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
    </abstract>
  </front>
  <seriesInfo name="BCP" value="14"/>
  <seriesInfo name="RFC" value="2119"/>
  <seriesInfo name="DOI" value="10.17487/RFC2119"/>
</reference>

<reference anchor="RFC8174">
  <front>
    <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
    <author fullname="B. Leiba" initials="B." surname="Leiba"/>
    <date month="May" year="2017"/>
    <abstract>
      <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
    </abstract>
  </front>
  <seriesInfo name="BCP" value="14"/>
  <seriesInfo name="RFC" value="8174"/>
  <seriesInfo name="DOI" value="10.17487/RFC8174"/>
</reference>

<reference anchor="RFC8259">
  <front>
    <title>The JavaScript Object Notation (JSON) Data Interchange Format</title>
    <author fullname="T. Bray" initials="T." role="editor" surname="Bray"/>
    <date month="December" year="2017"/>
    <abstract>
      <t>JavaScript Object Notation (JSON) is a lightweight, text-based, language-independent data interchange format. It was derived from the ECMAScript Programming Language Standard. JSON defines a small set of formatting rules for the portable representation of structured data.</t>
      <t>This document removes inconsistencies with other specifications of JSON, repairs specification errors, and offers experience-based interoperability guidance.</t>
    </abstract>
  </front>
  <seriesInfo name="STD" value="90"/>
  <seriesInfo name="RFC" value="8259"/>
  <seriesInfo name="DOI" value="10.17487/RFC8259"/>
</reference>


<reference anchor="JSONRPC" target="https://www.jsonrpc.org/specification">
  <front>
    <title>JSON-RPC 2.0 Specification</title>
    <author >
      <organization></organization>
    </author>
    <date year="2013"/>
  </front>
</reference>


    </references>

    <references title='Informative References' anchor="sec-informative-references">



<reference anchor="RFC4648">
  <front>
    <title>The Base16, Base32, and Base64 Data Encodings</title>
    <author fullname="S. Josefsson" initials="S." surname="Josefsson"/>
    <date month="October" year="2006"/>
    <abstract>
      <t>This document describes the commonly used base 64, base 32, and base 16 encoding schemes. It also discusses the use of line-feeds in encoded data, use of padding in encoded data, use of non-alphabet characters in encoded data, use of different encoding alphabets, and canonical encodings. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="4648"/>
  <seriesInfo name="DOI" value="10.17487/RFC4648"/>
</reference>


<reference anchor="MCP" target="https://modelcontextprotocol.io">
  <front>
    <title>Model Context Protocol</title>
    <author >
      <organization></organization>
    </author>
    <date year="2024"/>
  </front>
</reference>
<reference anchor="SEMVER" target="https://semver.org">
  <front>
    <title>Semantic Versioning 2.0.0</title>
    <author >
      <organization></organization>
    </author>
    <date year="2013"/>
  </front>
</reference>
<reference anchor="HEARTH" target="https://github.com/hearthworks/hearthd">
  <front>
    <title>HEARTH: Open Capability Layer Between AI Agents and Edge Hardware</title>
    <author >
      <organization></organization>
    </author>
    <date year="2026"/>
  </front>
</reference>


    </references>

</references>


<?line 662?>

<section anchor="acknowledgments"><name>Acknowledgments</name>

<t>The author thanks the early reviewers and contributors of the HEARTH
project for their feedback on the protocol surface, and the broader
LLM agent community whose function-calling conventions informed the
design of the <spanx style="verb">task.submit</spanx> shape.</t>

</section>


  </back>

<!-- ##markdown-source:
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
njoU6dmlfnB9w1zyicPofwGX90pu9FoAAA==

-->

</rfc>

