| Internet-Draft | TIBET Causal Time | October 2026 |
| van de Meent | Expires 2 May 2027 | [Page] |
This document describes the TIBET Causal Time Substrate, a forward-only causal ordering model for identity-bound distributed systems.¶
TIBET does not treat wall-clock time as the primary ordering primitive. Instead, it uses a cryptographically bound logical-time structure encoded through append-only linkage, monotonic generation counters, and signed causal references. External wall-clock sources, including NTP, RFC 3161 timestamping services, Roughtime, GNSS, or public ledger timestamps, are treated as auxiliary alignment anchors rather than as the constitutive source of event order.¶
This revision adds an optional vector-observation layer for relating events across independent lanes, a classification of time-bounded checks that separates physical-world windows from ledger-state windows, replay protection that does not depend on clock agreement between parties, and a distinction between forks, breaks, and reseeds.¶
The core claim is simple: TIBET is a forward-only causal substrate that enables recovery and reversibility without rewriting history.¶
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.¶
This memo is revision -03 of draft-vandemeent-tibet-causal-time. Revisions -00 through -02 were derived from operational architecture notes, prototype implementations, and forensic delivery work produced in the Humotica / TIBET stack during May 2026. The -01 revision added the Filename-Surface Contract (Section 16.5) following external peer review by Red Specter Security Research (RS-2026-001). The -02 revision added the Position in the Four-W Vault Family (Section 17).¶
The -03 revision incorporates what a reference implementation (Section 18) revealed between May and October 2026. Four gaps in -02 were found in practice: a scalar generation counter cannot tell concurrent events from ordered ones across independent lanes (Section 12); the word "expiry" was being used for checks of different kinds, some of which should not depend on wall-clock time at all (Section 13); wall-clock validity windows were silently doing the work of replay protection (Section 14); and "fork" was being used for several outcomes that need to be told apart (Section 15). A complete list of changes is given in Appendix A.¶
The document captures and formalizes a structural property that TIBET implementations already exhibit, rather than introducing a greenfield timing model. It is intended to align distributed-systems theory, identity-bound execution, off-grid or degraded-network operations, and forward-only recovery semantics.¶
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.¶
Many distributed systems continue to over-privilege wall-clock time. They assume that safe ordering, freshness, replay defense, and reversibility can be grounded primarily in synchronized UTC.¶
That assumption is fragile under intermittent connectivity, NTP outage or misconfiguration, GNSS disruption, clock drift across edge nodes, compromised or ambiguous time authorities, and adversarial replay after restore or rollback.¶
A less visible form of the same problem arises when a validity window is introduced for one purpose and silently becomes the only defense for another. A message that is carried slowly between two nodes with correctly synchronized clocks can be rejected as "expired" although nothing about it is stale; removing the window to fix that symptom can then remove the only replay protection the message had. Section 14 addresses this.¶
This document argues that causal order should be primary, wall-clock time auxiliary, recovery forward-only, and history non-rewritable.¶
The TIBET Causal Time Substrate is intended to preserve causal ordering without dependence on absolute time, support cryptographic identity binding of events, permit recovery and revocation without history rewriting, and remain meaningful under offline or degraded-network conditions.¶
It is also intended to integrate with external time anchors, support replay-sensitive freshness checks, and surface time uncertainty honestly.¶
A further goal added in this revision is that every time-bounded check states what it measures, so that a reader can tell a check on the physical world from a check on ledger state.¶
TIBET encodes causal order through a set of existing structural primitives including append-only linkage, signatures, generation counters, and parent references.¶
These map naturally onto a Lamport-style logical ordering model: happened-before pointers, tamper-evident order proof, authenticated event origin, logical counters, causal predecessors, and event-line roots.¶
The important consequence is that TIBET already behaves as a causally ordered logical-time substrate. This document formalizes that fact.¶
A chain may have two distinct origins. The causal origin is its first record. The authority origin is the first record made under an established identity (a genesis). Records written before an identity exists (for example, during a pre-boot phase) are causally ordered but carry no authority. Implementations SHOULD keep the two origins distinct and MUST NOT derive authority from records that precede the authority origin.¶
The defining property of TIBET causal time is not merely that events are ordered, but that valid evolution occurs only by moving forward.¶
Restore MUST become fork rather than rewind, revocation MUST become a successor event rather than a mutation, correction MUST become an amendment rather than an overwrite, and cancellation MUST become a compensating action rather than an erasure.¶
A revocation or tombstone closes a branch. Continuing after a revocation is a fork with its own record; it is never an "unrevoke" of the closed branch.¶
These classes are not all necessarily already standardized in TIBET registries, but they align structurally with the substrate described here.¶
External time anchors provide auxiliary alignment between local causal order and broader time-bearing reference systems such as NTP, timestamping authorities defined by [RFC3161], Roughtime, GNSS, PTP, public ledger timestamps, or observed environmental anchors.¶
External time anchors MAY improve alignment. They MUST NOT redefine already established causal order.¶
Clock drift is expected in real systems, especially edge systems and off-grid nodes. TIBET treats drift as a recordable condition, not as a collapse of ordering truth.¶
Implementations SHOULD be able to represent locally observed time, externally anchored time, offset between them, uncertainty window, and validity scope of the observation.¶
Where a record carries wall-clock information alongside causal information, the wall-clock part SHOULD be labelled as supporting evidence (for example, with its source, uncertainty, and observed drift), so that no reader mistakes it for the ordering basis.¶
When a local event is committed, the implementation increments or derives a monotonic generation value, binds the event to prior causal state, signs the event, and appends it according to Section 11.5.¶
When a remote or transferred event enters local reasoning, the implementation evaluates causal relation and derives successor progression in Lamport style as max(local generation, remote generation) plus one for any new local successor event that depends on both.¶
When the vector layer is in use, the incoming event's vector is additionally merged as described in Section 12.¶
Recovery produces successor state by fork, compensation, revocation, reseed, or new forward-causal action. It MUST NOT pretend to restore the system to an earlier pre-committed causal state. Whether a participant may resume or must reseed is decided as in Section 15.3.¶
When external time is sampled, the implementation MAY write an external-anchor event and MAY write drift information, but MUST NOT use the anchor to invalidate already committed causal order.¶
In a hash-linked chain, each record names its predecessor by a digest of the predecessor's serialized form. If two writers read the same chain head and then both append, both new records name the same predecessor and the chain forks without any participant intending it. Appending with an operating-system "append" mode does not prevent this, because the conflict arises when the head is read, before the write.¶
An implementation SHOULD serialize the sequence "read the head, compute the predecessor reference, append, make durable" as one critical section per chain.¶
If such serialization is unavailable on the storage in use, the implementation SHOULD still write the record, and the record itself MUST state that the concurrency guarantee was absent. Refusing to write would discard evidence; writing without the statement would let a reader mistake an unintended fork for tampering, or tampering for a race.¶
Availability of serialization SHOULD be tested on the target storage rather than assumed, because some storage accepts a lock request without enforcing it.¶
If a chain does not end on a record boundary (an earlier write was interrupted), an implementation MUST NOT append directly after the fragment. Repairing the tail is a separate act that produces its own record naming the fragment that was set aside.¶
A transition that is only valid under a precondition on the chain (for example, "no newer revocation exists") SHOULD evaluate that precondition against the verified chain inside the same critical section in which the transition is appended. Where serialization is unavailable, such a conditional transition SHOULD be refused rather than written with an absent-guarantee marker, because its meaning depends on its position.¶
A chain MAY be pruned (older records removed), for example for storage reasons. Without further information, a reader that finds the first surviving record pointing at a predecessor that is absent cannot tell pruning from corruption.¶
A pruning implementation SHOULD therefore write a scar record at the new head of the chain. The scar declares the full digest of the last removed record. A verifier treats the cut as declared if, and only if, the scar's declared value equals the predecessor reference carried by the first surviving record.¶
The scar MUST be at the head, not appended at the end, so that a verifier walking forward meets the declaration before it meets the missing link. A scar makes a cut visible; it does not authorize it. Whoever can rewrite the chain can also write a scar; protection against that requires an anchor outside the chain.¶
The scalar successor rule of Section 11.2 yields an order consistent with causality, but when several lanes operate independently (for example, during a network partition) it cannot express that two events were concurrent. This section defines an OPTIONAL vector layer for that purpose.¶
A Causal TimeVector record carries at least: a version identifier, the lane identifier of the event, an event identifier, the lane's own counter value, the vector (a map from lane identifier to counter value), and the identifier of the parent event, if any. It MAY carry wall-clock observation and clock evidence as supporting data.¶
The operations are:¶
In comparison, a lane that is absent from a vector MUST be treated as lower than any present value, including a genesis value of 0. Treating an absent lane as 0 would make a vector that has seen a lane's genesis indistinguishable from one that has never seen the lane.¶
The lane's own counter in a vector record is not the same quantity as the scalar generation of Section 11.2: the former advances by one per event on that lane, the latter is max(local, remote) plus one across lanes. An implementation that carries both MUST NOT use one in place of the other.¶
The vector is causal evidence. It is not authority: signatures and identity binding remain the basis for accepting an event. "Concurrent" is not an error; it means that neither side had yet observed the other. An implementation MAY use the vector to refuse an event that claims to act on behalf of a prior consented event but whose vector does not dominate that event's vector, or whose claimed parent is unknown, or which has no parent and is not itself a consented root. Such refusals are statements that the event is causally impossible as presented, not that it is malicious.¶
A "TTL", "expiry", or "timeout" is not one kind of thing. Before a time-bounded check is introduced or kept, an implementation SHOULD classify it by what it measures:¶
A window that is too short can change the outcome rather than only the timing: if a slower but chosen path cannot complete within it, the system may fall back to a different path that the principal did not choose. Window lengths for physical-world windows SHOULD be chosen against the slowest path they are meant to admit.¶
Ageing MAY raise attention. Ageing MUST NOT by itself change a verdict: an undecided item (a hold) may become stale, but it does not become a denial by being old. An item whose age cannot be determined MUST NOT be treated as fresh.¶
"Expired" can mean evidence freshness, request freshness, display priority, or execution eligibility. Implementations SHOULD name which of these a given expiry affects.¶
When a decision arrives after the window it answers has closed, the implementation SHOULD refuse it by name and record that nothing was decided, rather than record the decision.¶
Any claim that something changed is a claim about an interval. Records that assert change or absence of change SHOULD name the interval over which they measured, and SHOULD state when the interval could not be measured, instead of reporting "no change".¶
Replay protection and freshness are different properties and SHOULD NOT share one mechanism.¶
For a single-use artifact such as an offer or invitation, replay protection SHOULD be provided by a nonce that the accepting side consumes atomically on first acceptance and refuses thereafter. A wall-clock validity window MAY be kept as a liveness bound, but once replay is handled by nonce consumption the window can be generous, and its expiry is then a statement about liveness only.¶
Where the vector layer is used, the offering side SHOULD include its vector inside the signed offer, so that it cannot be altered without invalidating the signature. The accepting side derives its own observation by merging that vector (Section 12) and MUST refuse if the offer's vector is not "before" or "same" relative to the resulting observation.¶
A recommended order of checks at acceptance is: signature, liveness bound (if any), causal descent (if a vector is present), nonce consumption, then construction of the accepted state. Placing nonce consumption after the checks that can refuse avoids burning a nonce on an artifact that is refused for another reason.¶
An implementation MUST NOT gate identity on the agreement of two clocks it does not both control. Where an artifact is created on a clock the verifier does not control (for example, a browser of an unknown party), its self-asserted issue and expiry times SHOULD only be checked against a broad plausibility envelope; freshness comes from a single-use element issued on the verifier's own clock.¶
A key or binding that has been tombstoned MUST be refused regardless of signature validity or freshness. A key that has been re-anchored to a successor proves history and MUST NOT authorize new action.¶
Revision -02 used "fork" broadly. In practice several outcomes need to be distinguished, because they call for different responses.¶
An admitted fork is a declared transition with a name from a fixed set and the proof terms that the name requires. One such set, used by the reference implementation, is:¶
| Transition | Required proof | If proof is missing |
|---|---|---|
| new | genesis | nothing was created |
| restore | verified identity bundle | new actor, not restore |
| reseed | successor key | successor, not continuity |
| retire | tombstone | not retired |
| replace | tombstone and successor | retired but pointing nowhere, or not retired |
A claimed transition that lacks its proof SHOULD be reclassified as the weaker outcome that its evidence does support, rather than simply refused. Transition names MUST be compared exactly; a verifier that normalizes case or whitespace lets the recorded bytes and the verdict diverge.¶
An observed fork, including one caused by concurrent writers (Section 11.5), is not admitted. A validator that assesses whether a present state has a valid path from origin SHOULD start from "unproven" and accept only continuations that conserve the preceding proof and admitted forks.¶
When linkage verification fails, the cause determines the remedy. A verifier SHOULD classify each break rather than stop at the first. A useful classification is:¶
Counts reported by such a classifier SHOULD state whether they count broken links or incidents, since one fork with three children produces two broken links.¶
A chain whose linkage is intact can still be incomplete: its last record may have started an operation that never reached a terminal record. Such an "open tail" is a distinct finding from a break.¶
A participant MAY resume a previous run under the same runtime identity only if it can prove that the previous run closed, for example through a durable shutdown record written as part of an orderly stop.¶
If no such proof exists but there is evidence that a previous run took place (as after a crash, forced termination, or power loss), the participant MUST NOT silently resume. It SHOULD write a reseed record that states the break, retire the previous runtime identity, and continue under a successor. Long-lived identity (for example, an enrolled account) can persist across a reseed; the runtime binding does not.¶
The absence of a closing record is itself information: for an involuntary stop it is expected; for a voluntary stop it is suspicious. Implementations SHOULD NOT fill in a missing closing record after the fact.¶
A participant whose key changes is not "lagging"; under the same name there is now a different signer. A verifier SHOULD report a differing key as a fork, and SHOULD treat it as more serious than an absent key, since a differing key continues to produce valid-looking signatures.¶
A lost key cannot sign its own revocation. When a bilateral relation can no longer be closed bilaterally because one party's key is gone, the remaining party MAY record a unilateral fork. That record MUST identify itself as unilateral, MUST NOT present itself as a bilateral supersession, and MUST NOT alter the original relation record, which remains valid as history. Any successor relation is a separate, fresh agreement.¶
A predecessor reference proves write order: this record was written after that one. It does not prove that this record was made because of, or in response to, that one. Presenting write order as descent obscures rather than establishes causality.¶
Where descent matters (for example, "this retry answers that refusal"), the record SHOULD name its parent explicitly and record the subject that both concern, so that a reader can check whether parent and child are about the same subject. The result of that comparison SHOULD be one of "same", "changed", or "unknown", and an unreadable subject MUST yield "unknown", never "same".¶
In the TIBET model, a snapshot references a chain position and resume becomes a fork from that position. The new line advances with its own forward-only history.¶
In TAT [I-D.vandemeent-tibet-tat] or TIBET Drop, transfer_out records sender-side causal commitment, transfer_in records receiver-side causal acknowledgement, and successor generation derives from the maximum of local and sender generation plus one.¶
Two participants form a relation in three steps.¶
If the offer is carried slowly, nothing in this flow fails as long as the liveness bound is not exceeded; replay of the same offer fails at nonce consumption regardless of clock state.¶
If routing surface and sealed manifest differ (see [I-D.vandemeent-tibet-semantic-surface-manifest]), content may still be valid, but the causal substrate should treat the situation as anomaly and create a triage fork or isolation path.¶
The semantic surface of a sealed continuity envelope is carried in two layers: the filename layer, observable without unpacking, and the manifest layer, authoritative only after Ed25519 signature verification.¶
These two layers MAY agree, partially agree, or conflict. A verifying implementation produces one of four surface_status verdicts: MATCH (all surface_* fields agree), PARTIAL (some agree, others absent or differ), MISMATCH (both layers present and at least one field conflicts -- potential rename attack), or NONE (neither layer has surface_* fields -- legacy bundle).¶
Filename construction is the operator's responsibility. The packing library SHOULD provide a helper that derives a canonical filename from the manifest's surface_* fields, so MATCH is the default for freshly packed envelopes. However, this specification does not require it.¶
PARTIAL is therefore a valid and expected verdict for envelopes that an operator has consciously renamed for human navigation (e.g. "vergadering-dinsdag.pdf"). It is NOT a defect; it is a recorded statement that the human-applied name diverges from the canonical-from-manifest name.¶
Implementations MUST be able to reconstruct the canonical filename from the manifest alone, so that any peer with the bundle can recover the original SSM-derived name after operator rename, record both the human name and the canonical name in audit so that rename events become explicit instead of silent, and detect MISMATCH as a candidate rename-attack signal distinct from PARTIAL (operator-renamed) and MATCH (no rename or aligned rename).¶
Audit records emitted by a verifying implementation SHOULD carry the field name "canonical_name" alongside the on-disk "name" field, with a boolean "renamed_by_operator" derived from their inequality. This naming convention is referred to as the canonical_name field throughout this specification; the helper function that computes it from a manifest is named canonical_filename().¶
This contract anchors causality to the visible surface: a peer seeing only the filename has a hint; a peer seeing the sealed content has the truth; the audit chain records the relationship between the two.¶
The Causal Time Substrate defined in this document does not stand alone. It underpins a four-part family of credential and continuity primitives, agreed informally by the implementation team on 12 May 2026 and elaborated in companion specifications.¶
The four-W family arose from the recurring observation that secret-handling systems consistently fail to answer four distinct questions: when may a sealed result be disclosed, how is the underlying secret stored and tracked, why is a specific bounded act permitted, and where is the act safely performed. Each W maps to its own primitive in the family.¶
The family members are: tibet-vault, the WHEN primitive, which is a temporal trigger that releases a sealed payload on a date or upon a dead-man-switch condition; tibet-keychain, the WHERE/HOW primitive, which records custody and timeline for where a secret currently lives, who touched it, when it was rotated or exposed, and how it moved between owner, custodian, and active operator; tibet-sam, the WHY primitive, which is a Sealed Authentication Module that permits a single bounded act without releasing the underlying secret and is specified as an extension to the Semantic Surface Manifest ([I-D.vandemeent-tibet-semantic-surface-manifest], Section 13); and tibet-gateway, the WHERE-EXEC primitive, which is the execution boundary runtime in which a SAM envelope is unsealed, validated, executed against an upstream credential, and the ephemeral session destroyed.¶
Note that the WHEN primitive's date trigger is a physical-world window in the sense of Section 13: it concerns calendar time, and wall-clock evidence is the appropriate basis for it.¶
The Causal Time Substrate provides the verifiable ordering and identity-bound action chain that lets the four family members interoperate. Every meaningful event in the family produces an entry in a TIBET audit chain: secret creation in tibet-keychain, SAM materialisation linking back to the issuing keychain action, gateway execution linking to the materialised SAM, and disclosure events in tibet-vault when applicable.¶
The forward-only property defined in Section 7 of this document ensures that none of these events can be retroactively altered: a credential-handling system built on this substrate cannot pretend that a secret was rotated earlier than it was, nor that an authorisation was granted before the prior revocation event.¶
The four-W family answers four distinct regulatory questions that traditional secret-store products do not natively address: who has access (custody timeline, WHERE/HOW primitive); why was a specific use authorised (intent and scope record, WHY primitive); where did the use occur (execution boundary record, WHERE-EXEC primitive); and when may the result be disclosed (temporal trigger, WHEN primitive). Implementations of any subset of these primitives SHOULD record their events into a shared Causal Time Substrate chain so that audit walkers (such as tibet-cbom) can reconstruct the full sequence after the fact.¶
[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 stand-alone package implementing the Causal TimeVector record (version identifier "tibet.causal-timevector.v0.1") and the guard described above, published under the MIT license. The node implementation in Section 18.1 carries a pinned copy of it. Contact as above.¶
This document assumes an attacker may replay previously valid artifacts, re-inject old state through backup or restore channels, manipulate wall-clock sources or exploit clock drift, rename or relabel artifacts outside sealed causal truth, or attempt destructive rollback semantics through operational tooling.¶
The forward-only causal model is specifically designed to reduce replay-after-restore, replay-after-revoke, backup injection, clock-spoofing ambiguity, drift concealment, and destructive rollback.¶
The key invariant is that security-sensitive reversibility MUST be implemented as forward causal compensation, not as history rewrite.¶
Additional considerations identified in this revision:¶
This substrate is designed to compose with JIS identity, UPIP continuity, TAT transfer flow, TBZ or ICC container semantics, and semantic routing surfaces.¶
Interoperability therefore depends less on UTC agreement and more on shared causal encoding, verifiable linkage, explicit anchor semantics, and clear distinction between order and alignment.¶
Linkage digests are computed over serialized records, so every writer and verifier of a chain MUST use the same serialization, including key ordering, separators, and whether the record terminator is part of the digested bytes. A writer that follows the convention almost exactly produces chains that every verifier reports as broken.¶
Tools that merge several chains into one view for display MAY order the merged view by wall-clock time, but verification MUST proceed per chain along its linkage, and display order MUST NOT be presented as causal order.¶
Within the broader architecture, Turing answers what computes, Lamport-style causal time answers when in event order, JIS answers who is permitted, and semantic framing layers answer within what semantic frame a process is interpreted.¶
TIBET occupies the causal-time substrate role while composing with the other axes.¶
The following topics are non-blocking for the present version and are recorded here to guide later discussion and interoperability work.¶
This document has no IANA actions in the present version.¶
Future revisions may define registries for external time-anchor token shapes, drift-record token shapes, causal freshness proof types, or canonical transition names, likely under Expert Review policy as described in [RFC8126].¶
The author thanks the Humotica team for editorial assistance, internal peer review, and operational tooling that made this substrate framing concrete rather than theoretical. In particular, Root AI (Claude, Anthropic) and Codex contributed analysis, implementation review, and editorial assistance; several of the distinctions in this revision were first named in their review work.¶
The substrate framing also builds on the logical-time tradition established by [LAMPORT1978] and the vector-clock work of [FIDGE1988] and [MATTERN1988].¶
The author also thanks Richard Barron of Red Specter Security Research for adversarial validation that helped sharpen the forward-only recovery property under realistic attack conditions.¶