Skip to content

Dashboard v2.4.0.b58: reminder routing fallbacks + teamspace filter fix - #758

Closed
dwertheimer wants to merge 6 commits into
mainfrom
dashboard-reminder-routing-b58
Closed

Dashboard v2.4.0.b58: reminder routing fallbacks + teamspace filter fix#758
dwertheimer wants to merge 6 commits into
mainfrom
dashboard-reminder-routing-b58

Conversation

@dwertheimer

@dwertheimer dwertheimer commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

@jgclark — flagging you as owner/reviewer. This PR shows the complete diff of everything after your 29d938ba: five Dashboard fixes, plus the version bump to 2.4.0.b58 and changelog.

One thing to be aware of: equivalent commits (84bddf5416b08e91) are already on main — they were pushed straight there during a live debugging session, before this PR existed, and main is force-push protected so they can't be withdrawn. This branch is rebuilt on 29d938ba with those commits cherry-picked, so the diff you see below is the real, reviewable change set. The practical consequence: merging adds only the version bump and changelog as new content, since main already has the source changes. Review comments here still apply to live code — anything you want changed is a follow-up commit rather than a block.

All five were found by tracing a real symptom on a live install: "why am I only seeing 3 reminders?" Each was verified against running NotePlan, not just reasoned about.

The fixes

commit (this PR / on main) what
ce03cdb7 / 84bddf54 Overdue counted reminders it didn't display
54165422 / 8eec7ba0 reminders whose section was off were dropped → fall back to REM
d1453167 / c4e88d80 that fallback was resurrecting items hidden by Show Current Reminders
24ac1f54 / 703dd712 unreachable teamspace IDs hid every task
fa8b2e3c / 16b08e91 untimed-today fallback + DESIGN DECISION note

Two worth your attention

1. 24ac1f54 is the nasty one. includedTeamspaces held six stale teamspace IDs and no 'private'. Private notes are only read when 'private' is in that list, so every note was filtered out before a single task could be read — reminders still showed, so it looked like tasks had vanished. It was also unfixable from the UI: signed out of Spaces, Spaces to Include correctly says "You are not a member of any Spaces" and offers nothing to click.

Both existing guards miss this — ?? ['private'] only fires when the setting is absent, and the length === 0 check only when it's empty. A non-empty list of unreachable IDs sails through both. Now healed at runtime, so affected configs recover without editing settings.

Still open, and not mine to fix: something wrote those six IDs while zero Spaces were reachable, at the base dashboardSettings level. MultiSelectSpaces.jsx is the component showing "not a member of any Spaces" — if it can persist stale IDs while displaying nothing selectable, this will recur for anyone who signs out of Spaces.

2. The design note in fa8b2e3c. A timed reminder due later today is shown nowhere until its time arrives. That's your decision and I've left it as-is — but nothing recorded it, and from the outside it is indistinguishable from the silent-drop bug above. Separating the two took most of the session. The note names both places to change if you ever want them visible early, and flags that changing only one makes them appear twice.

Verification

Same data throughout — buckets timedToday=1 untimedToday=1 yesterday=0 tomorrow=0 overdue=4 undated=3 (sum 9):

perspective before after
z_ALL_ON 8 of 9 8 shown + 1 not-yet-due = 9
Reminders Only - ALL 7 of 9 8 shown + 1 not-yet-due = 9
z_OVERDUE Only 7 of 9 8 shown + 1 not-yet-due = 9
Reminders Only - No Current 7 of 9 unchanged — correct, Show Current Reminders is off

Every reminder is now either displayed or intentionally withheld. Tasks confirmed healthy after the teamspace fix (1 today + 7 overdue in z_ALL_ON). Dashboard tests 220/220; no new Flow errors (4 in these files before and after).

