ical: read a two-digit BYDAY ordinal
`FREQ=YEARLY;BYDAY=20MO` — the twentieth Monday of the year — **cannot be parsed at all**, and `BYDAY=6MO` parses into a value that fails its own `Validity`.
## Two bugs, one shape
RFC 5545 §3.3.10:
```
weekdaynum = [[plus / minus] ordwk] weekday
ordwk = 1*2DIGIT ;1 to 53
```
**The parser reads one digit.** `specificP` does `readMaybe [d]` on a single character, so `10MO` reads the `1` and then hands `"0MO"` to `parseDayOfWeek`, which makes nothing of it. Every legal ordinal from 10 to 53 is unparseable, in both signs. A leading `+`, which the grammar also allows, was unreadable for the same reason.
**The type bounds the ordinal at ±5.** That is the bound that fits a MONTHLY rule, where a weekday recurs at most five times. But the type does not know the frequency, and the same section says:
> The numeric value in a
> BYDAY rule part with the FREQ rule part set to YEARLY corresponds
> to an offset within the month when the BYMONTH rule part is
> present, and corresponds to an offset within the year when the
> BYMONTH rule part is not present.
(that second clause as corrected by errata 1913 and 3779). An offset within the year goes up to 53, which is exactly what the ABNF says. A restriction that depends on the frequency belongs in `Validity RecurrenceRule`, which already carries one for BYDAY.
Between the two bugs there was a gap where both were wrong at once:
| value | before | after |
| --- | --- | --- |
| `5MO` | parses, valid | parses, valid |
| `6MO` … `9MO` | parses, **invalid** | parses, valid |
| `10MO` … `53SU` | **rejected at parse** | parses, valid |
| `54MO` | rejected | rejected |
## Two commits
1. **Red.** Four fail: the three `can parse this example correctly` cases for `10MO`, `53SU`, `-53MO`, and `considers the largest ordinal valid`.
2. **Green.** The digits are taken as a run, and the bound becomes ±53.
`rejects an ordinal past the number of weeks in a year` passes before and after. It is there so that widening the bound cannot quietly remove the upper limit altogether.
## Generator
`GenValid ByDay` and its shrinker widen to match, so the roundtrip property in `recurrenceRulePartSpec` now actually exercises two-digit ordinals rather than stopping at 5.
The recurrence implementation needs no change: it compares the ordinal against a computed weekday index, so an ordinal that cannot occur in a given month or year simply matches nothing.
## Checks
`ical-gen` 1083 → 1090 passing, `ical-recurrence-gen` unchanged at 299, both 0 failing. `nix flake check` passes.
## How this was found
While designing the follow-up that makes the parser refuse any value failing its own `Validity`. That PR needs this one first, the same way it needed #33: otherwise it would start rejecting `BYDAY=6MO`, which is legal.