# V1 Block 03 — Scheduling Engine

Status: Completed

Purpose: Implement the core behavior that makes this product valuable: flexible tasks move safely without destroying the user's intended order.

## Chunk 3.1 — Define scheduling inputs and outputs

Recommended Codex level: high

Status: Completed with environment blocker noted

Tasks:

Create clear models/functions for scheduling operations:

- Current task list.
- Locked intervals.
- Required visible intervals.
- Flexible intervals/tasks.
- Scheduling window.
- Operation result with changed tasks and notices.

Rules:

- Scheduling functions should be deterministic.
- Avoid direct database access inside the engine.
- Return results; do not hide side effects.

Acceptance criteria:

- Scheduling engine can be called with in-memory data.
- Result object can describe moved tasks and overlaps.
- Tests can assert exact task placement results.

Execution notes:

- Added `SchedulingWindow`, `SchedulingInput`, `SchedulingChange`, and `SchedulingOverlap` models.
- Expanded `SchedulingResult` and `SchedulingNotice` so operation results can report changed task placements, overlap details, and typed notices.
- Added `SchedulingEngine.analyzeSchedule` for deterministic in-memory schedule analysis without moving tasks or touching persistence.
- Added tests for in-memory task grouping, overlap reporting, and exact movement-change representation.
- Initial Dart verification was blocked while the SDK was unavailable; after repair, `dart analyze` and `dart test` passed.
- Committed after the repository was initialized and repaired.

## Chunk 3.2 — Insert backlog task into next available flexible slot

Recommended Codex level: extra high

Status: Completed with environment blocker noted

Tasks:

Implement insertion behavior:

- A backlog item can be inserted into the soonest flexible slot where it fits.
- Later flexible tasks shift forward using normal bump rules.
- Locked, inflexible, and critical blocks do not move.
- If no slot exists today, return a clear overflow result.

Acceptance criteria:

- Test: insert 15-minute task into an open 20-minute slot.
- Test: insert task before flexible task and push later flexible task.
- Test: insertion skips locked time.
- Test: insertion does not move inflexible/critical blocks.
- Test: no available slot returns an overflow/no-fit result.

Execution notes:

- Added `SchedulingEngine.insertBacklogTaskIntoNextAvailableSlot`.
- Backlog insertion now requires a flexible backlog task with positive duration.
- The insertion planner schedules the task into the earliest available in-window slot, skips locked/required visible time, and preserves planned flexible task order while pushing affected flexible tasks later.
- Locked, inflexible, critical, and non-planned scheduled flexible intervals are treated as fixed for this operation.
- Successful insertion returns updated tasks, movement notices, and exact `SchedulingChange` records.
- No-fit and overflow cases return the original task list with a typed notice.
- Added tests for open-slot insertion, bumping a later flexible task, skipping locked time, preserving inflexible/critical blocks, and overflow/no-fit.
- Initial Dart verification was blocked while the SDK was unavailable; after repair, `dart analyze` and `dart test` passed.
- Committed after the repository was initialized and repaired.

BREAKPOINT: Stop here. Confirm `extra high` mode before starting this chunk if not already set.

## Chunk 3.3 — Push flexible task to next available slot

Recommended Codex level: extra high

Status: Completed

Tasks:

Implement push behavior:

- `Push -> Next available slot` moves the selected flexible task to the next slot where it fits.
- Later flexible tasks shift forward.
- Preserve order among affected flexible tasks.
- Do not move locked, inflexible, or critical blocks.

Acceptance criteria:

- Test: pushed flexible task moves after current slot.
- Test: downstream flexible tasks are bumped in order.
- Test: locked intervals are respected.
- Test: required items remain fixed and visible.

Execution notes:

- Added `SchedulingEngine.pushFlexibleTaskToNextAvailableSlot`.
- Push requires a planned flexible task with an existing scheduled interval and positive duration.
- The selected task moves after its current slot; downstream planned flexible tasks shift later in their existing order.
- Locked, inflexible, critical, non-planned, and earlier flexible intervals remain fixed or untouched.
- Successful push returns updated tasks, movement notices, and exact `SchedulingChange` records.
- Added tests for moving after the current slot, bumping downstream flexible tasks, respecting locked intervals, and preserving required visible items.
- `dart analyze` and `dart test` passed.

## Chunk 3.4 — Push flexible task to tomorrow top of queue

Recommended Codex level: high

Status: Completed

Tasks:

Implement tomorrow behavior:

- `Push -> Tomorrow` places the task at the top of tomorrow's flexible queue.
- Preserve order among multiple rolled/pushed tasks where applicable.
- Do not require manual scheduling.

Acceptance criteria:

- Test: task receives tomorrow date/queue marker.
- Test: task is before other flexible tomorrow tasks unless required/locked time blocks it.

Execution notes:

- Added `SchedulingEngine.pushFlexibleTaskToTomorrowTopOfQueue`.
- The input scheduling window represents tomorrow's flexible scheduling window.
- The selected planned flexible task is placed in the earliest available tomorrow slot and existing planned flexible tasks in that window shift later while preserving order.
- Locked and required visible time in the tomorrow window remains fixed.
- Successful tomorrow push returns updated tasks, movement notices, and exact `SchedulingChange` records.
- Added tests for tomorrow top-of-queue placement and locked/required blocking behavior.
- `dart analyze` and `dart test` passed.

BREAKPOINT: Stop here. The next chunk drops from high/extra high to medium.

## Chunk 3.5 — End-of-day rollover

Recommended Codex level: medium

Status: Completed

Tasks:

Implement rollover behavior:

- At end of day, unfinished flexible tasks move to tomorrow.
- Rolled tasks go to top of tomorrow's flexible queue.
- Preserve order among rolled-over tasks.
- Produce a small notice such as `3 unfinished flexible tasks were moved to tomorrow`.

Do not roll over:

- Locked blocks.
- Inflexible tasks.
- Critical tasks without explicit missed/backlog handling.
- Cancelled tasks.
- Completed tasks.

Acceptance criteria:

- Tests cover all included and excluded task types.
- Notice text/count is generated.

Execution notes:

- Added `SchedulingEngine.rollOverUnfinishedFlexibleTasks`.
- Rollover moves planned and active flexible tasks that are not already in the tomorrow window.
- Rolled tasks are placed at the top of tomorrow's flexible queue, preserving current order.
- Existing planned flexible tasks in the tomorrow window shift later while preserving order.
- Locked, inflexible, critical, completed, and cancelled tasks remain unchanged.
- Rollover returns exact `SchedulingChange` records and a count notice.
- Added tests for included flexible tasks, excluded task types/statuses, order preservation, downstream tomorrow bumps, and notice count generation.
- `dart analyze` and `dart test` passed.

Commit suggestion:

```text
feat(scheduling): implement flexible task movement rules
```
