Verified #017 established that idempotency protection can expire before recovery. #018 asks the distributed-time question: whose clock decides that expiry when nodes disagree?

SAME RECORDNODE A: ACTIVENODE B: EXPIREDREPLAY DECISION?

One record. Two opposite temporal decisions.

The record was created at T0 with a 60-second TTL.

A

Node A · T0+50Record is ACTIVE. Original effect remains COMMITTED.

B

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.

NODE B @ +70EXPIREDSAME KEY POSTAPPLIED2 EFFECTS
A local clock is not automatically a trust authority just because that worker happens to execute recovery.

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.

LOCAL CLOCKS DISAGREEAUTHORITY @ +55ACTIVEDEDUPLICATED1 EFFECT

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:

T0+40EXPIRY T0+60T0+80

Because the expiry boundary sat inside that uncertainty window, the safe temporal state was TIME_UNKNOWN — not EXPIRED.

TIME_UNKNOWNGET AUTHORITATIVE STATUSCOMMITTEDNO SECOND POST

What #018 adds to TTP.

I31

SAME RETENTION RECORD + DIFFERENT CLOCKS CAN YIELD DIFFERENT SAFETY DECISIONSTime interpretation is part of the decision evidence.

I32

TIME-BASED SAFETY REQUIRES A DECLARED CLOCK AUTHORITY OR SKEW BOUNDDecision time must have provenance.

I33

EXPIRY INSIDE CLOCK-UNCERTAINTY WINDOW ≠ SAFE REPLAY PERMISSIONTemporal ambiguity should preserve TIME_UNKNOWN.

I34

CLOCK DISAGREEMENT IS EVIDENCE CONFLICTIt should be reconciled, not silently collapsed.

Temporal trust memory.

DURABILITY+RETENTION+CLOCK AUTHORITY+RECOVERY

#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.

  1. Canonical report
  2. Benchmark harness
  3. TTP Clock Authority / Skew Rule
  4. Previous · Verified Report #017

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