Files
agendula/docs
makiolaj b25f8b231c sync(chunk 4): incremental sync and scheduling
RFC 6578 as an optimisation on top of chunk 3's full path, and sync that runs
by itself.

- :caldav gains sync-collection, with invalidation matched on
  DAV:valid-sync-token in the body on any 4xx rather than on a status code —
  400, 403, 409 and 412 are all used in the wild, and matching the status is
  why Thunderbird never recovers from sabre's 403. No DAV:limit (Nextcloud
  regressed it to an HTML error page); 507 on our own href is truncation.
- The engine persists the token per page, after the bodies. An iteration cap
  and a no-progress guard, since the RFC never requires the token to advance.
  The full path runs anyway every 24h: a token the server accepts over a
  pruned change log returns 207, zero changes and no error, and the protocol
  gives no other way to notice.
- The three membership traps: an unknown removed href is a no-op, a
  delete-then-recreate is re-identified from the UID in the body, and a mass
  removal is refused in favour of a real listing, because ACL churn looks
  exactly like one.
- Scheduling is a PeriodicWorkRequest with a network constraint, expedited
  only for the in-app button. getForegroundInfo is implemented unconditionally
  (setExpedited falls back to a foreground service below API 31 and the
  default throws) but declares no service type, which would have pulled back
  the Android 15 dataSync budget and a Play video-demo requirement.

initialIncomplete turned out not to be needed: adopting a token only after a
full reconciliation completes removes the hazard it guarded, so there is
nothing to persist atomically with anything.

/code-review high raised 8 findings, all fixed. The two that mattered: the
cadence clock sat in the backed-up DataStore, so a restore would have made the
engine trust a stale token for a day — both sync-state stores now have their
own excluded file; and the incremental download path lacked the write-phase
guard, overwriting local edits that had never reached the server. Reasoning in
docs/SYNC-PLAN.md.

Chunk 2's on-device review is still outstanding; none of this has run on a
device or against a real server.
2026-09-07 16:18:09 +02:00
..

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.