6.6 KiB
V1 ADR 001: Lifecycle, Metadata, and Reminder Semantics
Status: Accepted during Block 11.2
Date: 2026-06-24
Context
The human product specification lists planned, completed, missed,
cancelled, no longer relevant, backlog, skipped, and pushed under task
status. The current backend model exposes durable TaskStatus values for
lifecycle state and uses statistics/scheduling results for movement history.
V1 needs one durable meaning per field before later chunks add stronger validation, activity records, application use cases, and persistence codecs.
Decision
V1 durable task lifecycle states are:
planned: queued or placed work that has not started.active: work currently in progress.completed: work finished by the user.missed: work that did not happen in its intended time and remains as missed history.cancelled: work that was expected but intentionally will not happen.noLongerRelevant: work dismissed because circumstances changed.backlog: unscheduled work kept for later planning.
pushed is not a durable task lifecycle state. It is an activity/movement event
recorded through scheduling changes, Block 13/14 activity records, and counters such
as manuallyPushedCount, autoPushedCount, movedToBacklogCount, and
restoredFromBacklogCount.
skipped during burnout is not a V1 lifecycle state. V1 may keep compatible
statistics and schema fields such as skippedDuringBurnoutCount, but the
overwhelm shield and burnout catch-up workflow remain V2 work.
Task Type Semantics
| Task type | V1 lifecycle behavior |
|---|---|
| Flexible | planned and active tasks may be moved by scheduling operations. completed records completion. missed means the intended slot was not used; recovery actions may reschedule it as planned or move it to backlog. cancelled and noLongerRelevant remove it from active planning. |
| Critical | Required visible commitment. Automatic flexible scheduling must not move it. If missed, V1 records a missed event and places the task in backlog so it remains actionable. The backlog status is the durable current state; missed history is recorded in activity/stat metadata. |
| Inflexible | Required visible time-bound commitment. Automatic flexible scheduling must not move it. If missed, it remains missed in its original planned interval as historical context. |
| Locked | Scheduling constraint, not a normal task card. Locked time should normally be represented by locked-block models and overlay read models. If imported as a task-shaped item, it should not receive normal flexible or required task actions. |
| Surprise | Unplanned completed work logged after the fact. It is created as completed. If it has an interval, that interval is actual occupied time and later same-day scheduling must not ignore it. |
| Free Slot | Protected intentional rest. It blocks automatic flexible placement and normal flexible reminder directives. Explicit critical or inflexible commitments may conflict with it, but automatic scheduling must not silently move the free slot. |
Time and Metadata Fields
The following meanings are reserved for V1:
- Planned placement:
scheduledStartandscheduledEndrepresent where work or a visible commitment is planned on the schedule. - Actual work time: actual start/end must be represented by a distinct actual
interval, added in Block 12/13. It must not be inferred from
updatedAt. - Completion time: completion timestamp must be represented by a distinct
completion field, added in Block 13. It must not be inferred from
updatedAt. - Backlog-entry time: backlog age must use a distinct backlog-entered timestamp
once added in Blocks 13/15. The current starter model uses
createdAtonly as a documented temporary baseline for staleness markers. - Last modification time:
updatedAtmeans only "last domain-level change". It is not a proxy for backlog entry, completion, actual work, or missed time.
Current surprise-task logging stores the known surprise interval in the existing schedule interval fields so the baseline scheduler can repair overlaps. Block 12 must split actual occupancy from planned placement and preserve surprise occupancy for later same-day operations.
Project Defaults, Learned Suggestions, and Task Overrides
These are separate concepts:
- System defaults are hard-coded fallback values such as inbox project,
medium priority,
RewardLevel.notSet, and gentle reminders. - Configured project defaults are user/project settings stored on
ProjectProfile, such as default priority, reward, difficulty, duration, and reminder profile. - Learned suggestions are non-blocking recommendations with provenance and confidence. They never silently overwrite configured project defaults.
- Task overrides are explicit task-level choices that win over project defaults for that task.
Effective value resolution for future configurable fields is:
- Explicit task override.
- Configured project default.
- System default.
Learned suggestions may be shown as suggested values at creation or cleanup time, but they do not become effective values unless the user accepts them as a task override or configured project default.
Reminder Policy Boundary
Reminder delivery through operating-system, background, or notification services is outside the pure Dart core.
The backend/core may compute reminder policy inputs and directives:
- task-level reminder override, added in Block 13;
- configured project reminder profile;
- effective reminder profile resolver;
- free-slot suppression directive for normal flexible reminders;
- clear conflict/interrupt directives for critical and inflexible commitments.
Effective reminder profile resolution is:
- Task reminder override, if present.
- Project configured reminder profile.
- System default
ReminderProfile.gentle.
Free-slot suppression is not a reminder profile. It is a scheduling/rest policy
directive that can suppress normal flexible reminders during protected rest.
Block 13 implements these pure-core decisions through ReminderPolicyService
and typed ReminderDirective values without adding platform notification
delivery.
Consequences
- Later chunks must not add
pushedorskippedtoTaskStatusto make the human status list symmetrical. - Movement, restore, skip, and push operations need idempotent activity/stat records in Block 13/14.
- Block 12 must treat actual surprise occupancy as occupied time independent of planned placement.
- Blocks 13 and 15 must add explicit metadata and document mappings instead of
overloading
updatedAt. - V1 keeps the V2 burnout vocabulary compatible in stats/schema only and does not implement shield or catch-up workflows.