# 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: `scheduledStart` and `scheduledEnd` represent 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 `createdAt` only as
  a documented temporary baseline for staleness markers.
- Last modification time: `updatedAt` means 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:

1. Explicit task override.
2. Configured project default.
3. 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:

1. Task reminder override, if present.
2. Project configured reminder profile.
3. 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 `pushed` or `skipped` to `TaskStatus` to 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.
