# 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 ```