# Strict-expiry rule (intended semantics, enforced by mdip-agent-kit >= 0.1.3 verifyResponse):
#   a response MUST expire no later than the challenge it answers:  response.validUntil <= challenge.validUntil
#   equality is ALLOWED (the kit caps a response's expiry at exactly the challenge's validUntil);
#   one millisecond later is REJECTED. A missing response validUntil is REJECTED when the challenge has one.
#   Separately, at verify time both must still be in the future (now < validUntil); that needs a clock, not a vector.
# Timestamps are ISO-8601 (MDIP writes UTC with ms). Since 0.1.4 they are compared as epoch ms, not strings,
#   so a missing fractional part or a +00:00 offset still compares correctly; a timestamp with NO zone is rejected.
# challenge.validUntil          response.validUntil           expected
2026-10-26T16:41:19.930Z      2026-10-26T16:41:19.930Z      accept   equal (mdip-challenge-1/-2 are this case)
2026-10-26T16:41:19.930Z      2026-10-26T16:41:19.929Z      accept   1 ms earlier
2026-10-26T16:41:19.930Z      2026-10-19T16:41:19.930Z      accept   a week earlier
2026-10-26T16:41:19.930Z      2026-10-26T16:41:19.931Z      reject   1 ms later
2026-10-26T16:41:19.930Z      2026-10-26T17:41:19.930Z      reject   1 h later (keymaster's raw default, uncapped)
2026-10-26T16:41:19.930Z      2027-01-01T00:00:00.000Z      reject   next year
2026-10-26T16:41:19.930Z      -                             reject   response has no validUntil
-                             2026-10-26T16:41:19.930Z      accept   challenge has no validUntil (nothing to cap)
2026-10-26T16:41:19.930Z      2026-10-26T16:41:19Z          accept   response without ms (0.930 s earlier)
2026-10-26T16:41:19.930Z      2026-10-26T16:41:20Z          reject   response without ms, 70 ms later
2026-10-26T16:41:19.930Z      2026-10-26T09:41:19.930-07:00 accept   same instant written with an offset
2026-10-26T16:41:19.930Z      2026-10-26T16:41:19.930       reject   response with no timezone (fail closed)
