Reviewed the plan against the code it describes. Two design holes and five errors. Instance identity was the real one. The plan deleted the materialised instances table without saying what replaces the instance row id, which TasksRepositoryImpl.updateTask passes to updateInstance and which ListsScreen keys a lazy list by. Two occurrences of one series can appear in the same list, so taskId alone is not unique and a hash of (taskId, start) can collide - as a Compose key that is a visible bug. Task.id is dropped for occurrenceStart, updateInstance takes (taskId, occurrenceStart, form), and External mode maps back to a real instance row with one query. This is the single seam change, and the plan's "TasksDataSource unchanged" claim was wrong. Local lists had no account name. TaskList.accountName is non-null, ListsViewModel groups by it and ListsScreen renders it as a section header, so a null account_id must still report "Local". The unique index was wrong: overrides share their master's UID, so unique (list_id, uid) would reject the rows the recurrence design depends on. It needs recurrence_id in the key. Phase 0 broke background reminders. It dropped our authority from ProviderChangeReceiver's manifest filter while the provider was still the store, and renamed StorageMode.LOCAL to OWN four phases before OWN meant Room. Both moved to phase 5. Parity against the provider was overclaimed: the provider materialises one occurrence, so multi-occurrence expansion has nothing to compare against and is tested against RFC 5545 directly. The phases sum to 6.5-7 weeks, not the 6-6.5 stated, and the difference from STORAGE-DECISION.md's 4.5-6 is now explained rather than left as a contradiction. Gaps closed: WAL vs Auto Backup (checkpoint on ON_STOP, sidecars in the backup rules, tested in phase 6), cascade rules for master_id and parent_id, Instant type converters, a rollback path that re-runs the import from tasks.db.imported, the release note for dropping the authority and its permissions, and ICalendarWriter.uidFor's synthesis branch becoming External-only. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Agendula — documentation
Agendula is a Material 3 Expressive task app for Android. It carries its
own task store — the dmfs task provider vendored under our own authority — so
it is complete and local-first with nothing else installed; an external provider
(OpenTasks / tasks.org, synced by DAVx5 / SmoothSync / DecSync) is a user choice
rather than a requirement, and our own CalDAV sync is the 1.x arc. Sibling to
Calendula. See the
top-level ../README.md for the project pitch.
Index
| Doc | What it covers |
|---|---|
ARCHITECTURE.md |
How Agendula is built today — layers, the data seam, provider resolution, the reminder engine, DI, build/tooling, manifest. Start here to work on the code. |
ROADMAP.md |
Status and what's next — milestones (M0–M6 + Posture B), what's done, open decisions, how to build/verify. |
STORAGE-AND-SYNC.md |
Where task data lives — the decision to ship our own provider, the storage modes, permissions, distribution, and the dead ends. Supersedes PLAN.md on storage. |
SYNC.md |
How data reaches a server — the CalDAV sync adapter: the VTODO ↔ TaskContract mapper, Nextcloud sign-in, the engine, libraries and their licenses. Step 5 of STORAGE-AND-SYNC.md. |
STORAGE-DECISION.md |
Keep the vendored provider, or build our own? The measured cost of both. Decided: build our own. |
OWN-STORE.md |
Agendula's own Room store — the schema, recurrence design, migration off the vendored provider, and the six-phase plan that deletes :provider. Supersedes the "keep the provider" position in STORAGE-AND-SYNC.md. |
PLAN.md |
The original implementation plan and design rationale — the A-now-B-later thesis, what transfers from Calendula, the locked decisions. The "why". |
RELEASING.md |
How to cut a release — the git-tag-as-source-of-truth flow, CI jobs, F-Droid repo, required secrets. |
../provider/PROVENANCE.md |
What the vendored :provider module is, where it came from, and every deviation from upstream dmfs. |
Also: ../CHANGELOG.md (Keep a Changelog format; tag sections
feed the release notes).
How the docs relate
- PLAN is the original design decisions (the "why"), left as the historical record. On storage it is superseded by STORAGE-AND-SYNC.
- STORAGE-AND-SYNC and SYNC are the standing decision documents: the first settles where data lives, the second how it syncs. Both record rejected alternatives on purpose, so decisions don't get relitigated.
- ARCHITECTURE is the current shape of the code (kept in sync with the source as it grows).
- ROADMAP is the moving status layer (update as milestones land).
- RELEASING is the operational runbook.