| Internet-Draft | CEP | October 2026 |
| van de Meent | Expires 2 May 2027 | [Page] |
This document defines the Continuity Envelope Protocol (CEP), a transport-agnostic protocol model for identity-bound messaging systems where delivery alone is not sufficient.¶
CEP separates a visible envelope surface from sealed internal object truth and defines how receivers determine whether a delivered object may safely and legitimately continue. The protocol distinguishes between control-plane notification, data-plane object carriage, and decision-plane continuation handling. It further distinguishes a refused result from an absent one and from an unknown one, and requires that continuation decisions and refusals leave receipts.¶
CEP is the umbrella model for companion drafts such as TIBET TAT, which specifies generic sealed handoff and transfer flow, and IDDrop, which profiles that handoff model for identity transfer.¶
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 2 May 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.¶
Classical messaging protocols are primarily optimized for delivery. For cross-host agents, sealed artifact exchange, and resumable automation, delivery is necessary but insufficient. Delivery establishes that bytes arrived; it does not establish that the object they carry may continue.¶
CEP defines how visible surfaces, sealed truth, and continuation decisions relate across transport fabrics. It is designed to be used alongside agent naming [AINS], identity [JIS], provenance tokens [TIBET], and semantic surface manifests [SSM], but does not depend on any of them normatively.¶
This document defines the separation between control-plane notification, data-plane carriage, and decision-plane continuation handling; the role of the Continuity Envelope as a visible routing surface; the distinction between envelope reference, presence, verification, and continuation approval; the distinction between refused, absent, and unknown results; receipts for continuation decisions and for refusals; how continuity history is read; layered time semantics and drift handling; continuity across restart of a participating runtime; and a common vocabulary for causality and continuation outcomes.¶
This document does not define a single mandatory wire format, a single mandatory transport binding, a specific cryptographic primitive suite, or a universal trust-scoring algorithm.¶
Instead, this document provides the architectural frame into which companion drafts fit: TIBET TAT [TAT] defines the generic touch-and-transfer and relay handoff protocol, while IDDrop [IDDROP] defines an identity-transfer profile over that handoff model.¶
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.¶
The control plane carries notification and lightweight exchange metadata. Control-plane data MUST NOT be interpreted as proof that the receiver possesses or has verified the underlying object bytes unless such proof is explicitly encoded.¶
The data plane carries the continuity-bearing object itself. Examples include local file drop, relay-carried sealed object, peer-to-peer artifact transfer, and object fetched by reference.¶
An object in transit MAY be mutable, but it SHOULD become visible to a consumer only once complete: a sender SHOULD publish an object under its final name or reference atomically (for example, by writing to a temporary name and renaming), and a consumer SHOULD NOT inspect or act on an object before that publication. A partially written object is neither present nor absent; it is not yet published.¶
A drop location is a delivery point, not an archive. Where history of handled objects is needed, it SHOULD be kept as receipts separate from the delivery point, so that a delivery point does not silently become a queue of stale objects.¶
The decision plane evaluates whether continuation is legitimate and safe. The decision plane MUST treat sealed truth as authoritative where conflict exists.¶
A component that only carries or places an object MUST NOT add to, or weaken, a decision made elsewhere. If it carries a decision, it SHOULD carry the decision record unchanged.¶
In mailbox-centered systems, a successful delivery event is frequently treated as the end of the transport problem. In continuity-bearing systems, delivery is only one stage.¶
Several failure classes appear after arrival, including divergence between transport metadata and sealed truth, visible names that overclaim object identity, control-plane references without local bytes, disagreement between time fragments across layers, stale or replayed continuity, and missing or invalid causal parentage.¶
Implementation experience (Section 16) added further classes: a correct refusal that leaves no trace, so that a null receipt cannot be told apart from a receipt that was never needed; a permission that is still acted on after it has aged in transit; a damaged history that a tolerant reader presents as shorter rather than as damaged; and records that are produced but that no component reads, so that their existence implies an effect that does not happen.¶
The Continuity Envelope provides a visible routing surface for operator readability, sorting, grouping, routing hints, freshness hints, priority hints, and continuity diagnostics.¶
The envelope surface is not the final source of truth. CEP therefore adopts the principle: name is hint, content is truth.¶
<time-fragment>.<context>.<profile>.<priority>[.<extension>]¶
The following ABNF, using the notation of [RFC5234], defines a conservative baseline grammar for version 1 envelope surfaces:¶
surface-name = time-fragment "." context "." profile "." priority
[ "." extension ]
time-fragment = compact-time / dashed-time / date-only
compact-time = 8DIGIT "t" 6DIGIT "z"
dashed-time = 4DIGIT "-" 2DIGIT "-" 2DIGIT "t"
2DIGIT "-" 2DIGIT "-" 2DIGIT "z"
date-only = 4DIGIT "-" 2DIGIT "-" 2DIGIT
context = 1*48(segment-char)
profile = 1*48(segment-char)
priority = 1*32(segment-char)
extension = 1*48(segment-char)
segment-char = LCALPHA / DIGIT / "-"
LCALPHA = %x61-7A
DIGIT = %x30-39
¶
For portability and operator safety, implementations SHOULD
prefer lowercase ASCII, dot-delimited segments, and per-segment
characters from [a-z0-9-]. Implementations SHOULD
reject or normalize spaces, shell metacharacters, empty
segments, and path separators.¶
Implementations SHOULD also apply conservative operational limits. Representative values are a total surface length of 180 characters or less, hard rejection above 200 characters, a preferred segment length of 32 characters or less, and a segment upper bound of 48 characters.¶
The sealed object carries the normative internal state. This MAY include manifest data, mirrored surface fields, integrity digests, signature data, sealed time fields, causal parentage fields, and schema or version identifiers.¶
If the envelope surface and sealed truth disagree, the sealed truth MUST be treated as authoritative for object identity, while the mismatch SHOULD be surfaced as a continuity signal.¶
Control-plane metadata and sealed manifest schema identifiers SHOULD be consistent for the same object handoff. An implementation receiving a mismatch MAY triage the object, downgrade trust, request resynchronization, or continue under local policy if the mismatch is understood and bounded.¶
Where signatures in a sealed object are verified against public keys carried in that same object, a successful check establishes that the object is internally consistent. It does not establish that the keys belong to the parties they name; a self-consistent forgery passes the same check. An implementation SHOULD report such a result as internal consistency and MUST NOT report it as authentication unless the keys were bound to the parties by a separate, independently verified means (for example an identity layer such as [JIS]).¶
CEP requires verification to be layered. These states MUST NOT be collapsed into a single generic "verified" signal when their meanings differ.¶
Progress states record how far verification of an object has advanced. They are ordered; each implies the ones above it in Table 1.¶
| State | Meaning |
|---|---|
| referenced | Control plane carries a pointer only |
| present | Receiver possesses bytes locally |
| digest-matched | Observed digest matches expected digest |
| container-verified | Container structure and integrity verified |
| manifest-verified | Manifest semantics and mirrored fields validated |
| continuation-approved | Object may safely continue under policy |
Version -00 listed only progress states, which left a reader with one way to express that verification did not advance: the absence of a higher state. That absence covers three different facts. CEP therefore defines three non-progress states, which MUST be kept distinct from each other and from the progress states.¶
| State | Meaning |
|---|---|
| absent | The reader looked where the object or record must be and found none. This is a measurement. |
| refused | A check was performed and the object did not pass it, or the checking component refused to produce a result. The reason is recorded. |
| unknown | The reader could not determine the state: the bytes or history were unreadable or did not verify, or the component needed to check them was unavailable. |
A non-progress state SHOULD name the progress state at which verification stopped (for example, "refused at manifest-verified") and SHOULD carry a reason.¶
CEP treats causal legitimacy as distinct from delivery. An object MAY be successfully delivered but still fail continuation checks if causal parentage is missing, points to an unknown or invalid predecessor, policy forbids progression from the observed lineage, or drift exceeds acceptable thresholds.¶
| Outcome | Meaning |
|---|---|
| continue | Progression is allowed |
| triage | Further inspection is required |
| fork | Progression continues along a branch |
| quarantine | Object is isolated pending policy review |
| resync | Fresh alignment is required before continuation |
| refuse | Progression is denied and the refusal is recorded |
Continuity history is forward-only. Records SHOULD NOT be deleted or rewritten. A change of state, including a correction or a revocation, SHOULD be expressed as a new record that refers to the record it supersedes.¶
A revocation closes a branch. Continuing after a revocation is a fork: a new branch that refers to the closed one. Records on the closed branch remain valid as history; what ends is the ability to act further on that branch.¶
A party whose signing key has been lost cannot sign the revocation of its own relationship. Where one party therefore closes a branch alone, the record MUST describe itself as unilateral and MUST NOT be presented as a bilateral supersession. A unilateral fork records the local party's own state; it imposes nothing on the peer and grants nothing to a successor, which requires its own fresh establishment.¶
When a reader must determine which of several decisions is the newer one (for example, a grant and a later revocation), the order SHOULD be taken from a causal sequence assigned under a shared write boundary (for example, a sequence number assigned under a lock held by all writers, or position in a hash-linked history). Wall-clock timestamps, file order, and content pointers that other writers also move MUST NOT be the sole basis for that order.¶
A hash link to the previous record proves the order in which records were written. It does not prove that a step consumed, or was caused by, the record before it. A continuation claim that depends on a specific predecessor SHOULD name that predecessor and the subject it concerns explicitly, rather than rely on adjacency in the history.¶
A continuation decision and the effect that follows it are separate facts and SHOULD be recorded separately. The outcome record SHOULD state whether the effect was executed, failed, or never took place, and SHOULD refer to the decision it acts on by that decision's own record reference rather than by a value recomputed later.¶
If a writer cannot determine whether an effect took place, the outcome is uncertain. A reader MUST treat an uncertain outcome as unresolved, not as success and not as failure.¶
A decision record without a receipt can mean three different things: no receipt was needed; a receipt was needed and its production was never attempted; or a receipt was needed, its production was attempted, and the producing layer refused. A single null field cannot carry these three facts.¶
When a receipt is required and its production is attempted but refused, the implementation SHOULD record a Receipt Attempt beside the absent receipt. The receipt field itself SHOULD remain empty, because nothing verifiable was produced. The Receipt Attempt SHOULD contain:¶
The decision recorded alongside a Receipt Attempt stands. Anything downstream that requires a verifiable receipt remains fail-closed; the Receipt Attempt makes that state visible but does not substitute for the receipt.¶
A receiver that refuses an inbound object SHOULD keep a Refusal Record. A correct refusal that leaves no trace removes the evidence needed later to answer when, and with what, a peer stopped verifying.¶
A record that is produced but read by no consumer can imply an effect that does not happen, for example a revocation marker that no verifier consults. An implementation that produces a continuity record SHOULD identify the consumer that reads it. If no consumer exists yet, the producing component SHOULD declare that state explicitly (in this document: "awaiting consumer"), so that the absence of an effect reads as a declared gap rather than as a working mechanism.¶
Likewise, an implementation SHOULD declare which states it distinguishes and must not merge, and which capabilities are deliberately not available, so that a deliberate absence does not read as breakage.¶
A reader of continuity history SHOULD return one of three results:¶
A broken history is unknown, not empty and not shorter. A reader used for a continuation decision, or for any decision that grants or withdraws authority, MUST be a strict reader. A lenient reader MAY be used for display or diagnostics, but its result MUST NOT be used to grant or continue: a lenient reader that skips an unreadable record can drop a withdrawal and thereby make an earlier approval appear to stand again.¶
A strict reader SHOULD verify the same bytes it returns, rather than verify once and read again. A final record that is not yet completely written MAY be excluded from a read-only view, provided the remaining prefix itself verifies; a strict reader that holds the writer's lock SHOULD instead report an incomplete final record as unknown.¶
Where several readers interpret the same history, they SHOULD reach the same verdict on the same defect. In particular, a history whose writer never produces an empty predecessor link after the first record MUST NOT be read as having been legitimately restarted at such a link.¶
CEP treats time as layered rather than singular. Envelope time SHOULD be treated as a grouping hint, freshness hint, operator readability signal, and early drift indicator. It MUST NOT be treated as the sole authority for continuity legitimacy.¶
Sealed internal time fields carry the object's normative time claims. Causal order is authoritative for continuation legitimacy.¶
Implementations use time windows for several purposes, and a single "time to live" field tends to hide which one is meant. CEP distinguishes the following:¶
A window that is too short can silently select a different carrier or path than the one the owner chose. Window lengths SHOULD be chosen with the slowest legitimate path in mind, and a fallback taken because a window lapsed SHOULD be recorded as such.¶
A decision that permits an effect is evidence that the decision was made at a given point, not a permission that is valid whenever it is read. When a permission is carried to a consumer through a delivery point, its freshness SHOULD be checked when it is placed and MUST be checked again when the consumer picks it up. Otherwise a consumer that resumes after a pause can act on permissions that expired while waiting. Implementations SHOULD persist the request, not the permission.¶
When a participating node restarts, it SHOULD decide explicitly whether to resume its previous continuity state or to reseed (start a new runtime state while retaining history). The decision SHOULD be based on recorded evidence of how the previous run ended:¶
The decision SHOULD produce a receipt that names the branch taken, the reason, and the head of the continuity history at the time of the decision. The component that decides SHOULD NOT also consume the evidence it decided on, when another component performs the actual resumption.¶
Continuity relationships between parties SHOULD be bound to long-lived parties (accounts) rather than to the runtime instances that currently represent them, with a separate, short-lived attestation binding the current runtime to the relationship. A break retires the runtime, not the account.¶
CEP is transport-agnostic. Possible bindings include local file drop, peer-to-peer delivery, relay-based object transfer, control-plane notification over message protocols, object fetch by reference, and future bridge transports.¶
CEP is intended to be read together with companion drafts when a concrete transfer or application profile is needed.¶
In particular, TIBET TAT defines how a consent-bound sealed handoff is executed across proximity, relay, or local network paths, and IDDrop defines how identity claims are offered, requested, validated, and materialized over that handoff substrate.¶
CEP therefore acts as the umbrella model: CEP says how continuity-bearing messaging is structured, TAT says how a sealed transfer happens, and IDDrop says how identity transfer happens over TAT.¶
Field names in these examples are illustrative.¶
{
"from_agent": "jasper",
"to_agent": "codex",
"poll_type": "PUSH",
"metadata": {
"envelope_name": "20260514t064148z.message.jasper.normal.tza",
"envelope_ref": "/var/lib/tibet/inbox/20260514t064148z.message.jasper.normal.tza",
"schema": "aint-send-v2",
"verification_state": "referenced"
}
}
¶
{
"schema": "aint-send-v2",
"surface_time_fragment": "20260514t064148z",
"surface_context": "message",
"surface_profile": "jasper",
"surface_priority": "normal",
"sealed_created_at": "2026-05-14T06:41:48.207135+00:00",
"content_digest": "sha256:b5ca11489ffadc4438a3815a0d7ea3bc88836dbc2f5951b1e9d7800d784aa675",
"causal_parent": null
}
¶
{
"verification_state": "unknown",
"stopped_at": "manifest-verified",
"reason": "verifier unavailable; signatures carried, not checked"
}
¶
{
"decision": "continue",
"decision_ref": "9f2c41d07ab3e655",
"receipt": null,
"receipt_attempt": {
"state": "receipt_refused_by_minter",
"owner": "unattributed",
"reason": "ValueError: unknown axis 'example'",
"is_not": [
"no receipt was needed",
"the proposal or item was refused",
"the human presence failed"
]
}
}
¶
{
"kind": "refusal-record",
"at": 1789000000,
"refused_by": "sync-receive",
"reason": "bad-runtime-account-signature",
"grants_nothing": true,
"claimed_relation_id": "rel-0123456789abcdef",
"claimed_account": "peer.example",
"claimed_runtime_pubkey": "4f1e...",
"signature_halves": {"runtime": "valid", "account": "invalid"}
}
¶
To remain interoperable, CEP implementations SHOULD preserve predictable envelope grammars, separate reference from verification states, expose mismatches rather than hiding them, converge schema identity across control and sealed planes, and support both operator readability and machine normalization.¶
In addition, implementations SHOULD carry the non-progress states "absent", "refused", and "unknown" as distinct values on the wire, SHOULD carry a Receipt Attempt rather than a bare null where a required receipt could not be produced, and SHOULD agree on how a damaged continuity history is classified (Section 10), since two readers that disagree on whether a history is intact will disagree on whether an object may continue.¶
[RFC Editor: please remove this section, and the reference to RFC 7942, before publication.]¶
This section records the status of known implementations of the protocol defined by this specification at the time of posting of this Internet-Draft, and is based on a proposal described in [RFC7942]. The description of implementations in this section is intended to assist the IETF in its decision processes in progressing drafts to RFCs. Please note that the listing of any individual implementation here does not imply endorsement by the IETF. Furthermore, no effort has been spent to verify the information presented here that was supplied by IETF contributors. This is not intended as, and must not be construed to be, a catalog of available implementations or their features. Readers are advised to note that other implementations may exist.¶
According to [RFC7942], "this will allow reviewers and working groups to assign due consideration to documents that have the benefit of running code, which may serve as evidence of valuable experimentation and feedback that have made the implemented protocols more mature. It is up to the individual working groups to use this information as they see fit".¶
A receiver MUST NOT interpret a control-plane reference as proof of object integrity unless the referenced object has been acquired and verified under local policy.¶
Collapsing "unknown" into "absent" or into a progress state turns a failure to verify into a result. Implementations MUST fail closed on "unknown" (Section 7.3).¶
A lenient reader of continuity history can omit a revocation or withdrawal and so revive an earlier grant. Authority decisions MUST use a strict reader (Section 10). A strict reader detects damage to a history but not a writer that rewrites the entire history consistently; protection against that requires an anchor outside the history, which is out of scope here.¶
Refusal Records contain content chosen by the sender of the refused object. That content MUST be treated as untrusted data and MUST NOT be executed or used to resolve, look up, or compare against anything outside the receiver's own store (Section 9.2).¶
Verifying signatures against keys carried in the same object does not authenticate the signers (Section 6.2).¶
A permission that is acted on after it has aged in a delivery point permits work that began after the permission had already lapsed. Consumers MUST re-check freshness at pickup (Section 11.2).¶
Runtime attestations for a runtime that is no longer current MUST be refused, so that a retired runtime cannot continue a relationship (Section 12.2).¶
Records with no consumer can give the appearance of a control that is not enforced, for example a revocation marker that no verifier reads (Section 9.3).¶
This version of the document makes no IANA requests.¶
The following values are RECOMMENDED starting points for implementation alignment.¶
| Value | Class | Reference |
|---|---|---|
referenced
|
progress | Section 7.1 |
present
|
progress | Section 7.1 |
digest-matched
|
progress | Section 7.1 |
container-verified
|
progress | Section 7.1 |
manifest-verified
|
progress | Section 7.1 |
continuation-approved
|
progress | Section 7.1 |
absent
|
non-progress | Section 7.2 |
refused
|
non-progress | Section 7.2 |
unknown
|
non-progress | Section 7.2 |
The continuation outcomes of Table 3 (continue,
triage, fork, quarantine,
resync, refuse) and the history-reading results
of Section 10 (clean,
absent, unknown) are separate value sets and are
not verification states.¶
Future versions of this document MAY elevate these values into a formal registry.¶
[RFC Editor: please remove this section before publication.]¶
absent,
refused, and unknown, with rules that keep
them distinct and fail closed on unknown.¶
refuse
outcome and subsections on forward-only history and forks, on
ordering versus descent, and on separating decision from
outcome.¶
Initial version.¶
This draft emerged from continuityd, TBZ/TZA, AInternet, and JIS/TIBET design work across the HumoticaOS stack, including real operational feedback from early cross-host continuity handoffs.¶