| Internet-Draft | Agent Handoff Context | October 2026 |
| Srivastava | Expires 29 April 2027 | [Page] |
When one agent hands a task to another, the receiving agent often needs to know who handed it over, on whose behalf, through which earlier agents, and which prior context the work depends on. It also needs to know that the handoff is fresh and meant for it, and the sender needs a clear answer back. This document describes a small, transport-neutral handoff context: a signed offer, a signed status reply, and the chain of earlier offers that led to the current one, defined in CDDL for JSON and CBOR, with a lifecycle that maps to Agent2Agent task states. Each offer names the one before it by hash, so that a dropped or reordered intermediate hop can be detected when the chain is carried. Prior context is named by digest only; any log or transparency service behind it is opaque. Appendices show how a SCITT receipt or a Learnlog signed head can be referenced. The document is offered as input to the agentproto working group's use cases and dialog-context work.¶
This note is to be removed before publishing as an RFC.¶
Discussion of this document takes place on the Agent Communication Protocols (agentproto) Working Group mailing list (agentproto@ietf.org), which is archived at https://mailarchive.ietf.org/arch/browse/agentproto/.¶
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 29 April 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.¶
Agent systems hand work across agents, vendors, and trust boundaries. A planner agent asks a coding agent to write a patch; the coding agent asks a test agent to run it. Each hop raises the same questions for the agent that receives work:¶
The sender, in turn, needs a clear answer: accepted, rejected and why, completed, or failed.¶
The individual draft "Agentic AI Use Cases and Requirements" [I-D.agentic-ai-usecases-requirements] states several of these needs as requirements. For example, its B3-6 asks for a verifiable provenance record of a request and its response across a delegation chain, such that removal of a hop is detectable; B3-7 asks that a receiver can detect and reject a delegation chain that contains a cycle; and B3-9 asks that dialog context propagate across each hop. The same document places accountability and auditing out of its own scope.¶
This document describes one way to meet part of those per-hop needs with a small element that existing agent protocols can carry, without defining an audit log. It links the offers that hand work along a chain. It does not cover responses or attribute transformations to hops. Section 7 lists each requirement it touches and says what is and is not met.¶
An authorization token answers one question: may this agent act, and within what limits. A handoff raises questions that a token does not carry. Which agent handed this work over, to which agent, in which dialog, and when? Which earlier handoffs led here? Which prior context does the work depend on? Did the receiver take the work, and how did it end? OAuth 2.0 Token Exchange [RFC8693] can record a history of actors inside a token, but the token is issued by an authorization server, not by the agent handing over, and it says nothing about the dialog or about the answer back. The element defined here is signed by the agents themselves, at each hop, and is small enough to travel beside whatever token the host protocol carries.¶
This document defines:¶
The following are out of scope:¶
The charter says the dialog context "consists of the identifiers and lifecycle state needed to correlate and maintain an agentic dialog", and that dialog context "may need to be propagated and remain coherent across multiple intermediaries". It says the mechanisms it calls for need to ensure, among other things, "delegated authorization across AI agent chains". It also says dialog identifiers "may be used in auditing".¶
The handoff context is intended to sit inside that boundary. It is consumed at handoff time, to decide whether to accept work and to correlate hops. It is not a record kept for later review. Whether the working group sees the chain and reference members as dialog context or as audit data is the working group's call; see Section 11.¶
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.¶
Member names are short text strings so that one definition serves JSON and CBOR. Except in Digest, which is closed, a receiver MUST ignore members it does not understand and a forwarder MUST NOT remove them, since they are covered by the signature.¶
HandoffOffer = {
v: 1,
type: "offer",
hop: HopId,
dialog: text,
? task: text,
iss: AgentId,
aud: AgentId,
iat: Time,
exp: Time,
? obo: Principal,
? grant: Digest,
? prev: Digest,
? refs: [+ ContextRef],
* text => any
}
¶
HandoffStatus = {
v: 1,
type: "status",
hop: HopId,
offer: Digest,
iss: AgentId,
aud: AgentId,
iat: Time,
state: State,
? reason: Reason,
? detail: text,
? refs: [+ ContextRef],
* text => any
}
State = "accepted" / "rejected" / "completed" /
"failed" / "canceled"
Reason = "bad-signature" / "untrusted-key" / "wrong-audience" /
"stale" / "replay" / "equivocation" / "broken-chain" /
"cycle" / "too-deep" / "unverifiable-ref" /
"ref-mismatch" / "policy" / text
¶
HopId = text .regexp "[A-Za-z0-9_-]{22,64}"
AgentId = text
Time = uint
Principal = {
sub: text,
? iss: text,
* text => any
}
Digest = {
alg: "sha-256" / text,
val: B64u
}
B64u = text .regexp "[A-Za-z0-9_-]+"
ContextRef = {
kind: "digest" / "salted-digest" / "scitt-receipt" /
"learnlog-head" / text,
dig: Digest,
? loc: text,
? proof: any,
* text => any
}
; In JSON, a chain element is SignedHandoffJson.
; In CBOR, a chain element is SignedHandoffCbor.
SignedHandoff = SignedHandoffJson / SignedHandoffCbor
SignedHandoffJson = JwsCompact / B64u
SignedHandoffCbor = JwsCompact / bstr
JwsCompact = text .regexp
"[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+"
¶
Time is seconds since 1970-01-01T00:00:00Z, ignoring leap seconds, as an integer.¶
Digest is a closed map: it has exactly the two members shown. Its alg names the hash function, and its val is the full hash output in base64url without padding. This document defines one value, "sha-256", meaning SHA-256, which implementations MUST support. Other values are left to future specifications, which MUST NOT define a hash whose output is shorter than 256 bits. A receiver that does not implement the alg of a Digest MUST treat a check that depends on it as failed for prev and grant, and as unverifiable for refs.¶
What the host protocol carries is a Handoff: the signed offer together with its chain.¶
Handoff = {
offer: SignedHandoff,
? chain: [+ SignedHandoff],
* text => any
}
¶
The chain is outside the signature on purpose. Each offer already names its predecessor by digest, and each predecessor names its own, so the prev links fix the chain's membership and order without a second signature over them. Were the chain inside each signed offer, every offer would carry the chains of all its predecessors, and the size would double at each hop. Kept outside, the chain grows by one offer per hop. A chain that does not connect to the offer fails Section 5.3; a chain that was removed is simply absent, which the receiver's policy treats as it would any missing chain.¶
A status is carried on its own, as a SignedHandoff.¶
A ContextRef names prior context by digest. It says "the sender asserts that this work depends on the object with this digest". It does not say what the object means.¶
A receiver that checks a reference reports one of four outcomes: verified (digest matched and any proof checked against a key it trusts), mismatch, unverifiable (it could not obtain or check the object), or not checked. A receiver MUST NOT report a reference as verified unless it performed the check. These outcomes follow the distinction drawn in [I-D.he-agentproto-verifier-evidence] and [I-D.konda-agentproto-evaluation-state] between a negative result and a result that could not be established.¶
In this example, an assistant agent has handed a task to a planner, and the planner now hands part of it to a coder. The planner's offer payload, before signing, is:¶
{
"v": 1,
"type": "offer",
"hop": "q3Zl0v8bVfQmJm2c4bq1Ww",
"dialog": "ctx-7c1e",
"task": "task-42",
"iss": "spiffe://a.example/agent/planner",
"aud": "spiffe://b.example/agent/coder",
"iat": 1793000000,
"exp": 1793000120,
"obo": {
"sub": "u-8f2a",
"iss": "https://idp.u.example"
},
"grant": {
"alg": "sha-256",
"val": "SKLjsfET5xtZoO5hzIiZFigz2JoYZLmW8Cg8GuYh4o4"
},
"prev": {
"alg": "sha-256",
"val": "M-OyKnHLAGKpiZKw7sNqAsNKmtfRQ7DUFhtKAL3Slmg"
},
"refs": [
{
"kind": "digest",
"dig": {
"alg": "sha-256",
"val": "V_WPM8F9ztg6WxBxj1ZIGnzRbM1Xyp5GVdpEYmwbvuQ"
},
"loc": "https://a.example/ctx/9"
}
]
}
¶
The Handoff that the planner sends to the coder holds that offer, signed with ES256, and a chain of one element: the assistant's signed offer to the planner. Long lines are folded using the single backslash strategy of [RFC8792].¶
NOTE: '\' line wrapping per RFC 8792
{
"offer": "eyJhbGciOiJFUzI1NiIsImtpZCI6ImxXR0ZBQzhDcGM5Zm5lcVhaM2I0\
YUNqdGJiN3ZCb1Q4UmJ2SnhYNjEta1EiLCJ0eXAiOiJhZ2VudC1oYW5kb2ZmK2p3dC\
J9.eyJ2IjoxLCJ0eXBlIjoib2ZmZXIiLCJob3AiOiJxM1psMHY4YlZmUW1KbTJjNGJ\
xMVd3IiwiZGlhbG9nIjoiY3R4LTdjMWUiLCJ0YXNrIjoidGFzay00MiIsImlzcyI6I\
nNwaWZmZTovL2EuZXhhbXBsZS9hZ2VudC9wbGFubmVyIiwiYXVkIjoic3BpZmZlOi8\
vYi5leGFtcGxlL2FnZW50L2NvZGVyIiwiaWF0IjoxNzkzMDAwMDAwLCJleHAiOjE3O\
TMwMDAxMjAsIm9ibyI6eyJzdWIiOiJ1LThmMmEiLCJpc3MiOiJodHRwczovL2lkcC5\
1LmV4YW1wbGUifSwiZ3JhbnQiOnsiYWxnIjoic2hhLTI1NiIsInZhbCI6IlNLTGpzZ\
kVUNXh0Wm9PNWh6SWlaRmlnejJKb1laTG1XOENnOEd1WWg0bzQifSwicHJldiI6eyJ\
hbGciOiJzaGEtMjU2IiwidmFsIjoiTS1PeUtuSExBR0twaVpLdzdzTnFBc05LbXRmU\
lE3RFVGaHRLQUwzU2xtZyJ9LCJyZWZzIjpbeyJraW5kIjoiZGlnZXN0IiwiZGlnIjp\
7ImFsZyI6InNoYS0yNTYiLCJ2YWwiOiJWX1dQTThGOXp0ZzZXeEJ4ajFaSUduelJiT\
TFYeXA1R1ZkcEVZbXdidnVRIn0sImxvYyI6Imh0dHBzOi8vYS5leGFtcGxlL2N0eC8\
5In1dfQ.aHq9TQ3_SI_kM1xDVzxVluQRhWctEMDt0ATd0Tmf8KjWj6IscdZnav9rhZ\
zBNNTrvrD1chtHaSsv0y6uRAuVSA",
"chain": [
"eyJhbGciOiJFUzI1NiIsImtpZCI6IktLT2JfVVJsZFBNRThYWFhiV3ZYODhFWHB\
JNlRPaEtINHJ3dEhwcXRJYjgiLCJ0eXAiOiJhZ2VudC1oYW5kb2ZmK2p3dCJ9.eyJ2\
IjoxLCJ0eXBlIjoib2ZmZXIiLCJob3AiOiJWYjNrUXg5WnRSMm1OOHBMNHdZYzFBIi\
wiZGlhbG9nIjoiY3R4LTdjMWUiLCJpc3MiOiJzcGlmZmU6Ly91LmV4YW1wbGUvYWdl\
bnQvYXNzaXN0YW50IiwiYXVkIjoic3BpZmZlOi8vYS5leGFtcGxlL2FnZW50L3BsYW\
5uZXIiLCJpYXQiOjE3OTI5OTk5OTAsImV4cCI6MTc5MzAwMDExMCwib2JvIjp7InN1\
YiI6InUtOGYyYSIsImlzcyI6Imh0dHBzOi8vaWRwLnUuZXhhbXBsZSJ9fQ.3BHyncw\
224yirlOxWsl3gELq1MWlwBKVvkrVVV12qycHGyaByn019Beegv-lms_OFqseMOgf5\
Xs_kJHaynMcwg"
]
}
¶
The chain element's protected header decodes to the following (line breaks added for display):¶
{"alg":"ES256","kid":"KKOb_URldPME8XXXbWvX88EXpI6TOhKH4rwtHpqtIb8",
"typ":"agent-handoff+jwt"}
¶
Its payload decodes to the following (line breaks added for display):¶
{"v":1,"type":"offer","hop":"Vb3kQx9ZtR2mN8pL4wYc1A",
"dialog":"ctx-7c1e","iss":"spiffe://u.example/agent/assistant",
"aud":"spiffe://a.example/agent/planner","iat":1792999990,
"exp":1793000110,
"obo":{"sub":"u-8f2a","iss":"https://idp.u.example"}}
¶
The two signatures verify with the following public keys, whose JWK Thumbprints [RFC7638] are the kid values in the two headers. Both key pairs are for this example only.¶
{"crv":"P-256","kty":"EC",
"x":"G6ZXm5RqUggIPXdM3WR_kg2acGXtkaYFhoM51p-2_iA",
"y":"8Gv0K14KLtbFeBUSjRTW0CYXr-t_WTYrtbHOFasEL6s"}
¶
{"crv":"P-256","kty":"EC",
"x":"WnRSpcn3Krie0WFNKoxLb14dgx8uBHCiO0bf7S36cx8",
"y":"9t5Dm2PQpoSAckALLAGKhvYc4HccNnkPhGEBz3v2HUg"}
¶
The first key is the assistant's and signed the chain element. The second is the planner's and signed the offer. The other values are computed as follows.¶
example access token issued to spiffe://b.example/agent/coder¶
{"repo":"https://git.a.example/app","commit":"9fceb02","issue":9}
¶
The coder accepts the work and replies with this status payload, which it signs with its own key. Its offer member is the handoff digest of the planner's signed offer: SHA-256 over its 942 ASCII octets, unfolded.¶
{
"v": 1,
"type": "status",
"hop": "q3Zl0v8bVfQmJm2c4bq1Ww",
"offer": {
"alg": "sha-256",
"val": "kJIcudVNmFFwbYKTXNO3mqC3e9dQSWVXDNbamGeoP18"
},
"iss": "spiffe://b.example/agent/coder",
"aud": "spiffe://a.example/agent/planner",
"iat": 1793000003,
"state": "accepted"
}
¶
Every offer and status MUST be signed by its iss. An unsigned element MUST be treated as absent.¶
The payload is the JSON form of the element. The signed handoff is the JWS Compact Serialization [RFC7515].¶
The payload is the CBOR form of the element. The signed handoff is a COSE_Sign1 message [RFC9052] with tag 18.¶
In a JSON chain, a COSE signed handoff is carried as base64url text, which never contains a period and so cannot be confused with a JWS. In a CBOR chain, a JWS is carried as text and a COSE message as a byte string.¶
The handoff digest is SHA-256 over the signed handoff's octets exactly as sent: the ASCII octets of the JWS Compact Serialization, or the encoded tagged COSE_Sign1 message. Hashing what was signed, as sent, avoids any need for canonical JSON. A party that forwards a signed handoff in a chain MUST forward these octets unchanged.¶
This document does not define how a receiver learns that a key speaks for an AgentId. A receiver MUST use a key only if its own trust configuration binds that key to the iss of the message, for example through workload identity credentials of the kind WIMSE is chartered to define, X.509 certificates chaining to a configured anchor, or keys configured out of band. A key carried inside the message itself, without such a binding, shows nothing about who signed. A receiver MUST accept each trusted key with exactly one algorithm (Section 3.1 of [RFC8725]).¶
The agentproto charter asks for a reference architecture describing related protocol building blocks that the dialog management protocol can reuse, including identity and authentication. This element is meant to use whatever that architecture names.¶
Each hop has its own lifecycle, held separately by the delegator and the delegate.¶
offer (delegator)
|
v
+---------+ rejected (delegate)
| offered |---------------------> [rejected]
+---------+
| | canceled (delegator)
accepted | +-----------------------> [canceled]
(delegate) v
+----------+ canceled (delegator)
| accepted |--------------------> [canceled]
+----------+
| |
completed | | failed (delegate)
(delegate) v v
[completed] [failed]
Brackets mark terminal states. Not drawn: "completed" or
"failed" sent directly from "offered" (accepted is implied),
and the local terminal state "expired".
The host protocol keeps its own task state. The table shows the nearest A2A TaskState [A2A] for each state. A2A states with no entry, such as TASK_STATE_INPUT_REQUIRED and TASK_STATE_AUTH_REQUIRED, stay in the host protocol; they do not change the hop's state.¶
| Handoff state | Nearest A2A TaskState |
|---|---|
| offered | TASK_STATE_SUBMITTED |
| accepted | TASK_STATE_WORKING |
| rejected | TASK_STATE_REJECTED |
| completed | TASK_STATE_COMPLETED |
| failed | TASK_STATE_FAILED |
| canceled | TASK_STATE_CANCELED |
A delegate that receives an offer performs these checks. The first failure ends processing. Except where a check says otherwise, the delegate SHOULD send a "rejected" status with the reason shown, unless doing so would itself leak information its policy protects.¶
If all checks pass and the delegate takes the work, it sends "accepted".¶
Expiry of the outer offer is checked. Earlier offers in a chain are history and are expected to have expired; Section 5.3 checks only that each was live when the next was issued.¶
Let C[0..n-1] be the decoded chain, oldest first, and O the current offer. For uniformity, let C[n] denote O.¶
Failures of checks 2 through 4 use reason "broken-chain".¶
A verified chain shows that each listed agent signed an offer to the next, in that order, while the earlier offer was live. Removing or reordering an intermediate hop breaks check 2 or 3. It does not show that the agents were authorized, or that what they said was true (Section 8.2). It also does not show that an earlier offer had not been rejected or canceled when the next was issued.¶
The obo member names the principal for whom the root of the chain acted, such as a user. Prior delegators appear in chain. OAuth 2.0 Token Exchange [RFC8693] records a similar actor history with nested "act" claims, where the outermost actor is current and nested actors are earlier ones. As with nested act claims in Section 4.1 of [RFC8693], the prior delegators in chain are informational. Unlike a token's sub claim, obo is not an authorization claim. A receiver MUST NOT make an access control decision based on obo or chain alone.¶
Authority comes from credentials that the host protocol carries, issued under OAuth, WIMSE, or a similar framework. The grant member lets the delegator bind the hop to one such credential by digest. A receiver that is given a credential with the hop can check that it is the one the delegator named. Whether the credential's authority exceeds what the previous hop held (B3-8 in [I-D.agentic-ai-usecases-requirements]) is for that framework to decide, not this element.¶
Section 8.1 states, for each security-relevant claim this element makes, who carries it, who verifies it, and how it fails.¶
The handoff context is meant to travel inside the host protocol's own messages. This document defines no new transport and no HTTP header.¶
The table lists each requirement of [I-D.agentic-ai-usecases-requirements] that this element touches, what the element provides toward it, and what it leaves to other mechanisms.¶
| Requirement | Provided | Not provided |
|---|---|---|
| B3-6, verifiable per-hop provenance with removal detectable | Signed offers linked by digest; removing or reordering an intermediate hop is detected when the chain is carried (Section 5.3) | Responses and transformations are not attributed; the start of a chain can be dropped (Section 8.3) |
| B3-7, cycle detection | Check 6 of Section 5.3 | Cycles through hops not in the carried chain |
| B3-8, authority not exceeding the previous hop's | grant binds the hop to one credential by digest (Section 5.5) | The comparison itself, which belongs to the credential's framework |
| B3-9, dialog context propagated per hop | The dialog member and carriage inside the host message (Section 6) | The dialog context itself; this is one element of it |
| B1-7, checking a resuming party | Nothing | Resumption is a host protocol matter |
| CMN-10, revocation propagated down a chain | "canceled" follows prev from hop to hop (Section 4) | Revoking authority; the element grants none |
| B5-3, a mediator between protocols | The Handoff is opaque octets a mediator can copy (Section 6) | The dialog check across a translated identifier (see above) |
[I-D.bu-agentproto-security-principal-binding] asks a protocol to state, for each security-relevant claim, its carrier, its verifier, what binds it, what keeps it fresh, and how it fails. For this element:¶
| Claim | Carrier | Verifier | Binding | Freshness | Failure |
|---|---|---|---|---|---|
| The offer comes from iss | Signature over the offer | Delegate | A key its trust configuration binds to iss (Section 3.4) | iat, exp, and hop (Section 5.2) | "rejected": bad-signature or untrusted-key |
| The offer is for this receiver in this dialog | aud and dialog, under the signature | Delegate | aud equals its AgentId; dialog equals the host identifier | As above | "rejected": wrong-audience or policy |
| The offer follows these earlier offers in order | prev; the chain | Delegate | Handoff digests (Section 3.3); continuity and timing (Section 5.3) | Check 4 of Section 5.3 | "rejected": broken-chain, cycle, or too-deep; or unverifiable where a key is untrusted |
| The work depends on this prior context | refs | Delegate, when policy requires | The object's digest and any kind-specific proof (Section 2.2) | None in the element | "rejected": unverifiable-ref or ref-mismatch; or not checked |
| The delegate answered as stated | Signature over the status | Delegator | A key bound to status.iss; status.offer equals the offer's digest (Section 5.4) | The first verified status stands | Status discarded; conflict flagged to the operator |
A delegator can omit prev and the chain and present itself as the start. The offer is still valid. A receiver that needs to know the origin MUST require a full chain whose first element is signed by an origin it trusts. Without the chain, a receiver also cannot tell whether the delegator passed on an offer that had expired, been rejected, or been canceled.¶
Replay protection depends on the receiver keeping its (iss, hop) cache and on loosely synchronized clocks. A receiver that loses its cache, for example after a restart, SHOULD reject offers with iat before the restart until the maximum lifetime has passed.¶
A stolen delegator key lets an attacker issue offers in that delegator's name until the key is withdrawn from trust. Short lifetimes limit how long a captured offer is useful but not what a stolen key can sign. Revocation of keys is left to the key distribution mechanism (Section 3.4).¶
The typ and content type values make a signed handoff distinct from other JWS or COSE objects signed with the same key. Handoff receivers MUST check them (Section 5.1). This protects a handoff receiver from accepting another kind of object as an offer. It does not protect other verifiers that do not check a type, such as a verifier of Learnlog signed heads [I-D.srivastava-learnlog], which does not require a typ; using separate keys for separate purposes avoids the question.¶
The media types registered in Section 10 do not contain active content.¶
Chains and references can be large, and loc invites fetches. A chain grows by one signed offer per hop (Section 2.1). Receivers MUST bound chain length and element size, and SHOULD NOT fetch loc URIs from untrusted senders without the safeguards they apply to any untrusted URL.¶
The considerations of [RFC6973] apply.¶
This document requests two media type registrations in the "Media Types" registry [RFC6838]. The first names a complete JWS signed handoff, for the typ header (Section 3). The second names the CBOR payload of a COSE signed handoff, for its content type header. No other registry is requested.¶
RFC Editor: please replace "RFC XXXX" below with the number of this document and remove this note.¶
This type labels the CBOR payload carried inside a COSE_Sign1 signed handoff (Section 3).¶
A delegator may want to show that some prior context was registered with a transparency service, so a delegate can check it without trusting the delegator's own storage. The SCITT architecture [RFC9943] defines Signed Statements as COSE_Sign1 messages, and Receipts [RFC9942] as signed proofs that a statement is included in a verifiable data structure.¶
For kind "scitt-receipt":¶
A verified receipt shows that the statement was registered. It says nothing about whether the statement is true.¶
Learnlog [I-D.srivastava-learnlog] is a hash-chained record format. It defines a record as "A header and the entries about one subject, written by one producer", and its subject is a learner. It suits hops where the delegator is the producer of a Learnlog record about a learner, for example a tutoring agent that hands part of a session to another agent.¶
Learnlog defines signed heads. A head names the latest entry of a record (record_hash, seq, entry_hash, and time) and is signed with a JWS whose kid is the signing key's JWK Thumbprint; ES256 is mandatory to implement. A ContextRef of kind "learnlog-head" is one way to pass a head along a handoff:¶
Limits:¶