Picking Your Initial Bright Red Line on Goal Creation

By: bee
Spec level:
Gissue: #1144

Changelog

2021-11-17: Add link to help doc
2020-08-27: Add the dateplus/datediff functions
2020-08-09: Tons of editing

There are two problems with the current goal wizard’s way of asking the user what starting buffer they want.

  1. Users are often surprised — if they pick, e.g., a weekly rate — when they are expected to do something just a day later. (Related reading: blog.beeminder.com/chunky and lots of forum posts and at least one help doc.)
  2. If a user wants to start the goal on a specific date, it’s confusing to figure out how many days of initial safety buffer to request.

The first is the more critical problem — Beeminder seems utterly broken to a lot of people who think they’re picking a “weekly” goal. Fixing the second is icing. Fortunately this spec fixes both!

We also have a hard constraint: Even if a user chooses “0.5 skuzzlewuppers per year”, if they don’t explicitly opt in to start with some initial safety buffer, they’re going to have a beemergency tomorrow of 0.0014 skuzzlewuppers due. They probably don’t want that but the UI has to make it clear to them what to do about that. We can’t make magical assumptions or try to be generous. See the sidebar for the history on this.

HALT. CLEANUP BELOW IS COMING — RECOMMEND NOT READING FURTHER JUST YET!

Goal Creation Steps

Here they are! The ones that are checked off existed previously. Steps 3-5 are partially implemented, but their functionality is being moved around and clarified and those details are the main thrust of this spec. Separating Step 3 (what’s being tracked) from Step 4 (how much you’re committing to) is outside the scope of this spec, but is a really good idea, so I’ve included it in the list here, and there are some additional thoughts in the “Outside the Scope” section at the end.

-[x] Step 1: Autodata or manual?

-[x] Step 2: What kind of goal is it? [user picks do-more, do-less, etc]

-[~] Step 3: What do you want to track? [ text box ]

-[ ] Step 4: How much are you committing to do?

-[ ] Step 5: How soon are you going to start?

-[x] Step 6: How much do you want to pledge?

-[x] Step 7: Name your goal.

-[x] Step 8: Add a credit card.

-[x] Step 9: [Go to goal]

Work to be done

1. Change the default runit to “daily” globally, since everything is actually done daily as far as Beeminder is concerned.

The main gotcha here is to double check the autodata implementations as well as the manual goal elf. Also look if there are existing tests in elf_spec and api_spec for the different types of runits and write some if not.

ASIDE: There is future work to be done here, with further clarifying that, regardless of what units your rate is denoted in — daily, weekly, monthly, etc — Beeminder is a daily commitment. We always consider your on-track-ness with a day’s granularity. But as with so many things we could get excited about designing, that’s outside the scope of this spec.

2) Remove the leeway checkbox from the “COMMIT TO AT LEAST” step

Remove the leeway buffer checkbox (“Start this goal with extra leeway”) from COMMIT TO. Also remove the leeway buffer box from autodata wizards. Since it is becoming its own entire step of elf (Step 5) it will be taken care of outside the scope of the autodata wizards now.

3) Insert a step after COMMIT TO

This is what is described as Step 5 in the goal wizard.

Title   : "WHEN WILL YOU START"  

Dynatext: "If you do nothing, your first BEEMERGENCY* will be in N DAYS on"  
Datefield: [FRI| 08/07 |📅]

Add'l   : * A BEEMERGENCY is a day when you _must_ enter enough data or you will derail.

In some sense it is risky to be moving the starting buffer into its own entire step of the goal creation. In the current iteration of goal creation, we have decided that probably you should start your goal right away and we want that default to be a strong default. We even hide the “start with extra buffer” box unless you unfurl it intentionally.

So as we make this change, I have been careful to make the focus on the Beemergency. I first use the word in a sentence and put the date picker secondary to the description of how long you will have to do your task. Shifting the focus from “days of leeway” to “your beemergency will be __” makes it clearer what’s happening, and therefore both easier to accept the default and skip over it (why we hid the field in the original form), and also less friction to make a decision about if you choose to adjust the starting buffer (no trying to count out calendar days).

The calendar picker will start with tomorrow selected, since all goal types get a default buffer of 1 day. When the calendar is updated, the dynatext field will update to say the new amount of days.

Technical note: The information put in localstorage and submitted to the goal creation endpoint should be in terms of a number of days, however, not in terms of a calendar date.

// Take a date object d and return a date object that's n days later
function dateplus(d, n) {
  let x = d
  x.setDate(x.getDate() + n)
  return x
}

// Return the difference in days between date objects a and b
function datediff(a, b) {
  const utca = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate())
  const utcb = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate())
  return Math.floor((utcb-utca)/86400000)
}

4) Weight goal starting buffer

Starting buffer is different for weight goals than for any other goals and is not computed with respect to days, but rather the maxflux setting. Mostly these changes will not affect them as they don’t include the “initial leeway” checkbox to begin with. The only goal types that take maxflux for their starting buffer are “fatloser” and “gainer” goals. All goal flows will have selected a goaltype already by the end of Step 4, so the [next] button logic in the elf.js will skip Step 5 if goaltype is one of these two, and instead set starting buffer to 0.

In some future version it might be better to split out the “max flux” question for weighty goals and have a weighty version of Step 5, but for the time being that is outside the scope of this graph-start-onboard spec (but see the Future Work section below / aka the distraction list).


 



 

Future work (aka distraction list)

NEXT1) Move the maxflux question from weight goals into Step 5 as a special case for the weight goals (which currently skip Step5), and use the opportunity to clarify what the heck we mean by maxflux.

NEXT1.2) Probably there is some special case for do less goals that would be better than the status quo.

Currently they ask for starting buffer in terms of days, just like do more goals, so there’s no need to discuss a special case here, for this version of this spec, but ultimately we could probably improve on how we ask for do less starting buffer too.

NEXT2) Insert an additional step prior to Step 4 (#3 above)

Title: “WHAT ARE YOU TRACKING” text box label: “Goal units” text box placeholder: E.g. miles, books, runs, sessions…

Dynamically show multiple examples of the gunits being used throughout the site, e.g. mockup the goal header, dashboard blurb, zeno subject line, etc.

TODO: how to get across what we’re talking about…
TODO: don’t ask for all 6 versions of the gunits, but maybe the dynamic examples show all 6 versions?

See http://doc.bmndr.com/units for more on this.

NEXT3) pre-fill gunits in COMMIT TO step with already picked gunits from the new step 3.

SCHDEL: [yeah, so good. although, wait, having it on the same step means that when you type “do more workouts” or whatever shit as your goal units you can see how stupid that is and change it and have it dynamically change the other stuff and be non-stupid. so maybe not a separate step? — that’s addressed on the goal units step. you’re going to see “Bare min of +1 do more workouts by midnight” or whatever in the previous step.]

NEXT4) Move Naming to after the pledge step.

BONUS 0) https://github.com/beeminder/beeminder/issues/1449 — uluc made a sweet thing that shows you your red line as you set it up.

It would be super sexy to include that into goal creation, like just underneath the wizard or something so you can see the red line as it changes…. but that’s a lot more work than just these first steps described here.