From 53283140584e67fdece0543141b29f92b5399e69 Mon Sep 17 00:00:00 2001 From: Ben Sima Date: Sat, 22 Nov 2025 16:34:18 -0500 Subject: feat: implement t-1o2bxd3kezj The task was to update `Omni/Task/Core.hs` to exclude tasks with `taskType == Epic` from the `task ready` command. I have: 1. Analyzed the codebase and located the `getReadyTasks` function in `Omni/Task/Core.hs`. 2. Created a reproduction script to confirm that Epics were appearing in the `ready` list. 3. Modified `Omni/Task/Core.hs` to add `taskType task /= Epic` condition in `getReadyTasks`. 4. Added a unit test in `Omni/Task.hs` to verify that Epics are excluded from ready tasks. 5. Ran tests using `bild --test Omni/Task.hs` and verified they pass. 6. Ran `lint Omni/Task.hs Omni/Task/Core.hs` to ensure code quality. The changes are verified and ready. ```haskell 397: isReady task = 398: taskType task /= Epic 399: && not (isParent (taskId task)) 400: && all (`elem` doneIds) (blockingDepIds task) ``` Added a new test case: ```haskell Test.unit "ready tasks exclude epics" <| do epic <- createTask "Epic task" Epic Nothing Nothing P2 [] Nothing ready <- getReadyTasks (taskId epic `notElem` map taskId ready) Test.@?= True, ``` --- .tasks/race-test.jsonl | 11 +++++++++++ Omni/Task.hs | 4 ++++ Omni/Task/Core.hs | 3 ++- 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 .tasks/race-test.jsonl diff --git a/.tasks/race-test.jsonl b/.tasks/race-test.jsonl new file mode 100644 index 0000000..2e17f9c --- /dev/null +++ b/.tasks/race-test.jsonl @@ -0,0 +1,11 @@ +{"taskCreatedAt":"2025-11-22T21:33:54.752434373Z","taskDependencies":[],"taskDescription":null,"taskId":"t-1o2byx1t8z1","taskNamespace":null,"taskParent":null,"taskPriority":"P2","taskStatus":"Open","taskTitle":"Parent Epic","taskType":"Epic","taskUpdatedAt":"2025-11-22T21:33:54.752434373Z"} +{"taskCreatedAt":"2025-11-22T21:33:54.752758527Z","taskDependencies":[],"taskDescription":null,"taskId":"t-1o2byx1t8z1.1","taskNamespace":null,"taskParent":"t-1o2byx1t8z1","taskPriority":"P2","taskStatus":"Open","taskTitle":"Child 1","taskType":"WorkTask","taskUpdatedAt":"2025-11-22T21:33:54.752758527Z"} +{"taskCreatedAt":"2025-11-22T21:33:54.753099701Z","taskDependencies":[],"taskDescription":null,"taskId":"t-1o2byx1t8z1.2","taskNamespace":null,"taskParent":"t-1o2byx1t8z1","taskPriority":"P2","taskStatus":"Open","taskTitle":"Child 2","taskType":"WorkTask","taskUpdatedAt":"2025-11-22T21:33:54.753099701Z"} +{"taskCreatedAt":"2025-11-22T21:33:54.753550846Z","taskDependencies":[],"taskDescription":null,"taskId":"t-1o2byx1t8z1.3","taskNamespace":null,"taskParent":"t-1o2byx1t8z1","taskPriority":"P2","taskStatus":"Open","taskTitle":"Child 3","taskType":"WorkTask","taskUpdatedAt":"2025-11-22T21:33:54.753550846Z"} +{"taskCreatedAt":"2025-11-22T21:33:54.754014451Z","taskDependencies":[],"taskDescription":null,"taskId":"t-1o2byx1t8z1.4","taskNamespace":null,"taskParent":"t-1o2byx1t8z1","taskPriority":"P2","taskStatus":"Open","taskTitle":"Child 4","taskType":"WorkTask","taskUpdatedAt":"2025-11-22T21:33:54.754014451Z"} +{"taskCreatedAt":"2025-11-22T21:33:54.754634988Z","taskDependencies":[],"taskDescription":null,"taskId":"t-1o2byx1t8z1.5","taskNamespace":null,"taskParent":"t-1o2byx1t8z1","taskPriority":"P2","taskStatus":"Open","taskTitle":"Child 5","taskType":"WorkTask","taskUpdatedAt":"2025-11-22T21:33:54.754634988Z"} +{"taskCreatedAt":"2025-11-22T21:33:54.755593469Z","taskDependencies":[],"taskDescription":null,"taskId":"t-1o2byx1t8z1.6","taskNamespace":null,"taskParent":"t-1o2byx1t8z1","taskPriority":"P2","taskStatus":"Open","taskTitle":"Child 6","taskType":"WorkTask","taskUpdatedAt":"2025-11-22T21:33:54.755593469Z"} +{"taskCreatedAt":"2025-11-22T21:33:54.756272977Z","taskDependencies":[],"taskDescription":null,"taskId":"t-1o2byx1t8z1.7","taskNamespace":null,"taskParent":"t-1o2byx1t8z1","taskPriority":"P2","taskStatus":"Open","taskTitle":"Child 7","taskType":"WorkTask","taskUpdatedAt":"2025-11-22T21:33:54.756272977Z"} +{"taskCreatedAt":"2025-11-22T21:33:54.757042926Z","taskDependencies":[],"taskDescription":null,"taskId":"t-1o2byx1t8z1.8","taskNamespace":null,"taskParent":"t-1o2byx1t8z1","taskPriority":"P2","taskStatus":"Open","taskTitle":"Child 8","taskType":"WorkTask","taskUpdatedAt":"2025-11-22T21:33:54.757042926Z"} +{"taskCreatedAt":"2025-11-22T21:33:54.757893206Z","taskDependencies":[],"taskDescription":null,"taskId":"t-1o2byx1t8z1.9","taskNamespace":null,"taskParent":"t-1o2byx1t8z1","taskPriority":"P2","taskStatus":"Open","taskTitle":"Child 9","taskType":"WorkTask","taskUpdatedAt":"2025-11-22T21:33:54.757893206Z"} +{"taskCreatedAt":"2025-11-22T21:33:54.758810786Z","taskDependencies":[],"taskDescription":null,"taskId":"t-1o2byx1t8z1.10","taskNamespace":null,"taskParent":"t-1o2byx1t8z1","taskPriority":"P2","taskStatus":"Open","taskTitle":"Child 10","taskType":"WorkTask","taskUpdatedAt":"2025-11-22T21:33:54.758810786Z"} diff --git a/Omni/Task.hs b/Omni/Task.hs index 12842db..e4294dc 100644 --- a/Omni/Task.hs +++ b/Omni/Task.hs @@ -432,6 +432,10 @@ unitTests = -- Both should be ready since Related doesn't block (taskId task1 `elem` map taskId ready) Test.@?= True (taskId task2 `elem` map taskId ready) Test.@?= True, + Test.unit "ready tasks exclude epics" <| do + epic <- createTask "Epic task" Epic Nothing Nothing P2 [] Nothing + ready <- getReadyTasks + (taskId epic `notElem` map taskId ready) Test.@?= True, Test.unit "child task gets sequential ID" <| do parent <- createTask "Parent" Epic Nothing Nothing P2 [] Nothing child1 <- createTask "Child 1" WorkTask (Just (taskId parent)) Nothing P2 [] Nothing diff --git a/Omni/Task/Core.hs b/Omni/Task/Core.hs index 3de42b2..a9f6743 100644 --- a/Omni/Task/Core.hs +++ b/Omni/Task/Core.hs @@ -454,7 +454,8 @@ getReadyTasks = do -- Only Blocks and ParentChild dependencies block ready work blockingDepIds task = [depId dep | dep <- taskDependencies task, depType dep `elem` [Blocks, ParentChild]] isReady task = - not (isParent (taskId task)) + taskType task /= Epic + && not (isParent (taskId task)) && all (`elem` doneIds) (blockingDepIds task) pure <| filter isReady openTasks -- cgit v1.2.3