| Internet-Draft | HCTP | August 2026 |
| Ruvalcaba | Expires 12 February 2027 | [Page] |
The Hash-Chain Context Transfer Protocol (HCTP) is a payload format and synchronization protocol for incrementally transferring an ordered, append-only sequence of conversational context between two endpoints over a bandwidth-constrained channel. Acknowledged history is represented by a single fixed-size rolling hash commitment (the "static root"); only not-yet-acknowledged context blocks (the "dynamic window") are transmitted. As a result, the per-message wire overhead attributable to history is constant and independent of the total number of previously acknowledged turns. HCTP is transport-agnostic and carries no confidentiality or peer authentication of its own; it is intended to run over a secure transport. This document specifies the HCTP data model, wire format, rolling-root computation, and synchronization state machine.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 12 February 2027.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
Conversational and agentic systems increasingly need to share an evolving record of interaction ("context") between components: between a client and a service, between cooperating agents, or between a live process and a resumable checkpoint. The naive approach retransmits the entire conversation on every exchange, so the wire cost grows without bound as the conversation lengthens. This is wasteful on any channel and prohibitive on a constrained one.¶
HCTP addresses this by partitioning the context into two parts:¶
Each context block commits to the raw text of one turn via a content hash and additionally carries a short semantic summary, so that an endpoint may operate on the summary as context without ever receiving the raw text, while retaining the ability to verify the block against the raw text if it later obtains it (Section 8).¶
HCTP provides ordering and tamper-evidence through a hash chain. It does not provide confidentiality, peer authentication, or non-repudiation, and its integrity guarantees are meaningful only when it is carried over a transport that authenticates the peer and protects the payload (Section 11). HCTP is deliberately independent of any particular transport: it defines the payload octets, and any datagram or stream transport MAY carry them.¶
This document specifies only the transport-agnostic core: the block format, the rolling-root commitment, the SYNC/ACK exchange, and the rules for advancing the chain. Mechanisms for peer authentication, key establishment, message confidentiality, and the specific method by which a summary is produced are out of scope and are expected to be supplied by the surrounding system.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
All multi-octet integers in this document are unsigned and encoded in network byte order (big-endian). Octet strings written as hexadecimal are shown for illustration only; on the wire they are raw octets.¶
A context block is a logical record with the following fields:¶
For hashing and for on-the-wire serialization, a context block MUST be encoded as canonical JSON: a JSON object containing exactly the members "content_hash", "role", "seq", and "summary", with member names sorted in ascending lexicographic (Unicode code point) order, no insignificant whitespace, and no member separators other than a single "," and ":". The canonical encoding of a block B is denoted canonical(B).¶
Each endpoint maintains, per session:¶
Acknowledged blocks are never retransmitted; they are represented solely by the static root, whose size is constant and independent of the number of blocks it commits to.¶
The static root is a SHA-256 hash chain over acknowledged blocks. Let "||" denote octet-string concatenation and SHA256(x) denote the 32-octet SHA-256 digest of x.¶
The genesis root is defined as:¶
root_0 = SHA256(GENESIS_SEED)¶
where GENESIS_SEED is the ASCII octet string "hctp-genesis-v1" (15 octets, no trailing NUL).¶
Given a current root R and a block B, folding B advances the root:¶
fold(R, B) = SHA256( R || SHA256(canonical(B)) )¶
The static root after acknowledging blocks B_1, ..., B_n (in order) is therefore:¶
root_n = fold( fold( ... fold(root_0, B_1) ..., B_{n-1}), B_n )
¶
Because each root embeds every prior acknowledged root, any modification, reordering, insertion, or deletion of acknowledged history produces a different static root, and the mismatch is detected at the next SYNC (Section 6.3).¶
HCTP defines two packet types, SYNC and ACK. Every packet begins with a 1-octet version and a 1-octet packet type. The version specified by this document is 0x01.¶
0 1 2 3 4 5 6 +--------+--------+--------------------------+ |version | ptype | seq | | 0x01 | 0x53 | (uint32, 4 octets) | +--------+--------+--------------------------+ | static_root | | (32 octets) | +--------------------------------------------+ | dynamic_len | | (uint32, 4 octets) | +--------------------------------------------+ | dynamic_data (dynamic_len octets) | | ... | +--------------------------------------------+ | combined_hash | | (32 octets) | +--------------------------------------------+¶
The fixed overhead of a SYNC packet is 74 octets (1 + 1 + 4 + 32 + 4 + 32), independent of the acknowledged-history depth. The total size is 74 octets plus dynamic_len.¶
0 1 2 3 4 5 6 +--------+--------+--------------------------+ |version | ptype | seq | | 0x01 | 0x41 | (uint32, 4 octets) | +--------+--------+--------------------------+ | new_root | | (32 octets) | +--------------------------------------------+¶
An ACK packet is exactly 38 octets.¶
The SYNC/ACK exchange is asymmetric, and sender state MUST NOT be conflated with receiver state. For a given directional chain (Section 7) an endpoint maintains:¶
Receiver state:¶
Sender state:¶
To transmit pending context, the sender:¶
The sender MUST NOT advance its static_root at send time; the root is advanced only upon receiving a valid ACK (Section 6.4).¶
On receiving a SYNC packet P, the receiver applies the following checks in order:¶
On acceptance the receiver records pre_fold_root = local_root, folds each accepted block into local_root in order (Section 4), sets last_seen_seq = P.seq and has_seen = true, constructs an ACK with new_root = local_root, records (pre_fold_root, ACK) in ack_cache, and sends the ACK.¶
On receiving an ACK packet A, the sender:¶
If the retransmit timer expires before an ACK is received, the sender MUST retransmit the SYNC bearing the unchanged seq and the unchanged pre-fold static_root, up to a bounded retransmit count. A single lost ACK MUST NOT cause session re-establishment or re-keying: the idempotent-retransmit rule (Section 6.3) ensures a retransmitted SYNC re-elicits the same ACK without double-folding. Only after the bounded retransmit count is exhausted without acknowledgment does the sender signal transport failure.¶
A static-root mismatch (either endpoint) means the endpoints no longer share acknowledged history and cannot be reconciled within HCTP. Implementations MUST treat this as a fatal session error and re-establish a new session from genesis. HCTP does not define reconciliation of divergent chains; such divergence indicates loss, reordering that escaped detection at a lower layer, or tampering.¶
The seq field is a 32-bit unsigned integer. An endpoint MUST NOT allow seq to wrap; upon approaching 2^32 blocks in a session, both endpoints MUST re-key by starting a new session with a fresh genesis root. Sessions exceeding 2^32 blocks are not supported.¶
When both endpoints originate context concurrently, a single shared static root can diverge, because each endpoint would fold blocks in an order the other cannot reproduce. HCTP resolves this with per-direction chains: an endpoint pair maintains two independent rolling-root chains, one advanced solely by folding blocks originated by the first endpoint and acknowledged by the second, and the other advanced solely by folding blocks originated by the second endpoint and acknowledged by the first. A SYNC is associated with a direction, determined either from the role indicator or from the channel on which it is received. Because opposite-direction SYNCs fold into disjoint chains, they cannot diverge.¶
Alternatively, endpoints MAY serialize all folds onto a single shared chain using a single-writer turn-token: an endpoint transmits a SYNC only while holding the turn-token, and the token is conveyed to the peer upon transmission of an ACK. This yields a single agreed fold order at the cost of strictly alternating turns. An implementation MUST use exactly one of these two strategies for a given session and MUST NOT mix them.¶
An endpoint that lacks the raw turn text MAY operate using the block's summary as its working context. If the endpoint later obtains the raw text, it can verify the block by recomputing content_hash from the raw text and comparing it to the block's content_hash field.¶
Implementations MAY additionally make the summary itself reproducible and thus verifiable, rather than merely asserted, by computing it with a fixed, pre-agreed deterministic summarization function -- for example a summarizer identified by name and version, applied with a fixed prompt or template and a deterministic decoding configuration -- such that any party holding the raw text and the agreed configuration recomputes the identical summary. This document does not mandate any particular summarization function; when determinism across heterogeneous implementations cannot be guaranteed, an endpoint MAY instead verify a summary under a pre-agreed equivalence predicate (for example a canonicalization or a distance threshold). Absent such a mechanism, the summary MUST be treated as unverified assertion.¶
HCTP is transport-agnostic; it defines only the octets of SYNC and ACK packets. A SYNC or ACK is a self-delimiting unit (its length is fully determined by its fixed fields plus dynamic_len) and MAY be carried as a single datagram, a length-framed record on a stream, a WebSocket [RFC6455] binary message, or the body of an HTTP request or response. HCTP performs no fragmentation of its own: if a dynamic payload exceeds the underlying channel's usable size, the sending application MUST split the pending blocks across multiple SYNC packets, each bearing the same static_root and an increasing seq, and reassemble on the receiver.¶
Because HCTP supplies no confidentiality or peer authentication, it MUST be carried over a transport that provides them where those properties are required (Section 11).¶
HCTP is not a secure channel by itself. The static root, combined_hash, and content_hash are computed with an unkeyed hash function. They provide tamper-evidence against accidental corruption and against a party that cannot forge packets, but they provide no cryptographic authentication: an active attacker who can inject packets can recompute a consistent combined_hash and a consistent chain for any payload of the attacker's choosing. Authenticity, integrity against active attackers, and confidentiality MUST be provided by the underlying transport (for example TLS 1.3 [RFC8446] or QUIC [RFC9000]) or by an authenticated-encryption layer that wraps the HCTP packet. Absent such a layer, HCTP's integrity guarantees are meaningless.¶
No non-repudiation. Either endpoint can construct a valid-looking chain from genesis; the chain proves internal consistency, not origin. Binding context to a long-term identity requires signatures and is out of scope.¶
Replay. Within a session, the seq field and the strict ordering check reject replays of superseded SYNCs, and the static-root alignment check rejects out-of-context injection. Cross-session replay is prevented by starting each session from a fresh genesis and never reusing session state; endpoints SHOULD bind the session to transport-layer freshness (for example a fresh TLS session) to prevent whole-session replay.¶
Decompression resource exhaustion. dynamic_data is attacker-influenced compressed input. A receiver MUST bound the maximum accepted decompressed size and the maximum number of blocks per SYNC, and MUST abort decompression that exceeds those bounds, to avoid a decompression "bomb" denial of service. dynamic_len itself MUST be bounded before allocation.¶
Confidentiality of summaries. A block's summary may reveal the semantic content of a turn even though the raw text is not sent. Where the summary is sensitive, the transport MUST encrypt the packet. The content_hash likewise permits confirmation of a guessed plaintext; where raw texts are low-entropy or guessable, this MUST be considered.¶
Hash agility. This version fixes SHA-256 and a fixed genesis seed. Collision resistance of the chain rests entirely on SHA-256. A future version of the protocol (indicated by the version octet) may specify an alternative hash; endpoints MUST reject versions they do not implement.¶
IANA is requested to create a new registry, "HCTP Packet Types", with a 1-octet unsigned integer identifier space, under a to-be-assigned HCTP-protocol registry group. The registration policy is "Specification Required" [RFC8126]. The initial contents are:¶
| Value | Name | Reference |
|---|---|---|
| 0x41 | ACK | This document |
| 0x53 | SYNC | This document |
| 0x00, 0x02-0x40, 0x42-0x52, 0x54-0xFF | Unassigned |
IANA is requested to create a registry "HCTP Versions" with a 1-octet identifier space, registration policy "Specification Required", initially containing value 0x01 ("HCTP/1", this document).¶
IANA is requested to register the "application/hctp" media type for HCTP packets carried over media-type-aware transports, per the procedures of [RFC6838]. Type name: application; Subtype name: hctp; Required parameters: none; Optional parameters: none; Encoding considerations: binary; Security considerations: see Section 11 of this document.¶
The rolling-root delta-transfer design and the verifiable-summary block derive from an earlier reference implementation of the protocol.¶