tibet-timevector
Causal TimeVector — Mattern/Fidge vector clocks for TIBET/JIS lanes.
TIBET's Lamport generations give a monotone successor order — enough for causal succession, but they cannot tell, across multiple independent JIS lanes, whether A happened before B, B before A, or A and B were genuinely concurrent (under partition / offline work). For that you need a vector clock (Mattern/Fidge 1988). That's this package.
The vector is causal evidence. Wall-clock time is supporting evidence only. JIS/TIBET signatures remain the authority.
It is a separate layer from tibet-y2k38 (which
adapts broken wall clocks). This is the JIS-causality-flex layer.
Two things it gives you
1. Honest causality across lanes
from tibet_timevector import CausalTimeVector
codex = CausalTimeVector.genesis("codex.aint", "codex_0").tick("codex_1")
claude = CausalTimeVector.genesis("claude.aint", "claude_0").tick("claude_1")
codex.relation_to(claude) # "concurrent" — neither saw the other
claude2 = claude.observe(codex, "claude_saw_codex")
codex.relation_to(claude2) # "before" — claude2 now knows codex_1
Relation rule (Mattern/Fidge): A < B iff every component A[i] <= B[i] and at least one
<; symmetric for >; otherwise concurrent. This makes causal drift visible instead
of pretending timestamps are enough.
2. CausalGuard — refuse causally-spontaneous actions
The sharper use, and the reason it's a security primitive. A sleeper agent (e.g. Red
Specter's DETONATE) breaks cause-and-effect: on its trigger it initiates a destructive
action out of nothing — no cryptographically-proven user-intent, no logical predecessor
in the chain. CausalGuard rejects it not because it looks malicious, but because it is
causally impossible: it has no valid ancestor tracing back to a consented intent.
from tibet_timevector import CausalTimeVector, CausalGuard
guard = CausalGuard()
root = CausalTimeVector.genesis("agent.aint", "grant_root")
guard.register(root, consented_root=True) # e.g. produced by a ParentAttest grant
guard.register(root.tick("legit_action")) # descends from the grant → allowed
# A DETONATE action that arises from nowhere:
sleeper = CausalTimeVector(lane_id="agent.aint", event_id="detonate",
generation=99, vector={"agent.aint": 99},
parent_event_id="evt_that_never_existed")
guard.verify(sleeper).allowed # False — "orphan: parent not in the known chain"
You don't need to recognise the attack. You need to recognise the absence of a valid predecessor. That's a fundamentally stronger model than signature/policy matching.
Rejection classes (all = "causally impossible", not "naughty"):
- spontaneous — no parent link and not a consented root
- orphan — parent_event_id references an event never seen (forged / out-of-nothing)
- broken causality — candidate vector does not dominate its claimed parent
- unrooted — chain does not lead back to any consented root
CLI
pip install tibet-timevector
tibet-timevector demo # two-lane concurrency → observe()
tibet-timevector guard-demo # spontaneous-intent rejection (DETONATE)
tibet-timevector check a.json b.json # relation between two vectors
Where it fits
- Mahipal's drift-test: the vector clock IS the answer to "causal timeline + drift" — it distinguishes concurrency from causality under partition, which Lamport can't.
- W3C / VC over TAT: tells which causal world a Verifiable Credential knew at the moment of transfer/presentation/re-attestation — distinct from a linear verifiable history.
- T-1 genesis + sleeper defense (Principe 3): CausalGuard is the runtime gate that makes a DETONATE-style spontaneous action causally impossible. See the SPECTER SLEEPER defensive mapping for the full vector-by-vector analysis.
Dependencies (bootstrap-or-die)
tibet-core >= 0.5.0b2— provenance chainjis-core >= 0.4.0b1— identity / lane authority
Credits
Reference implementation: Codex (tibet-causal-timevector sketch, 2026-05-31). Productionisation + CausalGuard (spontaneous-intent rejection): Root AI, 2026-06-01. Concept + layer-split (vs tibet-y2k38): Jasper van de Meent.
Part of HumoticaOS. One love, one fAmIly. 💙
Metadata
Release files for tibet-timevector 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tibet_timevector-0.1.0.tar.gz | 9.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tibet_timevector-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 19.2 kB
Release files / tibet_timevector-0.1.0.tar.gz
| Download URL | tibet_timevector-0.1.0.tar.gz |
|---|---|
| Size | 9.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5131d14711bb8b02c260e37c0c2d378ea76f33088a3ed263ad86ac61b665334b
|
|
BLAKE2b-256 checksum How to use checksums |
482e57ecea0eb26b0e324d08369e4ba35f2f667f00c48a6c4513f4740a5bb8b7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|
Release files / tibet_timevector-0.1.0-py3-none-any.whl
| Download URL | tibet_timevector-0.1.0-py3-none-any.whl |
|---|---|
| Size | 9.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b656c688f2c7947cfcbe4b5154dad43ecbc507d86a3b79a78a26dd1c019b15a7
|
|
BLAKE2b-256 checksum How to use checksums |
a48e73490360e901e9347d034a00e361b3781921102b9863ec759c45d26ca395
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|