Repository navigation
Repeat rules stay readable by 1.0 devices where an equivalent exists - #1022
Merged
Merged
Conversation
`every N weeks on <day>` on a task due on that day is `every N weeks` anchored on the due date. 1.0 cannot parse the new form and ends the series when it completes the task, so every writer now stores the old form where it is equivalent: quick add (web and Go), the repeat field, REST, the agent tools, CalDAV (FromRRULE), the importer, the vault and a series split, through recurrence.Compatible and compatibleRule, pinned by the "compatible" vectors. A frozen copy of the 1.0.0 grammar checks every writer's output and every quick-add vector. docs/stability.md says what remains for rules only 1.1 can express. OpenSpec change recurrence-1-0-compatible (archived). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bkw4TZLFDGeMdZR3vWZF13
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #1019 (#1016).
The compatibility problem
#1019 added
every N weeks on <weekdays>and made quick add, CalDAV, the importer and the vault write it, even for "every other Friday" due on a Friday, where 1.0'severy 2 weeksmeans exactly the same. A 1.0.0 client cannot parse the new form: in v1.0.0'scompleteTask(web/src/lib/ops.ts),seriesRule()returns null for an unparseable rule, the task takescompletePlain, and the series ends for good.docs/stability.mdpromises that every 1.x client (including a web app still cached on a phone) keeps working against a newer server, so this was data loss on a 1.0 device.The fix
every N weeks on <day>on a task whose due date (at write time) falls on that day is stored asevery N weeks, which the due date anchors. Theuntil/for N timesend is kept. The two give the same dates, including catch-up.recurrence.Compatible(Go) andcompatibleRule(TS), pinned by the newcompatiblevectors inrecurrence.vectors.json. Every writer goes through it: quick add (both parsers), the repeat field (setRecurrence) andplanTask, REST (canonicalizeRecurrence, using the body's due or the task's), the agent tools (create and update), CalDAV (FromRRULE, which also covers the importer's and the vault notes' RRULEs), the importer planner and own-export import, the vault's 🔁 lines, and a series split (Go and web).internal/recurrence/recurrence10andweb/src/lib/testdata/recurrence-1.0.tsare frozen copies of the v1.0.0 grammar.Check/check10fail a stored rule that 1.0 can't read when a 1.0 rule gives the same dates over 60 occurrences. Every writer's test runs its output through it, and so does every quick-add vector, in both languages.TestNotLinkedkeeps the Go copy out of both binaries.docs/stability.mdunder what may change within 1.x, with the advice to update devices. I left resume-detection out: the op doesn't record which client version completed the task, and "completed with a rule 1.0 can't read" would also catch series someone ended on purpose.What each writer stores now
every 2 weeksevery 2 weeks on saturdayevery 2 weeksFREQ=WEEKLY;INTERVAL=2;BYDAY=SA, Saturday DTSTART/DUEevery 2 weeksevery 2 weeks on saturdayOpenSpec change
recurrence-1-0-compatible(archived): it adds "Rules a 1.0 client reads" torecurring-tasksand updates the "every other" scenarios innatural-language-capture. Docs:stability.md,recurrence.md(new "Rules older devices read"),quick-add.md,repeat-rules.md,caldav.md,import.md, plus AGENTS.md and architecture.md for the new package. The changelog fragment from #1019 now describes the final behaviour.Checks
go test ./...,go vet ./..., staticcheck on the touched packages;npx vitest run src/lib/nlp src/lib/recurrence src/lib/recurring src/lib/recurrenceCompatible src/lib/seriesSplit src/lib/habits src/app/task-detail(1089 tests),npm run typecheck,make web-lint,npm run build,make bundle-budget(687.0 of 687 KB),make docs-check,make openspec-validate,make repo-check,make i18n-check.🤖 Generated with Claude Code
https://claude.ai/code/session_01Bkw4TZLFDGeMdZR3vWZF13