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

@@ -89,22 +89,28 @@ read-only instead of being discarded. Saves reject external changes, retain a
last-known-good backup, and feed bounded session undo/redo history. Supported
recurring instances appear throughout the month, preserve civil time across
daylight-saving changes, and expose their source zone and whole-series mutation
semantics in the reader. `/` searches occurrence-aware title, description,
location, and calendar-ID matches in a finite ten-year window centered on the
selected date. `c` toggles session-only calendar visibility consistently across
the grid, appointment focus, and search without filtering the model supplied to
persistence. `g` opens an occurrence-aware agenda at the selected month date;
navigation is bounded to consecutive 42-day windows and `Enter` returns to the
exact occurrence in the month grid. `Esc` or `g` closes the agenda without
changing the month selection unless an occurrence was chosen. Hidden calendars
remain filtered there, while calendar selection and search can overlay the
agenda. Agenda navigation never persists state, and add/edit/delete remain in
the month workflow. Week-start selection rotates only the month grid, header,
and the visible range used by its month queries; storage, agenda windows, and
semantics in the reader. A supported recurrence set combines `DTSTART`, rule
expansion, and compatible DATE or DATE-TIME `RDATE` starts, deduplicates starts,
and then removes `EXDATE` exclusions. `/` searches occurrence-aware title,
description, location, and calendar-ID matches in a finite ten-year window
centered on the selected date. `c` toggles session-only calendar visibility
consistently across the grid, appointment focus, and search without filtering
the model supplied to persistence. `g` opens an occurrence-aware agenda at the
selected month date; navigation is bounded to consecutive 42-day windows and
`Enter` returns to the exact occurrence in the month grid. `Esc` or `g` closes
the agenda without changing the month selection unless an occurrence was
chosen. Hidden calendars remain filtered there, while calendar selection and
search can overlay the agenda. Agenda navigation never persists state, and
add/edit/delete remain in the month workflow. Week-start selection rotates only
the month grid, header, and the visible range used by its month queries;
storage, agenda windows, and
recurrence rules are unchanged. The default remains Monday for backward
compatibility. The CLI accepts the exact lowercase values `monday`, `tuesday`,
`wednesday`, `thursday`, `friday`, `saturday`, and `sunday`. The next local-data
work adds advanced recurrence overrides and rule editing.
`wednesday`, `thursday`, `friday`, `saturday`, and `sunday`. `RDATE` periods,
values incompatible with the event's `DTSTART` time basis or `TZID`, detached
`RECURRENCE-ID` overrides, and embedded `VTIMEZONE` definitions remain
read-only. Remaining local-data work includes detached overrides and rule
editing.
## Local file interchange