The File Lifecycle
Every task is a Markdown file with YAML frontmatter. Here’s what happens from creation to completion.
┌─────────────────────────────────────────────────────┐│ CREATE ││ New .md file with YAML frontmatter + content │└─────────────────┬───────────────────────────────────┘ │ ▼┌─────────────────────────────────────────────────────┐│ ACTIVE ││ Task visible in app, grouped by scheduled date ││ Status: active │└─────────────────┬───────────────────────────────────┘ │ ┌───────┴───────┐ ▼ ▼┌─────────────────┐ ┌─────────────────┐│ COMPLETED │ │ ARCHIVED ││ status: done │ │ status: arch. ││ Shows in │ │ Hidden from ││ Wrapped group │ │ all views │└─────────────────┘ └─────────────────┘Creating a Task
When you create a task in Daylight, it writes a Markdown file:
---title: Review pull requeststatus: activecreated: 2026-01-28scheduled: 2026-01-28tags: - work - code-reviewproject: Backend API---
Check the auth changes in PR #142.Look for edge cases in token refresh.The file lives in your chosen task folder. Daylight watches that folder and reloads when files change.
Editing Tasks
Changes in the app write directly to the file. Changes to the file (from any editor) appear in the app when Daylight reloads.
You can edit the YAML frontmatter in VS Code, and Daylight will reflect those changes. The file is the source of truth.
Completing Tasks
Completing a task changes status: active to status: completed. The file stays in the same folder—only the status field changes.
Completed tasks appear in the Wrapped group for the rest of the day, then hide from default views.
Archiving Tasks
Archiving sets status: archived. The file stays in place but disappears from all views. Archive is soft-delete—the file still exists, and you can restore it by changing the status back.
Smart Grouping
Daylight organizes tasks into four groups based on their relationship to today:
| Group | Shows tasks where… |
|---|---|
| Past | scheduled < today AND status = active |
| Now | scheduled = today (or no scheduled date) AND status = active |
| Upcoming | scheduled > today AND status = active |
| Wrapped | status = completed AND completed today |
How It Works
- Daylight reads all
.mdfiles in your task folder - Parses the YAML frontmatter to get
scheduledandstatus - Compares
scheduledto today’s date - Places each task in the appropriate group
No manual sorting. No priority algorithms. Just date math.
Tasks Without Scheduled Dates
If a task has no scheduled field, it appears in Now. The assumption: if you haven’t scheduled it, it’s available for today.
Recurring Task Instances
For recurring tasks, each instance appears in its appropriate group:
- Past instances (not yet completed) appear in Past
- Today’s instance appears in Now
- Future instances appear in Upcoming
Sync
Daylight doesn’t sync—your file sync tool does. This is intentional.
The Model
┌─────────────┐ Syncthing ┌─────────────┐│ Phone │ ←───────────────→ │ Laptop ││ ~/Tasks/ │ │ ~/Tasks/ │└─────────────┘ └─────────────┘Each device has a complete copy of your tasks. Syncthing (or Dropbox, or whatever you use) handles synchronization.
Setup
- Install Syncthing on all your devices
- Create a shared folder for tasks
- Point Daylight to that folder on each device
That’s it. When you create or edit a task, Syncthing propagates the change to other devices.
Why BYO Sync?
- No server to maintain — Syncthing is peer-to-peer
- You control the sync — Choose what syncs, when, and where
- No vendor dependency — Syncthing is open source; so is Dropbox sync, iCloud, etc.
- Privacy by architecture — Your tasks never pass through our servers (we don’t have servers)
Conflicts
Conflicts happen when the same file is edited on two devices before they sync. Syncthing handles this by creating a conflict file.
What a Conflict Looks Like
Tasks/├── weekly-review.md ← Current version└── weekly-review.sync-conflict-20260128.md ← Conflicting versionDaylight sees both files as separate tasks. You’ll notice a duplicate.
Why Conflicts Happen
- Offline edits: You edit on your phone, your laptop is asleep, you edit on your laptop before they sync
- Simultaneous edits: Two devices edit the same task faster than sync can propagate
- Recurring tasks: Two devices complete the same instance before sync
Resolving Conflicts
- Find the conflict file (look for
.sync-conflict-in the filename) - Open both files—compare what’s different
- Keep the version you want, delete the conflict file
- Wait for sync to propagate
It’s a 30-second fix. The benefit: you always know what happened, nothing is silently lost.
Best Practices to Avoid Conflicts
- Let Syncthing finish before switching devices
- Complete tasks on one device (phone or laptop, not both)
- Check sync status before editing recently-changed tasks
Recurring Tasks
Recurring tasks use the iCalendar RRULE standard—the same format your calendar uses.
How It Works
recurrence: rule: FREQ=WEEKLY;BYDAY=FR instances: - date: 2026-01-24 status: completed - date: 2026-01-31 status: activeThe rule defines the pattern. The instances array tracks each occurrence with its own status.
Instance-Based Tracking
When you complete a recurring task, Daylight marks that specific instance as completed. Other instances are unaffected.
- Complete Friday’s instance → Friday is done, next Friday still shows
- Skip an instance → It’s marked skipped, series continues
- Reschedule an instance → That instance moves, others stay put
Why This Matters
Most apps track recurrence as “next date”—they just bump the date forward when you complete. This causes problems:
- Complete early? You might skip the next occurrence
- History? Often lost or limited
- Reschedule one? Might move the whole series
Instance-based tracking eliminates these issues.
Time Tracking
Daylight tracks time with manual entries, not timers.
How It Works
time_entries: - date: 2026-01-28 duration: 45 notes: Initial review - date: 2026-01-28 duration: 30 notes: Follow-up questionsEach entry has a date, duration (in minutes), and optional notes. Add entries whenever you want—during work, at the end of the day, or retrospectively.
Why No Timers?
Timers assume uninterrupted work. In reality:
- You start a timer, get interrupted, forget to stop it
- Timer runs for 4 hours while you did 45 minutes of actual work
- Timer state needs to persist across app restarts and device switches
Manual entry captures what actually happened. At the end of a work session, you know how long you worked better than a timer does.
15-Minute Snapping
Daylight snaps to 15-minute increments by default. “About 45 minutes” becomes 45. This makes entry fast while maintaining useful precision.
Edge Cases
What happens when…
| Scenario | Behavior |
|---|---|
| Task file is edited externally | Daylight reloads on next app focus |
| Task file has invalid YAML | Task doesn’t appear; fix the YAML, it comes back |
| Task folder is empty | Empty state shown; create your first task |
| Syncthing isn’t running | Everything still works locally; sync happens when Syncthing starts |
| Task scheduled for past date | Appears in Past group until completed |
| Recurring task rescheduled to future | Past instances hide; future instances show |
| Large task files (>1MB) | Works but slower; consider splitting notes |
Data Flow Summary
Read: Folder → Parse YAML → Build groups → Render UI
Write: User action → Update YAML → Write file → Syncthing picks up change
Sync: Syncthing detects change → Propagates to other devices → Daylight reloads
The file is always the source of truth. The app is just a nice way to read and write it.