Happy holidays, Christmas for example.

If you’ve only just tuned in, we successfully deployed a distressingly basic notes app to “production”, which is to say it has a domain name and I can access and edit my notes from both my phone and laptop. But as much as I love resting on laurels, we should probably make some progress towards the goal of making the mother of all todo list apps.

Let’s immediately sidetrack this goal with:

Market research

At Christmas lunch I talked to my cousin, who is developing an indie game, and asked how he does his project management. Some dot points:

  • Uses a complex system for himself and simplified interface when working with other people
  • Todo list has a flat hierarchy of tasks to be completed in order
  • Task dependencies/parallel work handled by simply doing everything himself
    • Collaborators primarily for art assets – character design, music
    • So not generally blocking – synchronous meetups can be arranged
    • Main dev work generally not easily parallelisable, I assume
    • Does not expect collaborators to have to deal with unfamiliar tools e.g. Vikunja
  • Timeline mainly oriented around giving a demo in $MONTH
    • Tasks tagged in Vikunja with how critical they are for the demo
    • Unclear how time estimates being made – presume it’s more fine-grained in near term, coarse-grained in far term
      • Time estimates very difficult in something as open-ended as game development
        • Progress contingent on if playtesters like something or not, for example
          • Could maybe model as tasks having random chance of success? probability distribution?
            • But then how do you assign probabilities?
      • Sounds daunting! Wishing him the best of luck!

I also dug up a Mastodon post from @futurebird@sauropods.win that I had bookmarked that presents some hypothetical prompts from a digital assistant for a project management app. I would really like to integrate something like this into my app at some point; mental hygiene is super important when staying on tasks, as experience has taught me. Will have to revisit this.

We now resume your regularly scheduled programming!

Adding tasks to my notes app so that it’s a todo list app

