ical-recurrence: revive the resolve/unresolve roundtrip test
`TimeZoneSpec.hs` had a permanently-disabled `xit` asserting that resolving and unresolving any local time gives it back. That is false unconditionally: a local time inside a spring-forward gap has no instant that maps to it, and a single generated observance with `TZOFFSETTO` past `TZOFFSETFROM` creates exactly such a gap. Presumably why it was disabled rather than fixed.
That roundtrip is worth keeping rather than deleting, because it **is** the existence test. `localTimeExists` defines it that way and `recurEvents` drops the instances that fail it, so this property pins the predicate the recurrence set depends on.
## What the property asserts now
The domain is restricted to the local times the zone actually has. The gap is derived **from the two offsets**, not from the roundtrip:
```haskell
inTransitionGap =
lt >= start
&& Time.localTimeToUTC (utcOffsetTimeZone toOffset) lt
< Time.localTimeToUTC (utcOffsetTimeZone fromOffset) start
```
That is the composition of what the two neighbouring tests in the same file already assert about which offset each direction picks. Guarding with `localTimeExists` instead would have asserted a tautology, since that function *is* the roundtrip.
## Two things the generators cannot reach, so they get their own tests
**The gap.** The property generates its local time independently of the observance, so the two land within an hour of each other essentially never. The branch this test exists for was never exercised. Four cases pin it with exact expected values, including both boundaries: the gap is `[start, start + (to - from))`, so `02:30` comes back as `01:30` while `03:00` comes back unchanged.
**Leap seconds.** These surfaced as a genuine failure while writing this, and they are not a time zone question: whether one survives depends on both the time of day and the offset. `23:59:60` at a zero offset comes back, `00:00:60` normalises into the following minute, and `23:59:60` at `+01:00` lands on the next day's midnight. The property excludes them, and three cases pin the behaviour that justifies the exclusion, so it cannot quietly stop being justified if `time` changes.
## Not red
No source changed. The property passes as soon as its domain is right. Suite goes from 289 passing / 0 failing / 2 pending to 297 / 0 / 1; the only remaining pending is the deliberate `RecurrenceRuleSpec.hs` one. `nix flake check` passes.
## Finding, not addressed here
`BySecond`'s `Validity` admits 0 to 60 (RFC 5545 §3.3.10 allows 60 for leap seconds), so a rule such as `FREQ=MINUTELY;BYSECOND=60` can generate a local time holding a leap second. `localTimeExists` then reports it nonexistent, so `recurEvents` drops the instance everywhere except `23:59:60` at a zero offset, which survives by accident. Whether that is wrong depends on what a leap-second `BYSECOND` ought to generate, and the spec does not say.