Compact Binary Linked Data with Semantic Reasoning for Constrained IoT Networks
Project description
CBOR-LD-ex
Compact Binary Linked Data with Semantic Reasoning for Constrained IoT Networks
CBOR-LD-ex extends CBOR-LD with bit-packed Subjective Logic primitives — compliance status, opinion tuples, operator provenance, temporal decay, and security metadata — enabling edge IoT devices to exchange semantically-rich compliance annotations at a fraction of the cost of JSON-LD.
Built on jsonld-ex and its compliance algebra (Syed et al. 2026).
Key Properties
- 4-byte semantic annotations on constrained devices (1-byte header + 3-byte opinion)
- 37× smaller than JSON-LD, >10× smaller than standard CBOR-LD for the same semantic content
- 93% bit efficiency — almost every wire bit carries Shannon information
- Tiered encoding adapts to device capability: 1-byte headers on MCUs, 4-byte+ on gateways/cloud
- Temporal extensions — bit-packed decay metadata, log-scale half-life (1s to 388 days in 8 bits), compliance triggers
- Security primitives — annotation digests, Byzantine fusion metadata, chained provenance (16 bytes per entry, zero waste)
- Transport-agnostic — identical payloads over MQTT and CoAP
- Three formal axioms — backward compatibility, algebraic closure, quantization correctness
- 282 tests including exhaustive 8-bit verification (32,896 pairs) and Hypothesis property tests
6-Way Encoding Benchmark
CBOR-LD-ex is not just smaller — it carries more semantic information in fewer bytes than any alternative encoding.
| # | Encoding | Payload size | Annotation overhead | Semantic fields |
|---|---|---|---|---|
| 1 | JSON-LD (raw text) | ~280 bytes | ~148 bytes | data + verbose annotation |
| 2 | jsonld-ex CBOR-LD (context-only compression) | ~85 bytes | 0 | data only |
| 3 | Our CBOR-LD (full key+value compression) | ~22 bytes | 0 | data only |
| 4 | jsonld-ex CBOR-LD + annotation | ~210 bytes | ~125 bytes | data + annotation as JSON |
| 5 | Our CBOR-LD + standard CBOR annotation | ~70 bytes | ~49 bytes | data + CBOR k/v annotation |
| 6 | CBOR-LD-ex (bit-packed) | ~30 bytes | 4 bytes | data + compliance + opinion + provenance |
Key findings:
- CBOR-LD-ex annotation: 4 bytes vs CBOR-LD's 49 bytes for the same semantic content (>10× smaller)
- Our
ContextRegistry(full key+value compression) beats jsonld-ex's context-only compression - CBOR-LD-ex is the only encoding that fits compliance + opinion in a single 802.15.4 frame (127 bytes)
- Annotation bit efficiency: 93% (Shannon information / wire bits)
Run cbor_ld_ex.transport.full_benchmark() to reproduce these numbers for your own documents.
Installation
pip install cbor-ld-ex
Or with Poetry:
poetry add cbor-ld-ex
Quick Start
from cbor_ld_ex.opinions import quantize_binomial
from cbor_ld_ex.headers import Tier1Header, ComplianceStatus, PrecisionMode
from cbor_ld_ex.annotations import Annotation, encode_annotation
from cbor_ld_ex.codec import encode, decode, ContextRegistry
# Quantize an opinion: 85% belief, 5% disbelief, 10% uncertainty
b_q, d_q, u_q, a_q = quantize_binomial(0.85, 0.05, 0.10, 0.50, precision=8)
# (217, 13, 25, 128) — SL constraint preserved exactly: 217 + 13 + 25 = 255
# Build a Tier 1 annotation (constrained device)
header = Tier1Header(
compliance_status=ComplianceStatus.COMPLIANT,
delegation_flag=False,
has_opinion=True,
precision_mode=PrecisionMode.BITS_8,
)
ann = Annotation(header=header, opinion=(b_q, d_q, u_q, a_q))
# Encode annotation: 4 bytes total (1 header + 3 opinion; û not on wire)
wire_bytes = encode_annotation(ann)
assert len(wire_bytes) == 4
# Full CBOR-LD-ex message with context compression
registry = ContextRegistry(
key_map={"@context": 0, "@type": 1, "value": 2, "unit": 3},
value_map={"https://schema.org/": 100, "Observation": 101, "celsius": 102},
)
doc = {
"@context": "https://schema.org/",
"@type": "Observation",
"value": 22.5,
"unit": "celsius",
}
cbor_ld_ex_bytes = encode(doc, ann, context_registry=registry)
# Decode round-trip
recovered_doc, recovered_ann = decode(cbor_ld_ex_bytes, context_registry=registry)
assert recovered_doc["value"] == 22.5
assert recovered_ann.opinion[:3] == (217, 13, 25) # b̂, d̂, û (û derived)
Transport (MQTT / CoAP)
from cbor_ld_ex.transport import (
to_mqtt_payload, from_mqtt_payload, derive_topic, derive_qos,
to_coap_payload, from_coap_payload,
)
# MQTT — same CBOR-LD-ex payload + protocol metadata
payload = to_mqtt_payload(doc, ann, context_registry=registry)
topic = derive_topic(doc, ann) # "cbor-ld-ex/Observation/temp-042/compliant"
qos = derive_qos(doc, ann) # 2 (high confidence → exactly-once)
# CoAP — identical payload, different transport
coap_payload = to_coap_payload(doc, ann, context_registry=registry)
assert coap_payload == payload # Transport-agnostic encoding
Temporal Decay
from cbor_ld_ex.temporal import (
TemporalBlock, ExtensionBlock, encode_half_life, decode_half_life,
compute_decay_factor, apply_decay_quantized, DECAY_EXPONENTIAL,
)
# Encode a 1-hour half-life in 8 bits (log-scale, ~7% granularity)
encoded = encode_half_life(3600.0)
decoded = decode_half_life(encoded) # ≈ 3600 seconds
# Apply decay to a quantized opinion (dequantize → decay → re-quantize)
factor = compute_decay_factor(DECAY_EXPONENTIAL, half_life=3600.0, elapsed=3600.0)
# factor ≈ 0.5 (one half-life elapsed)
b2, d2, u2, a2 = apply_decay_quantized(*ann.opinion, factor, precision=8)
assert b2 + d2 + u2 == 255 # Axiom 3 preserved through decay
Security
from cbor_ld_ex.security import (
compute_annotation_digest, verify_annotation_digest,
ProvenanceEntry, CHAIN_ORIGIN_SENTINEL,
encode_provenance_entry, verify_provenance_chain, compute_entry_digest,
)
# Annotation digest (truncated SHA-256, 8 bytes)
digest = compute_annotation_digest(wire_bytes)
assert verify_annotation_digest(wire_bytes, digest)
# Provenance chain entry (16 bytes, 128 bits, zero waste)
entry = ProvenanceEntry(
origin_tier=0, operator_id=0, precision_mode=0,
b_q=217, d_q=13, a_q=128,
timestamp=1710230400,
prev_digest=CHAIN_ORIGIN_SENTINEL,
)
entry_bytes = encode_provenance_entry(entry)
assert len(entry_bytes) == 16 # Every bit carries information
Architecture
Tier 1 (Constrained) Tier 2 (Edge Gateway) Tier 3 (Cloud)
┌─────────────────┐ ┌─────────────────────┐ ┌──────────────────────┐
│ 1-byte header │ │ 4-byte header │ │ 4-byte + extensions │
│ 3-byte opinion │─────>│ Fused opinion │──>│ Provenance chain │
│ = 4 bytes total │ MQTT │ Operator provenance │ │ Full audit trail │
│ │ CoAP │ Byzantine filtering │ │ Chained digests │
└─────────────────┘ └─────────────────────┘ └──────────────────────┘
~85% smaller Temporal decay Full reasoning
than JSON-LD + spatial fusion reconstruction
Formal Guarantees
| Axiom | Property | Guarantee |
|---|---|---|
| Axiom 1 | Backward Compatibility | Strip annotations → valid CBOR-LD → valid JSON-LD |
| Axiom 2 | Algebraic Closure | Every SL operator produces valid annotations |
| Axiom 3 | Quantization Correctness | b̂ + d̂ + û = 2ⁿ − 1 exactly |
All three axioms are verified by cross-cutting property tests including exhaustive enumeration of all 32,896 valid 8-bit opinion pairs, and Hypothesis property tests through all operators (fusion, meet, decay).
| Precision | Max error (b,d) | Max error (u) | Wire bytes |
|---|---|---|---|
| 8-bit | ~0.002 | ~0.004 | 3 |
| 16-bit | ~0.000008 | ~0.000015 | 6 |
| 32-bit | IEEE 754 | IEEE 754 | 12 |
API Overview
| Module | Purpose |
|---|---|
opinions.py |
Constrained quantization codec (Theorems 1–3) |
headers.py |
Tier-dependent header encoding/decoding (§5) |
annotations.py |
Annotation assembly + CBOR Tag(60000) + extensions |
temporal.py |
Bit-packed decay, log-scale half-life, expiry/review triggers |
security.py |
Annotation digests, Byzantine metadata, provenance chains |
codec.py |
Full encode/decode pipeline, ContextRegistry, Shannon bit analysis |
transport.py |
MQTT + CoAP adapters, 6-way full_benchmark() engine |
Development
git clone https://github.com/jemsbhai/cbor-ld-ex.git
cd cbor-ld-ex
poetry install
poetry run python -m pytest tests/ -v
TDD Methodology
This project follows strict test-driven development. Every module has comprehensive tests including property-based testing via Hypothesis. Tests are never weakened to pass — the code or design is fixed instead.
Project Structure
cborldex/
├── src/cbor_ld_ex/
│ ├── opinions.py # Quantization codec (Theorems 1–3)
│ ├── headers.py # Tier-dependent header codec (§5)
│ ├── annotations.py # Annotation assembly + CBOR tagging + extensions
│ ├── temporal.py # Temporal extensions — decay, triggers, BitWriter/BitReader
│ ├── security.py # Digests, Byzantine metadata, provenance chains
│ ├── codec.py # Full codec, ContextRegistry, bit-level analysis
│ └── transport.py # MQTT + CoAP adapters, 6-way benchmark engine
├── tests/
│ ├── test_opinions.py # 38 tests — quantization, Hypothesis properties
│ ├── test_headers.py # 28 tests — Tier 1/2/3 header roundtrips
│ ├── test_annotations.py # 15 tests — assembly, CBOR tag, wire format
│ ├── test_temporal.py # 65 tests — bit-packed extensions, decay, triggers
│ ├── test_security.py # 33 tests — digests, Byzantine, provenance chains
│ ├── test_codec.py # 46 tests — full pipeline, payload comparison
│ ├── test_axioms.py # 19 tests — cross-cutting axiom verification
│ └── test_transport.py # 24 tests — MQTT, CoAP, 6-way benchmark
├── spec/
│ ├── FORMAL_MODEL.md # Formal specification v0.2.0-draft
│ └── IMPLEMENTATION_PLAN.md
├── pyproject.toml
└── LICENSE
282 tests total, all passing.
References
- Syed, M., Silaghi, M., Abujar, S., and Alssadi, R. (2026). A Compliance Algebra: Modeling Regulatory Uncertainty with Subjective Logic. Working paper.
- Jøsang, A. (2016). Subjective Logic: A Formalism for Reasoning Under Uncertainty. Springer.
- Shannon, C.E. (1948). A Mathematical Theory of Communication. Bell System Technical Journal.
- Bormann, C. and Hoffman, P. (2020). RFC 8949: CBOR. IETF.
- Shelby, Z. et al. (2014). RFC 7252: CoAP. IETF.
- Selander, G. et al. (2019). RFC 8613: OSCORE. IETF.
- CBOR-LD Specification (W3C Community Group Draft).
- JSON-LD 1.1 (W3C Recommendation).
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cbor_ld_ex-0.2.1.tar.gz.
File metadata
- Download URL: cbor_ld_ex-0.2.1.tar.gz
- Upload date:
- Size: 33.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.3.2 CPython/3.12.2 Windows/11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8cc0a02e8441e2b2eb99b4224af97482c5343bdd50a1f749adb96b584c468cd5
|
|
| MD5 |
b72df1f9be56f0d47cf05a755faba7fb
|
|
| BLAKE2b-256 |
16466957fa6108011a2935a8a39551e2c590f65f7f7b5034a5ebb2d989c0c09e
|
File details
Details for the file cbor_ld_ex-0.2.1-py3-none-any.whl.
File metadata
- Download URL: cbor_ld_ex-0.2.1-py3-none-any.whl
- Upload date:
- Size: 34.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.3.2 CPython/3.12.2 Windows/11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fe6f2955fc5544fda00712ad13a219d2454136c9dfa60844f5ad00a406a03e53
|
|
| MD5 |
ad2a0b14b74c5cab8d9a07b2e189a46a
|
|
| BLAKE2b-256 |
ae79657ed036e3122acb570185bae2e8b9bda6826cbc63f52c0830df206d0dc9
|