oficina / calendar Public

Clone
git clone https://amadan.net/oficina/calendar

Plain git — no account needed to clone.

Download

Download this file

1# Recurrence stepping bounds
2
3Status: revision 2 APPROVED by Claude Fable5.1 (claude-fable-5-1), 2026-09-07.
4Evidence: /tmp/oficina-calendar-recurrence-review/design-review2.json.
5Baseline: application branch 2074881; live binary d961b65. This support
6branch does not approve the application's entire unmerged history.
7
8Scope: bounded, exact stepping within the existing recurrence subset.
9Keep every currently parsed positive INTERVAL; no parser or picker limit.
10No UI copy, schema, migrations, COUNT fast-forwarding or new RRULE shapes.
11
12## Evidence
13
14Weekly INTERVAL=100000000 with BYDAY exceeds a two-second child deadline.
15Civil 1600-01-01 to 2000-01-01 saturates at 106751 rather than146097 days.
16A valid INTERVAL=20871 Saturday series silently loses its2000 occurrence
17and reports complete. Yearly MaxInt wraps backwards. Invalid zone/start/end
18reports complete, and a store-level test confirms strict busy-time reads
19return nil rather than ErrIncompleteExpansion for those invalid fields.
20
21## Revised implementation contract
22
231. Use civil(t).Unix()/86400 for integer civil days within the representable
24 record domain: year0000 through9999, the four-digit local date format.
25 All parsed source dates fit this domain. Generated candidates are bounded
26 before arithmetic; no arbitrary-year Unix round-trip machinery is needed.
27 daysBetween subtracts civil-day integers, never time.Duration or floats.
282. Weekly BYDAY considers remaining selected weekdays in the current eligible
29 week, then the first selected weekday in the next INTERVAL-th week, ordered
30 from WKST. cur is eligible by induction from DTSTART. At most13 weekday
31 candidates; no scanning proportional to INTERVAL and no saturated phase.
32 Construct each candidate with the original proto clock as before.
333. Check distance to the final representable civil date by division before
34 multiplying. Daily compares interval with remaining civil days; weekly
35 compares interval with remaining days/7 before computing its week jump.
36 Monthly compares interval with remaining month indexes/step; yearly with
37 remaining years/step. Thus every addition/product stays inside the small
38 four-digit date domain. Do not change parsing or stored INTERVAL.
394. Test calendar-date existence before zone resolution. Yearly checks month
40 length before constructing the candidate; monthly ordinal weekday arithmetic
41 uses UTC civil weekdays, then resolves the selected date in loc. A complete
42 flat4800-month-step or400-year-step search covers every Gregorian residue
43 reachable by any integer interval, because those periods repeat the calendar.
44 No match after that full search proves exhaustion. A horizon reached first
45 does not prove exhaustion. No gcd machinery is required.
465. Stepping distinguishes candidate, proved exhaustion and incomplete. A
47 horizon refusal is ALWAYS INCOMPLETE, regardless of query end: this avoids
48 claiming a UTC cutoff for zones whose next local year starts before UTC's.
49 Invalid Rule construction, non-advancing resolved candidates and resolved
50 dates outside year0000..9999 also report incomplete. Ordinary DST clock
51 normalization remains unchanged; intended-versus-resolved dates across a
52 midnight gap remain a separate pre-existing issue, not silently redesigned.
536. Invalid zone/start/end or reversed event/window intervals make strict
54 expansion incomplete. For an unreadable end preserve tolerant instantaneous
55 output where possible, but retain an input-validity flag so no stop reason
56 can turn it into complete. Existing canceled/note exceptions remain.
577. COUNT/UNTIL satisfaction, passing the window, a valid one-off or proved
58 exhaustion are completion proofs. Check COUNT after generating its final
59 candidate so no unneeded next step can turn completed COUNT into a horizon
60 failure. Keep existing100000 outer/1000 output caps and EXDATE ordering.
61
62## Validation
63
64Adapt the two-second huge-interval probe to expect prompt incomplete refusal;
65add INTERVAL=400000 within year9999 with exact date/weekday/clock. Keep the
66four-century observable regression, reversed civil span, huge-interval cases
67for every frequency, exact near-horizon boundaries, monthly31st/fifth weekday
68and leap-day skips, WKST/DTSTART phase and existing DST/span tests.
69
70Strict store regression must fail before the fix and pass after it while the
71view remains tolerant. Test invalid input, COUNT completion near the horizon,
72query beyond the horizon and unsupported direct Rule values. Mutation-prove
73bounded stepping, exact day arithmetic and incomplete propagation. Run make ci,
74then independent Fable branch review and actual CI before owner integration.
75No production rollout of the unmerged application history is authorized here.
76
77Revision1 was REQUEST CHANGES by Claude Fable5.1 (claude-fable-5-1), evidence
78/tmp/oficina-calendar-recurrence-review/design-review.json. This revision
79accepts the four-digit horizon, exact civil-day arithmetic, pre-zone cycle
80proof and bounded weekly induction; explicitly chooses safe incomplete horizon
81handling from the review's allowed alternatives.
82