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?

ACTIVEEXPIREDCLOCK ROLLBACKACTIVE?

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:

A

7,000,050 → ACTIVEThe record is before expiry.

B

7,000,070 → EXPIREDThe expiry boundary has been crossed.

A

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.

Same wall-clock value ≠ same temporal state after history advances.

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:

EXPIREDGC removes recordepoch 1 → 2

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.

same keyrolled-back timeAPPLIED2 EFFECTS

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.

expected epoch 2current epoch 3HTTP 409FENCED OUT

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:

seen 10,000,070wall clock 10,000,050effective now 10,000,070

The temporal state remained EXPIRED. Recovery reconciled the committed remote effect and made no second POST.

What #019 adds to TTP.

I35

SAME WALL-CLOCK VALUE ≠ SAME TEMPORAL STATE AFTER HISTORY ADVANCESA timestamp is not a history identifier.

I36

RETIRED SAFETY EPOCH MUST NOT BE RESURRECTED BY CLOCK ROLLBACKPast permission does not return with an old time value.

I37

TIME-BASED EXECUTION SHOULD BIND TO MONOTONIC HISTORYUse a temporal epoch, fence or monotonic watermark.

I38

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.

  1. Canonical report
  2. Benchmark harness
  3. TTP Temporal ABA rule
  4. Previous · Verified Report #018

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