UTLP Executive Summary: The Unkillable Watchdog¶
For Hardware Engineers — How to Build It
What It Is¶
A distributed timing protocol that maintains phase lock across nodes without: - A master node (any node can be Genesis) - Connection state (pure broadcast) - Central coordination (consensus emerges locally)
Target Hardware: ESP32-C6 with ESP-NOW (tested), portable to any MCU with broadcast RF.
The 30-Second Architecture¶
┌─────────────────────────────────────────────────────────────────────┐
│ UTLP NODE │
├─────────────────────────────────────────────────────────────────────┤
│ LAYER 7: APPLICATION │
│ Your app (EMDR therapy, drone swarm, etc.) │
│ Reads: atomic_time = local_time + time_offset │
├─────────────────────────────────────────────────────────────────────┤
│ LAYER 4: TIMING ENGINE (utlp.c) │
│ - Beacon TX/RX (11-byte chirps) │
│ - Genesis election (stratum + atomic time) │
│ - Phase alignment (drift correction) │
├─────────────────────────────────────────────────────────────────────┤
│ LAYER 3: TRUST (utlp_trust.c) │
│ - Metabolic Ledger (12 peer slots) │
│ - Health scores (0-255) │
│ - Median consensus │
├─────────────────────────────────────────────────────────────────────┤
│ LAYER 2: IMMUNITY (utlp_immune.c) │
│ - Token bucket (5 tokens) │
│ - Anergy state (exhaustion) │
│ - Rate limiting │
├─────────────────────────────────────────────────────────────────────┤
│ LAYER 1: HAL (utlp_hal_esp32.c) │
│ - ESP-NOW broadcast │
│ - 64-bit timer (esp_timer_get_time) │
│ - GPIO/PWM actuators │
└─────────────────────────────────────────────────────────────────────┘
Critical Numbers¶
| Parameter | Value | Why |
|---|---|---|
| Beacon size | 11 bytes | Fits in single ESP-NOW frame |
| Peer slots | 12 | Silicon Dunbar's Number |
| Sync threshold | 100 health | Minimum to be trusted |
| Agreement window | 2 ms | Phase tolerance |
| Lying threshold | 100 ms | Beyond = punished hard |
| Token bucket | 5 tokens | Entrainment rate limit |
| Token refill | 12 seconds | 1 token per 12s |
| Anergy recovery | 3 tokens | Exit exhaustion at 3 |
Beacon Format (11 bytes)¶
Byte 0: Stratum (0=GPS, 1=Genesis, 2=Follower, ...)
Byte 1: Burst index (0, 1, 2 for seismic chirp)
Byte 2: Genesis score (0-255, topology metric)
Bytes 3-10: TX timestamp (64-bit, little-endian, microseconds)
Seismic Chirp: 3 bursts × 2ms spacing = 6ms per beacon. Enables drift extraction via polynomial fit.
Genesis Election (Who Is The Clock?)¶
// Priority order:
1. Lower stratum wins (GPS < Genesis < Follower)
2. Same stratum: Higher atomic time wins ("First Born")
3. Tie-breaker: Lower MAC address wins (dominance hierarchy)
// Bootstrap behavior:
- Boot as stratum 1 (Genesis)
- If hear better stratum → demote and adopt
- If hear same stratum with elder atomic time → demote
Trust Dynamics (The Immune System)¶
// On receiving a beacon:
deviation = peer_offset - consensus_offset;
if (deviation < 2000us) health += 2; // TRUTH
else if (deviation < 100ms) health -= 10; // DRIFTING
else health -= 50; // LYING
// Selection: health dominates stratum
score = (health * 10) + (16 - stratum);
// A healthy stratum-2 beats a sick stratum-1
Rate Limiting (Cytokine Storm Prevention)¶
// Before firing entrainment pulse:
if (!utlp_immune_can_defend()) return; // Budget exhausted
if (!utlp_trust_has_quorum()) return; // No crowd support
// Both constraints must pass
send_chirp(); // Fire entrainment pulse
Time-Indexed Execution (The Magic)¶
Wrong way:
UTLP way:
uint64_t now = utlp_hal_get_atomic_time_us();
bool should_be_on = (now % 1000000) < 500000;
set_led(should_be_on); // Recalculated every tick
This is drift-proof because output state is computed from shared atomic time, not accumulated delays.
Genesis Pulse (Beacon Intervals)¶
| Uptime | Interval | Phase |
|---|---|---|
| 0-1s | 100ms | Genesis burst |
| 1-5s | 500ms | Fast convergence |
| 5-10s | 1000ms | Settling |
| 10-60s | 10s | Stabilizing |
| 60s+ | 60s | Steady state |
New nodes announce loudly, then quiet down. Late joiners inherit established timing.
Hardware Requirements¶
| Component | ESP32-C6 Example | Notes |
|---|---|---|
| Timer | esp_timer (64-bit) | Microsecond resolution |
| Radio | ESP-NOW | Connectionless broadcast |
| Actuator | GPIO/PWM | Phase-aligned output |
| Memory | ~400 bytes | Static allocation only |
No malloc. No fragmentation. No surprises.
Build Checklist¶
- ☐ Implement HAL for your platform (see
utlp_hal.h) - ☐ Copy
utlp.c,utlp_trust.c,utlp_immune.c - ☐ Call
utlp_app_run()from your main - ☐ Use
utlp_hal_get_atomic_time_us()for all timing - ☐ Test two nodes: verify LED blink sync < 2ms
Test Vectors¶
| Test | Expected Result |
|---|---|
| Single node boot | Stratum 1, beacon @ 100ms initially |
| Two nodes, same boot | Lower MAC stays Genesis |
| Node reset with offset | Elder atomic time wins |
| Byzantine attacker | Drops to health=0, ignored |
| Ledger full | Lowest-health peer evicted |
Quick Reference: Key Functions¶
// Initialization
utlp_trust_init();
utlp_immune_init();
utlp_hal_init();
// Get synchronized time
uint64_t now = utlp_hal_get_atomic_time_us();
// Record peer observation (called on beacon RX)
utlp_trust_record_observation(mac, offset_us, stratum);
// Select best peer for sync
utlp_peer_ledger_t *best = utlp_trust_select_best_peer();
// Check entrainment budget
bool can_fire = utlp_immune_can_defend();
// Check crowd support
bool have_support = utlp_trust_has_quorum(my_offset, 2000);
Files¶
| File | Lines | Purpose |
|---|---|---|
utlp.c |
~1300 | Core protocol engine |
utlp_trust.c |
~800 | Metabolic Ledger |
utlp_trust.h |
~550 | Trust API + constants |
utlp_immune.c |
~120 | Token bucket + anergy |
utlp_immune.h |
~200 | Immune API + constants |
utlp_hal.h |
~250 | Platform abstraction |
utlp_hal_esp32.c |
~400 | ESP32 HAL implementation |
Total: ~3,620 lines of C
The Philosophy¶
"Time cannot wait for pairwise agreement or quorum. A distributed timeline must be born of one — a single genesis node declares the epoch and propagates the reference."
The first device IS the atomic clock. Peers are optional enhancements, not requirements. When a second device arrives, it defers to the established timeline. No voting. No elections. Just physics.
Document version: 1.0 Parent: UTLP Technical Supplement S2.35 Implementation: ESP32-C6 / ESP-NOW Repository: https://github.com/lemonforest/mlehaptics/tree/main/examples/utlp