Two things to know before merging

  • Diagnostic logging is deliberately left in at @dwertheimer's request for continued testing: one line per reminder (list, title, raw EventKit date vs derived date/time), one per bucket assignment, REM section size, and the names of reminder lists disabled in NotePlan. That last one resolved two "missing" reminders as simply living in lists NotePlan has switched off. Say the word and I'll strip them.
  • One non-bug worth knowing: reminders only come from lists enabled in NotePlan. A blank includedReminderLists inherits NotePlan's enabled set; a non-empty CSV can select any accessible list, including ones NotePlan has switched off.

🤖 Generated with Claude Code

dwertheimer and others added 6 commits July 30, 2026 00:33
…re dropped

Two problems found while tracing "why am I only seeing 3 reminders".

The Overdue section counted reminders it did not show. When
maxItemsToShowInSection left fewer slots than there were overdue reminders,
the extras were sliced off the displayed list but still added to
totalOverdue, so the header claimed more items than the section contained
and the difference was unreachable. Count what was actually assigned, and
warn when some do not fit.

More seriously, a reminder whose bucket has no visible host section is
discarded with no trace. In a perspective with Yesterday, Tomorrow and
Overdue all off, 6 of 9 reminders vanished and only the 3 undated ones
appeared in REM -- indistinguishable, from the outside, from having only 3
reminders. getSomeSectionsData now names them:

  1 yesterday (Yesterday section off, and Overdue off so the spill has
  nowhere to land); 3 overdue (Overdue section off); 2 tomorrow (Tomorrow
  section off) reminder(s) have no visible section and will not be shown
  anywhere

Note the yesterday case has to check that Overdue is actually visible, not
just that the spill happened: yesterday spills into Overdue, so treating the
spill as a home hid the loss whenever Overdue was itself off.

Also log each reminder placement with its target section, which is what made
the routing traceable in the first place.

Verified against a live NotePlan across three perspectives: 11 fetched, 2
dated beyond tomorrow and dropped by design, 9 bucketed, and 9 displayed in
z_ALL_ON (1 yesterday + 2 tomorrow + 3 overdue + 3 undated) with no
duplicates. Dashboard tests 217/217.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…than dropping reminders

A dated reminder whose host section was switched off was discarded. With
Yesterday, Tomorrow and Overdue all off, 6 of 9 reminders disappeared and
only the 3 undated ones showed, which is indistinguishable from having 3
reminders.

Yesterday and overdue reminders now fall back to the REM section, whose
setting is literally "Show Undated/Overdue Reminders": an overdue reminder
belongs there by name, and a yesterday one is overdue in every sense that
matters once there is no Yesterday section to hold it. Routing order is own
section -> Overdue -> REM, so nothing is adopted while a more specific
section is visible.

Tomorrow is deliberately excluded. A future reminder is neither undated nor
overdue, and switching off the Tomorrow section is a reasonable way of
saying you do not want to see it yet. Those are still reported by the
warning, which is now narrowed to reminders the fallback genuinely cannot
rescue.

Verified live across three perspectives:

- Today-All (all three off): REM adopts 4 (3 overdue + 1 yesterday), so 7
  reminders show instead of 3; only the 2 tomorrow ones remain hidden, and
  are warned about. 7 + 2 = 9 bucketed.
- z_ALL_ON: no adoption at all, DY gets 1 and DO gets 2 as before.
- z_OVERDUE Only: no adoption; Overdue takes 4 (3 overdue + the yesterday
  spill).

Dashboard tests 220/220, and no new Flow errors (4 in these files before and
after).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…how Current Reminders

The fallback added in the previous commit adopted yesterday's reminders into
the REM section whenever the Yesterday and Overdue sections were both off --
including when "Show Current Reminders" was itself off. That toggle's
description is "Show or hide reminders due today, yesterday, or tomorrow", so
adopting a yesterday reminder there put back an item the user had explicitly
hidden.

Yesterday is a current reminder, so its fallback is now gated on that toggle.
Overdue is unaffected: it belongs to "Show Undated/Overdue Reminders", which
is the setting the REM section is named for.

