feat: support safe recurrence additions

Parse, persist, expand, and round-trip compatible RDATE values while preserving whole-series TUI behavior and conservative rewrite guards.

Verified: normal, warning-as-error, and ASan/UBSan builds pass all 9 suites; storage failure paths preserve calendar and backup bytes; live PTY restores terminal state.
This commit is contained in:
2026-07-18 10:14:53 +01:00
parent 989332ef9a
commit cfca6ab6d0
16 changed files with 498 additions and 69 deletions

View File

@@ -36,8 +36,11 @@ requested time window and return values that point back to their source series,
preserving series-level storage and mutation semantics. The supported rule
surface is deliberately bounded to daily/weekly/monthly/yearly frequency,
interval, count or until, weekly `BYDAY`, monthly `BYMONTHDAY`, yearly
`BYMONTH`, and `EXDATE`. Invalid metadata retains at most the base event rather
than crashing a render.
`BYMONTH`, compatible DATE or DATE-TIME `RDATE`, and `EXDATE`. An occurrence set
merges `DTSTART`, rule expansion, and additional `RDATE` starts, deduplicates by
start, and then subtracts exclusions. Mutations continue to address the source
series as a whole. Invalid metadata retains at most the base event rather than
crashing a render.
Search matching is a pure domain predicate over normalized event text; the TUI
owns result presentation and occurrence identity. Recurring searches expand a
@@ -107,12 +110,13 @@ combined with any of the other modes.
The current writer deliberately refuses to mutate an existing file when the
loader encounters information it cannot round-trip, including recurrence
overrides, `RDATE`, custom `VTIMEZONE` definitions, alarms, attendees, unknown
properties, or malformed components. Supported recurrence rules, exclusions,
and system IANA time-zone identifiers round-trip semantically. Browsing remains
available for unsupported files. This conservative boundary is more important
than partial editing because a successful-looking edit must not erase unrelated
calendar data.
overrides, `RDATE` periods or values incompatible with `DTSTART`'s time basis or
`TZID`, custom `VTIMEZONE` definitions, alarms, attendees, unknown properties,
or malformed components. Supported recurrence rules, compatible additional
starts, exclusions, and system IANA time-zone identifiers round-trip
semantically. Browsing remains available for unsupported files. This
conservative boundary is more important than partial editing because a
successful-looking edit must not erase unrelated calendar data.
Provider synchronization will not write directly into this UI file. It will use
a transaction-capable local cache and preserve remote ETags/sync tokens in a