Verified #017 established that idempotency protection can expire before recovery. #018 asks the distributed-time question: whose clock decides that expiry when nodes disagree?
One record. Two opposite temporal decisions.
The record was created at T0 with a 60-second TTL.
Node A · T0+50Record is ACTIVE. Original effect remains COMMITTED.
Node B · T0+70Same record is EXPIRED. Original effect still remains COMMITTED.
The only difference is the clock used to interpret expires_at=T0+60. The business evidence itself did not change.
Unsafe · node-local expiry becomes replay authority.
The first HTTP POST committed one remote effect and then dropped the response, so recovery began at ACK_UNKNOWN. Node A observed active_idempotency_records=1. Node B observed active_idempotency_records=0 for the same record and same effect_count=1.
Final unsafe state: 2 POST requests, 2 remote effects, CONFLICT.
Safe A · use a declared decision-time authority.
The second scenario kept the exact local disagreement: Node A still saw ACTIVE and Node B still saw EXPIRED. But replay was evaluated against a declared authority time T0+55, still before expires_at=T0+60.
The real second HTTP POST reused the same idempotency key and returned deduplicated.
Safe B · if uncertainty crosses expiry, preserve TIME_UNKNOWN.
The third path declared a maximum clock error of ±20 seconds. The observed local time was exactly on the expiry boundary. That produced an uncertainty interval spanning both sides of expiry:
Because the expiry boundary sat inside that uncertainty window, the safe temporal state was TIME_UNKNOWN — not EXPIRED.
What #018 adds to TTP.
SAME RETENTION RECORD + DIFFERENT CLOCKS CAN YIELD DIFFERENT SAFETY DECISIONSTime interpretation is part of the decision evidence.
TIME-BASED SAFETY REQUIRES A DECLARED CLOCK AUTHORITY OR SKEW BOUNDDecision time must have provenance.
EXPIRY INSIDE CLOCK-UNCERTAINTY WINDOW ≠ SAFE REPLAY PERMISSIONTemporal ambiguity should preserve TIME_UNKNOWN.
CLOCK DISAGREEMENT IS EVIDENCE CONFLICTIt should be reconciled, not silently collapsed.
Temporal trust memory.
#016 asked whether memory survived. #017 asked whether it was still valid. #018 asks whose time decides that validity and what to do when the answer is uncertain.
Evidence.
GitHub Actions run 31468827381 completed successfully. Artifact resonance-idempotency-clock-skew-v1.0 has ID 9092529978 and digest sha256:de18c97b164742f55dcb2725af83637abe8d51014930c56d26363e6340b2a345.
Execution used PostgreSQL 17.6 and a separate python:3.12-slim HTTP container with persistent SQLite remote state. The HTTP image digest was python@sha256:229a2c5bfa27522db7815ea81f9bed70af17ccb9de9fc7ad142b1877b5830d36.
Interpretation boundary.
This benchmark tests deterministic decision semantics under intentionally separated logical clocks. It does not test NTP/PTP/chrony, physical oscillator drift, leap seconds, consensus time, a universal production skew bound or production provider idempotency behavior. The 20-second disagreement and 60-second TTL are benchmark parameters.
Inspect / reproduce
Verdict: time-based replay protection needs a declared time authority or an uncertainty policy that refuses to turn temporal disagreement into permission.
RESONANCE Verified #018
time authority → uncertainty → reconciliation → proof.
Read the TTP clock rule