Before Project Croissant was a web app, it was a command-line prototype, and one of the core ideas was that task lists were simple text files that could be edited with a text editor. I had come across the plain text [1] todo.txt file format (main website) a while ago and found it promising. However, I wanted tasks to be able to be automatically scheduled around a user’s calendar events, and have some sense of dependency on each other (e.g. Task X must be completed before Task Y), so I extended the format slightly. A brief overview:

  • Indentations indicate subtasks, subtasks inherit parent properties
  • Sequences of dashed (-) items are to be completed in order (in series)
  • Sequences of asterisked (*) items can be completed out of order (in parallel)
  • “dur:” tag indicates duration
  • “due:” tag indicates due date (or datetime) in ISO 8601 format (or human-understandable time)
  • Special due dates:
    • ASAP: task takes priority over all other tasks. Can be destructive, use sparingly
    • SPC: “soonest possible convenience”: task should be scheduled to be done at the earliest possible time that does not prevent any tasks with due dates not being completed before their deadlines
  • Lines beginning with octothorpes (#) are comments, not tasks
  • #NONCRIT tag can be included in an item to indicate a task is noncritical (i.e. optional if not enough time)
  • Replace a line’s prefix symbol with an ‘x’ to indicate it is completed

I think it’s easier to understand by example. Here’s what a university student’s personal finance task list might look like:

* (B) Sort out tutoring payments due:SPC
  - Make sure I've been paid for last term of tutoring and that hours are correct
    - Copy last term's spreadsheet from old laptop dur:5m
    - Extract bank statements, enter data into spreadsheet dur:5m
    - Log onto timesheet app, enter data into spreadsheet dur:10m
    - Confirm everything in order dur:10m
  - Transfer funds between accounts
    # Make sure I'm getting bonus interest on savings acct?
* (B) Buy stocks (index ETFs) due:SPC
- (C) Figure out next steps for managing personal finance due:SPC
  # goal: $600 a week?
  # buy X amount of stocks every (week? fortnight?)
  # charity donations?

“Sort out tutoring payments” and “Buy stocks” can be done in parallel, but both need to be completed before “Figure out next steps”.

Work on a larger, more complex project might look like:

* Mainline tasks 
  - Complete Milestone 2 due:2024-09-30T18:00 
    - Framework for non-blocking system calls and I/O (i.e. kernthread) 
      x open() 
      * close() 
      x read() 
      x write() 
      x sleep() 
      * gettime() 
    - Submit code
  - Milestone 2 postmortem and resolutions due:SPC 
    - How can we stay on track, allocate work, conduct work, raise issues if we encounter any, check in regularly 
      # Have a project management table like this; check in regularly 
  - Complete Milestone 3 due 2024-10-04T18:00 
    - Make task breakdown and allocate work
    - Implement a proper page table for the user process 
      # Right now, we map in a single Frame for the stack (mapping.c:map_frame()) and hope we don't use more than 4KiB for the stack I guess 
      - Research and decide on what type of page table to use dur:1h? 
        # Is mirroring the hardware page table a bad idea somehow? Hashed page table mentioned as one possibility? Must not be a single-level one (LOL) 
        # Decided on just doing this – see Discord logs 
      - Create a data structure for this page table dur:1h 
    - Write a new frame mapping function (in mapping.c??) such that it uses this new page table dur:1.5h 
      # Spec says to make our own version but not necessarily replace the current version? Might be helpful to identify and track all current instances of map_frame()? 
    - Add page fault handler, wherever that goes dur:1.5h 
* Noncritical tasks #NONCRIT 
  x Move sections of main.c into own source files/libraries 
    * Consolidate user_process and per-process items into something like a proc.c due:2024-11-01
      # need to do before milestone 6
  x Avoid dropping bytes in network buffer 
  x Make sure read()ing console twice (from same process) doesn't deadlock 
    # File-specific open() method? vfs_open()? 
  x Make sleep() and read() yield their kernel timeslices rather than busy-wait 
  x Get callback framework working? Diagnose why it hasn't been working 
  x Fix sos_read not stopping at '\n' 
  x Fix leaking reply cap on sleep 
  * Free nfs data after use 
  * change to use posix flags internally 
  * Use guard typing for user addresses 
  * Get benchmarking toolchain set up locally and get familiar with it 
  * Improve system calls 
  * Proper testing of all our stuff (hmm very specific) 
  * Keep track of data overhead and performance – open a performance/benchmarking logbook? 
  x Bitstuff the page table entries 

Maybe this is overcomplicating things, but all the extra features provide information that an automatic scheduler would really like to work with, so I felt they were necessary to include in the prototype (which had primitive automatic task scheduling).

On one hand, this is a very anti-web app user interface pattern. It requires the user to learn how to format a file a specific way, which is something you typically only want to get a programmer to do, and even they don’t like having to do it sometimes. Just let me push buttons and fill out clear forms! But for people who are very comfortable with text formatting, having a todo list in a format like can be nice because editing it just requires simple and natural text editing operations, like indenting sections and moving lines around and updating numbers on a given line. Even then, operations that should be instant, like marking an item complete, have quite a bit of friction. And the second example above does look somewhat intimidating.

My compromise, for now, is to have both views of the same task list. Users can edit the todo.txt-esque “source” of the task list directly, or just interact with a simplified, “rendered” interface. If the rendered interface gets good enough, we can deprecate the source editing, maybe with an obscure option in settings to re-enable it.

Focus, damn it!

Anyway. Lots of rambling. Here’s the plan:

  • Introduce a Task model into the system
    • Converting back and forth between the state of abstract Tasks and the task text? Making sure state is consistent?
      • System of triggers? Text editing functions?
  • Design a Task frontend component
    • Reusable, so it can appear in the context of the dashboard too
    • Possibly annoying within the constraints of vanilla Django templates
  • Develop the “edit”/”render” workflow
    • Reuse the textual task list parser
  • Test it all out
  • May need to implement actual functionality in the user settings part of the app

Eventually:

  • Rudimentary dashboard – display all tasks across all task lists ordered by due date, priority, duration

Then we’ll move onto fetching calendar data, then scheduling tasks around calendar tasks, and then the real killer feature(s). Onwards and upwards!

Footnotes

[1] There is no such thing as plain text. I mean UTF-8. Please read Joel’s article on this.