Verified #018 established that different clocks can disagree about expiry. #019 asks a harder question: what if one clock first crosses expiry and later moves backward, making the old time value appear valid again after the execution history has changed?
The same record visibly performs a Temporal ABA.
With one durable idempotency record expiring at 7,000,060, the service was queried at three logical wall-clock values:
7,000,050 → ACTIVEThe record is before expiry.
7,000,070 → EXPIREDThe expiry boundary has been crossed.
7,000,050 → ACTIVE againThe scalar returned to its old value.
Across all three observations the remote effect remained COMMITTED / effect_count=1. The value returned; the history did not.
Unsafe · cleanup advances history, rollback resurrects replay permission.
The unsafe case committed one remote effect, lost the acknowledgement, then crossed expiry. Maintenance removed the expired dedupe record and advanced a monotonic temporal epoch:
The wall clock then rolled back from 8,000,070 to 8,000,050, numerically before the original expiry. An un-fenced worker treated the old TTL window as safe replay territory and sent the same Idempotency-Key again.
Final remote state: effect_count=2 / CONFLICT.
Safe A · monotonic temporal epoch fences the old decision.
Recovery bound itself to temporal epoch 2. Expiry cleanup advanced the service to epoch 3. After wall-clock rollback, the same-key retry still carried the old execution epoch.
The service returned temporal_epoch_mismatch, preserved effect_count=1, and recovery reconciled authoritative COMMITTED.
Safe B · monotonic time watermark refuses to move backward.
The second safe control retained the largest time already observed in the trajectory:
The temporal state remained EXPIRED. Recovery reconciled the committed remote effect and made no second POST.
What #019 adds to TTP.
SAME WALL-CLOCK VALUE ≠ SAME TEMPORAL STATE AFTER HISTORY ADVANCESA timestamp is not a history identifier.
RETIRED SAFETY EPOCH MUST NOT BE RESURRECTED BY CLOCK ROLLBACKPast permission does not return with an old time value.
TIME-BASED EXECUTION SHOULD BIND TO MONOTONIC HISTORYUse a temporal epoch, fence or monotonic watermark.
CLOCK ROLLBACK AFTER IRREVERSIBLE TEMPORAL TRANSITION IS EVIDENCE CONFLICTFence or reconcile instead of replaying.
Evidence.
GitHub Actions run 31470122034 completed successfully. Artifact resonance-idempotency-clock-rollback-v1.0 has ID 9093020263 and digest sha256:6132fb3a357952eedcd54aac4d15b48cd429684f9630ed152f3c3b65674b9dce.
The run used PostgreSQL 17.6, psycopg 3.2.9 and a separate python:3.12-slim HTTP service with persistent SQLite effect/idempotency state. The container image digest was python@sha256:229a2c5bfa27522db7815ea81f9bed70af17ccb9de9fc7ad142b1877b5830d36.
Interpretation boundary.
The clock sequence is deterministic logical benchmark time. The experiment does not test operating-system clock rollback, NTP/PTP/chrony, leap seconds, hardware drift, distributed consensus time, multi-region timing or universal exactly-once guarantees. The TTL and timestamps are benchmark parameters, not production recommendations.
Inspect / reproduce
Verdict: a reversible clock value must not be allowed to resurrect an execution state whose temporal history has already advanced.
RESONANCE Verified #019
clock rollback → temporal ABA → monotonic history → safe recovery.
Read TTP v1.0