The horizon window determines how early a temporal task starts surfacing.
baseCost = relativeCost x durationMinutes x personalCoefficient x 0.5typicalPool = 30-day median of poolEwmahorizonDays = clamp(ceil(baseCost / (typicalPool x 0.30)), 2, 7)
Task cost as % of typical pool
Horizon window
< 30%
2 days
30-60%
2-3 days
60-90%
3 days
90-120%
4 days
120-180%
4-5 days
180%+
6-7 days
When inside horizon window:
Task becomes visible regardless of remaining pool
Card uses horizon framing copy
Scheduled tasks contribute to pre-warning logic
For deadline-window tasks, horizon visibility makes the task actionable because the work can happen before the due time. For appointment tasks, horizon visibility is a preview only until the appointment day.
Surfacing rules are policy-driven. The defaults below are the recommended profile, but teams should treat visibility behavior as user-configurable and wire those choices into onboarding.
if timingType == 'deadline': if dueDatetime < now and state == 'active': surface as carried-over/actionable elif today == dueDatetime.localDay: surface as due-today/actionable elif today >= dueDatetime - horizonDays: surface as actionable with pool exemption else: standard surfacing (cost <= remainingPool)
if timingType == 'scheduled': if today == dueDatetime: surface as active/completable elif dueDatetime < now and state == 'active': surface as needs-update/actionable elif today >= dueDatetime - horizonDays: surface with horizon framing, not completable else: hidden
The snippet above reflects default policy values. If onboarding preferences differ, the surfacing layer applies the selected policy at runtime.
Temporal surfacing is consumed by feature-sliced app surfaces:
Home projection and sections (app/lib/features/home/presentation/widgets/home_screen.dart)
Tasks list (app/lib/features/tasks/presentation/widgets/tasks_screen.dart)
Orchard list for orchard-tagged surfaced tasks (app/lib/features/orchard/presentation/widgets/orchard_screen.dart)
Mana notices and reserve/conflict messaging (app/lib/features/mana/)
The Home IA target is documented in Home Information Architecture. If runtime behavior lags this contract, treat the mana docs here as the product behavior source of truth and capture app changes as implementation follow-ups.Primary surfacing implementation lives in:
due date/time passed without completion; reframed in UI as carried over or needs updating
automatic
cancelled
will not happen / called off
user action
cancelled is available for all task types.There is no overdue state. A passed deadline-window task can remain actionable if it is still relevant, or the user can cancel/archive it. A passed appointment enters a neutral update flow so the user can mark it attended, defer follow-up, or cancel it.
Set state = cancelled on the specific TaskOccurrence
Edit this occurrence only
Set dueDatetimeOverride on the specific TaskOccurrence (shifts effective due time)
Edit this and all future
EXDATE the current slot in the root task’s RRULE; create a new sibling task from that date with the modified rule
Edit all recurring tasks in the series
Update the root task recurrence definition for the full series
dueDatetimeOverride takes precedence over dueDatetime for all scheduling and surfacing calculations. It does not change the occurrenceKey (which is still keyed to dueDatetime).EXDATE lines are stored in the task’s recurrenceRule field alongside DTSTART and RRULE: