DRAFT: Nannybot Replacement for Zeno Polling

By: dreev
Spec level:
Gissue: #TBD

Changelog

2024-08-06: New question about a book brigade use case
2024-06-22: Add open questions
2023-03-21: Add PS about Pareto dominating the status quo
2023-01-14: Original draft

(This is still in flux. See the open questions at the end. Thanks to Christopher Moravec for helping hash this out.)

First, a shamefully confessed opinion: sort threshold (aka panic threshold) was an elegant and practical solution to a lot of problems with trying to run one’s life off one’s Beeminder dashboard! For example, I have a Beeminder goal to solve a Project Euler problem once a month. By the time that goal is noticeable to me on my dashboard — i.e., it’s in the red or orange, or even blue — it’s too late. Project Euler problems often take me a few days of thinking and trying things.

(In the meantime I’ve solved my Project Euler problem via fractional beeminding but the points here stand.)

A goal field for “how long does it take to dispatch a beemergency for this?” is pretty natural and could be practical enough to overcome the Anti-Settings Principle.


1. Quantum and Qtime

Diving in, a goal’s quantum is the least amount you can measure. It’s pretty much the same as display precision (which we call quantum internally) and we can probably generalize that setting for this. Like 1 step for a steps goal or 5 minutes for a music practice goal or 1 Project Euler problem.

So along with quantum we’d add qtime to specify how long you expect a quantum to take. Examples:

(Goals by default can have quantum=1, as they do in the status quo, and qtime 24 hours.)

Having that in place, we can replace zeno polling with something much more useful and less spammy and more nannybotty. You get exactly one reminder per goal such that you’ll finish everything just under the wire, or however close to the wire you like, depending on how conservative you are with your qtimes. No lead days or reminder start time, just one reminder at the right time, on each medium/modality you specify, based on quantum and qtime.

(Which means technically this whole proposal reduces the number of settings! Generalize the existing quantum slightly, add qtime, and kill reminder start and lead days.)

The tricky part is being smart about multiple goals with the same deadline, or deadlines near each other. But it’s not as tricky or as “smart”/magical as it sounds!

  1. At any given time, a goal has an amount of time till it derails and an amount, delta, required by that time. This is standard in the status quo.
  2. Assume delta is rounded conservatively to the nearest quantum. We’re already using conservaround for this.
  3. We alert you when the time to derail (the difference between the deadline timestamp and the current timestamp) is qtime*delta — i.e., there’s just enough time to dispatch the beemergency. We call deadline - qtime*delta the panic time.
  4. But what about two goals with the same deadline, each with 1 unit due and each with a quantum of 1 and qtime of 1 hour? We’d like Beeminder to understand that you generally can’t do those in parallel! They should ideally stack up, gantt-chart-style, or like an auto-waterfall.

2. The Scoochy Algorithm

Start with a list of intervals for each goal: [panic time, deadline] sorted by decreasing deadline. Call the goal with the latest deadline g and let p be g’s panic time. (For multiple goals with the same deadline, break ties in favor of smaller pledges.) For every goal with deadline after p — i.e., its panic interval overlaps g’s — scooch it earlier so its deadline is p. Now goal g is safe — nothing overlaps with it — so remove it from the list and repeat. Goal g is the new goal with the latest deadline. (Again, by breaking ties in favor of smaller pledges we prefer to scooch more expensive goals earlier.)

We keep doing this until every goal is safe in this sense; none of the intervals overlap. (There might be a more direct or off-the-shelf or efficient way to minimally scooch a set of intervals so they don’t overlap — fun puzzle? — but this should work.)

Now just schedule an alert for the goal with the earliest adjusted panic time. When that alert goes out, redo the above algorithm to find the next alert to schedule. Now the user can just get to work on whatever goal they get alerted about and expect to get it done before the next alert comes in. Keep jumping on beemergencies as you’re alerted about them and you’ll never derail! Or work ahead and build safety buffer and try to avoid ever getting panic alerts at all.

Of course the user may still back themself into a corner by not jumping on the alerts. The way that plays out with this algorithm is that it yields one or more panic times in the past. So the alert can just say that. “You’re in the panic period for the following goals…”

Open Questions and TODOs

1. Can we / should we Pareto-dominate the status quo by also zenoing?

We could keep all the nannybot stuff and qtime and gantt-scooching, but also it zenos. Like you find the goal with the soonest panic time, you schedule the reminder, then you temporarily divide that goal’s qtime in half and throw it back in the pool. When the reminder happens, you find the new goal with the soonest panic time. Maybe it’s the same goal with a halved qtime. So schedule it.

I don’t know if I like it but it’s all still a big improvement over each goal zenoing independently and in parallel.

2. How does dashboard sorting work? Does qtime default to 0 or to 24 hours?

We want to sort the dashboard by deadline minus qtime and we want the dashboard to sort normally if you don’t touch any qtimes. And then any time you do choose an explicit qtime, maybe it would be nice for that to sort ahead of anything for which you don’t, if they’d otherwise be tied? But that means the default qtime should be 0, not 24 hours. But for the alerts a default of 24 hours is what makes sense, right? Hmmm.

3. What about a use case where I just want more safety buffer on a particular goal?

In 2024 we did a 9-person book brigade to read Thinking in Bets with a group goal. Everyone was super into it and we got 9 days of safety buffer by the time we finished the first chapter. When I was up next, I worried about being the one to squander that buffer. The natural settings for my quantum and qtime for reading a book are one page and some number of minutes, respectively. Would it be reasonable to abuse this feature and pretend it takes me 9 days to read a page? That would keep the group goal sorted to the top of my dashboard if the safety buffer fell below 9 days. That might do the trick but the wolf-crying would make me nervous.