Verified in a perspective with Show Current Reminders off, Yesterday off and
Overdue off: adoption drops from 4 to 3, i.e. the 3 overdue reminders are
still rescued while the yesterday one stays hidden as requested. Dashboard
tests 220/220.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… reachable

A user's Dashboard showed all 9 reminders and zero tasks. Cause:
includedTeamspaces held 6 teamspace IDs and not 'private'. Private notes are
only read when 'private' appears in that list, so every note was filtered out
before a single task could be read -- reminders were unaffected because they
come from the Reminders app, not from notes. The visible symptom was
"8 backlinked paras found" immediately followed by "0 refs".

The list was also unfixable from the UI: the user is signed out of Spaces, so
"Spaces to Include" correctly reports "You are not a member of any Spaces" and
offers nothing to click. The six IDs were stale, pointing at spaces that can
no longer be resolved.

The two existing guards both miss this. `?? ['private']` only applies when the
setting is absent, and the `length === 0` check only when it is empty; a
non-empty list of unreachable IDs sails through both and silently matches
nothing.

resolveAllowedTeamspaceIDs() now discards IDs that no longer exist, and when
nothing survives falls back to ['private'] with a warning naming the setting
and the likely cause. Deliberate configurations are untouched: absent still
means private-only, an empty list still means don't filter, and a list of
genuinely reachable teamspaces without 'private' still excludes private notes,
because that is a real thing to ask for. All four call sites now share the
resolver instead of repeating the `?? ['private']` idiom.

Verified live on the affected setup: the warning fires, the teamspace filter
goes from 0 of 1 notes to 1 of 1, and Today returns 4 open items again --
without editing the stored settings, so existing configs heal themselves.
Dashboard tests 220/220.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…-yet-due rule

Sweeping five perspectives against the reminder buckets showed every one of
them losing items, and separated two causes.

Real gap, now fixed: an untimed reminder due today had exactly one home, the
Today section. With that off it went nowhere, even with the Reminders section
on. It now falls back to REM alongside overdue and yesterday, under the same
"Show Current Reminders" gate so an explicitly hidden item is not resurrected.

Not a gap: a timed reminder due later today is shown nowhere until its time
arrives. That is a deliberate decision, but nothing in the code said so, and
from the outside it is indistinguishable from the bug above -- it cost a good
while to tell the two apart. There is now a DESIGN DECISION note at the filter
in getTimeBlockSectionData recording the intent, naming the two places that
would have to change to show them early, and warning about the double-display
that would result if only one were changed. The REM fallback comment says why
this bucket alone is skipped, and the "no visible section" warning explicitly
does not fire for it.

Measured before and after on the same data (buckets timedToday=1
untimedToday=1 yesterday=0 tomorrow=0 overdue=4 undated=3, sum 9):

  perspective                    before  after
  z_ALL_ON                        8 of 9  8 shown + 1 not-yet-due = 9
  Reminders Only - ALL            7 of 9  8 shown + 1 not-yet-due = 9
  z_OVERDUE Only                  7 of 9  8 shown + 1 not-yet-due = 9

Every reminder is now either displayed or intentionally withheld, with no
silent losses left in those paths. Dashboard tests 220/220.

Diagnostic logging is deliberately left in for continued testing: one line per
reminder (list, title, raw EventKit date vs derived date/time), one per bucket
assignment, the REM section size, and the names of reminder lists disabled in
NotePlan -- that last one is how we found two "missing" reminders were simply
in lists NotePlan has switched off.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…nd teamspace fixes

Covers the five fixes already on main (84bddf5, 8eec7ba, c4e88d8,
703dd71, 16b08e9), all found while tracing "why am I only seeing 3
reminders" against a live install.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@dwertheimer
dwertheimer force-pushed the dashboard-reminder-routing-b58 branch from e682325 to 459a60a Compare July 30, 2026 07:33
@jgclark

jgclark commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

I'm confused. Somehow this has made it into my local code without merging this.
So I'm closing without apparently merging it, but in practice it is merged with thanks, @dwertheimer

@jgclark jgclark closed this Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants