Tasks Integration Architecture¶
Core Contract
The Tasks integration is a cache-subscriber provider that performs surgical markdown I/O. It treats the Obsidian Tasks plugin as its data authority and the EventCache as its synchronization target.
This provider family context is defined in Provider Architecture.
Data Flow & Synchronization¶
Unlike other providers that crawl files directly, the Tasks provider is an event-driven system:
- Subscription: On initialization, the provider subscribes to
obsidian-tasks-plugin:cache-update. - In-Memory Mirroring: It maintains an internal
allTasksarray which is a transformed view of the Tasks plugin's raw cache. - Differential Sync: Every time the Tasks cache updates, the provider performs a granular diff against its previous state and emits batch updates (
additions,updates,deletions) to the globalProviderRegistry.
For cache authority and mutation sequencing, see EventCache Contract.
Surgical Markdown I/O¶
When a user drags a task on the calendar or toggles its completion state, the provider performs Surgical Replacement:
- Targeting: It uses the file path and line number provided by the Tasks cache.
- Injection Logic: It uses regex to inject or update date emojis (
⏳,🛫,📅) and time tokens while preserving:- Task descriptions.
- Existing metadata (created dates, recurrence, etc.).
- Block Links (
^uuid): The regex ensures that injected data is placed before any block links at the end of the line.
Time Format Contract¶
The Tasks integration has an explicit write-format setting:
settings.tasksIntegration.taskDisplayFormatdayPlanner(default): write time at the start of the task line.standard: write parenthesized time near date metadata.
Settings ownership and propagation model: Settings Architecture.
Write behavior¶
For timed tasks, the provider writes one of the following:
- Day Planner range:
- [ ] 5:00 - 19:00 Task title ⏳ 2026-05-02 - Day Planner single:
- [ ] 14:30 Task title ⏳ 2026-05-02 - Standard range:
- [ ] Task title (5:00 AM-7:00 AM) ⏳ 2026-05-02 - Standard single:
- [ ] Task title (14:30) ⏳ 2026-05-02
All-day updates remove time tokens in either format.
Read behavior¶
Parsing is format-agnostic and supports both Day Planner prefix and legacy parenthesized syntax. This means:
- Existing legacy tasks remain fully compatible.
- Newly written day-planner tasks are parsed identically into
startTime/endTime. - No mandatory bulk migration is required for correctness.
Optimistic UI Updates¶
To ensure the calendar feels responsive despite file I/O latency:
1. The provider modifies the markdown file asynchronously.
2. It simultaneously pushes an Optimistic Update to the EventCache with the new expected state.
3. The eventual file change triggers a fresh cache update from the Tasks plugin, which the provider reconciles to confirm the operation.
This follows the canonical mutation path in EventCache Contract.
Date Logic & "No Fallback" Policy¶
The provider enforces a strict mapping policy to maintain data integrity: - Consistency: It only reads from the specific date target configured by the user (Scheduled, Due, or Start). - Reasoning: This prevents "ghosting" where a task appears on the calendar under one date but is tracked in the backlog under another, ensuring a predictable user experience.
Backlog View Filtering Contract¶
Backlog filtering is split by responsibility:
- Provider-level filter (
TasksPluginProvider.getUndatedTasks()): decides which tasks are backlog candidates usingbacklogDateTargetand completion state. - View-level filter (
TasksBacklogView): applies client-side fuzzy filtering over candidate tasks by title and file path.
View-layer boundary reference: Views Architecture.
The view-level fuzzy filter is intentionally non-destructive: it does not mutate provider state and only narrows visible rows in the panel.