Some key philosophies:
- Manage tasks, not calendar
- Context switching is expensive
- Tasks don't commute
As a MVP, user would be interacting with the scheduler through a REPL-like console. Fundamentally, the whole system consists of three parts
- A scheduler which schedules atomic tasks using Google's CP-SAT solver.
- A prediction model which predicts the probability a given task will complete at different times. The result will be used by the scheduler to predict the length of less obvious tasks and schedule accordingly.
- A frontend that compiles tasks (e.g. recurring tasks, grouped tasks, or even sleep schedules) and their relevant constraints into atomic tasks alongside their constraints, which are fed into the scheduler. And render the scheduled atomic tasks back into beautiful schedules user can understand.
So the first step is to implement the last part, the compiler. To facilitate development, we should simplify things further by ignoring the console part for now and focus entirely on compiling into atomic tasks.
For the moment, we should support a few essential task types only
step: an atomic task.- It can either be completed or not completed.
- It can have a deadline and dependencies on other tasks (either
goalorstep). This is implemented throughbeforeandafterlists. - It can be recurring with a frequency (much like systemd timer) but also allows manual overriding (e.g. I want to skip gym this Friday for Amy's birthday party).
- recurrence can be
indefinite,until. - when having both recurrence and deadline, usually we should ask user to set a relative deadline (however, it would be nice to have a way to override certain occurrences).
- recurrence can be
- It can have
priority? A simple priority implementation will be assign a bigger coefficient to the early/late deadline reward/penalty - It can have tags
goal: a task that consists of listOf (steporgoal)- A
goalis complete iff. all subtasks within it are completed. - It can also have a deadline. The deadline is enforced by setting all leaf steps deadline by
min(leafDDL, goalDDL)(essentially another merging, but with merging priority based on DDL itself instead of distance to the leaf node, so no overriding from child). - It can be set as recurring, the behaviour is that it sets a "default" frequency for all leaf nodes with merging priority depending on how far the
goalis from thestep. The final frequency is a result of merging these frequencies based on priority. This allows, for example, user to set a recurring big task but with some small steps that only need to be done once. - It can have tags, they will serve as the default tags for children, and feature a merging behaviour like above.
- A
On scheduling, the compiler will compile all atomic tasks that needs to occur before a given time. By needs to occur, we mean
- all tasks without a deadline will be included.
- recurring tasks with a given frequency would be expanded using time and frequency.
Can goal be implemented through the dependencies resolution engine entirely?
https://docs.skedpal.com/board/using-the-board the board prioritization in skedpal seems like a good design
skedpal dependency management seems like a mess to use.
Our priority now is to create an easy to interface text-based todolist format (not exactly YAML) so that tasks are easy to create/split etc.
And figure out how to enforce time mask (hard/soft mask? how to reconcile with existing ideas?)
- Timezone support (default to default-timezone specified by user, don't use machine timezone or UTC if user didn't specify, error instead)
- Allow importing bg from a calendar subscribe.
- Add
afterkeyword to tasks so I can specify e.g. do it after Friday 13:00 - Testing