Skip to content

feat(lifeboard): proactivity, scheduled boards, and Google sign-in - #310

Open
ivanmkc wants to merge 2 commits into
lifeboard/08-bridge-jobsfrom
feat/lifeboard-foundation
Open

feat(lifeboard): proactivity, scheduled boards, and Google sign-in#310
ivanmkc wants to merge 2 commits into
lifeboard/08-bridge-jobsfrom
feat/lifeboard-foundation

Conversation

@ivanmkc

@ivanmkc ivanmkc commented Sep 2, 2026

Copy link
Copy Markdown
Owner

The stack

# PR What it adds Tests at this point
1 #311 A real localStorage for the test suite on Node 25 viewer 747
2 #312 @ivanmkc/termchart-canvas; injectable interact transport canvas 473 · viewer 278
3 #313 lifeboard PWA: fact log, boards, service worker lifeboard 36
4 #314 Shell, family profiles, tap layer lifeboard 82
5 #315 The agent turn, four providers, Connections lifeboard 142
6 #316 Packs, recipes, shopping-list arithmetic lifeboard 231
7 #317 Provenance and lineage lifeboard 257
8 #318 Calendar, Gmail, mail triage lifeboard 301
9 #319 The bridge and long jobs cli 314 · lifeboard 320
10 #310 Proactivity, scheduled boards, Google sign-in cli 320 · lifeboard 343
11 #320 Persistence audit fixes: multi-tab, stale builds, no-storage boot lifeboard 350
12 #321 User guide, bridge setup, QA guide, persistence audit lifeboard 350
13 #322 A plan for third-party integrations (docs only) unchanged
14 #323 A practice drill a board can define: audio + Q&A canvas 485 · lifeboard 372
15 #325 Export and restore lifeboard 389
16 #326 Draft a message, approve it, then send lifeboard 399
17 #327 Hand long work to the Mac lifeboard 406
18 #328 A Packs screen, and authoring one by describing it lifeboard 418
19 #329 Activity — what changed, who changed it, undo lifeboard 428
20 #330 Four defects found reviewing the stack cli 323 · lifeboard 431

Every branch in the stack was checked out on its own and verified independently: npm install, tsc --noEmit for every package, npm test across the workspace, and the offline e2e where it exists. All twenty are green — no branch depends on a later one to build or pass. Full viewer e2e (11 suites, 106 assertions) was run on #312 as the behaviour-preservation evidence for the extraction.


Stack position: 10 of 10 — the top of the stack. Base: lifeboard/08-bridge-jobs.

(This PR was originally the whole branch. It has been split into a ten-PR stack; this is now the last of them.)

Two things: the assistant noticing problems before you do, and the Google sign-in that makes the calendar and mail subsystems actually run.

The hard part of conflict detection is restraint, not detection. A rule that fires on every adjacent pair produces an app people mute in a week. So: timed events only, inside a fortnight, one conflict per pair with an order-independent id, and nothing at all when it does not know where either thing is — an unknown location is not a problem, and inventing one is how an assistant becomes noise.

The case worth getting right is the one plain overlap detection misses: you land at 18:40 and dinner is at 19:00 across town. Those two events do not overlap. Travel time is what makes it a conflict, and the estimator is injected so a later plan can use real routing.

A clash becomes a proposal, so it lands in the same inbox and is raised exactly once. Accepting proposes nothing automatic — the fix is a decision about someone's day — and declining changes nothing.

Scheduling reuses what exists rather than inventing a second scheduler: board definitions stay in .termchart/boards and running one is termchart run, the same command a crontab would call. The bridge is one more host. It is off unless asked for with --schedule, because every tick spends money on someone's subscription. Cadence is reported in words next to the cron, since 0 7 * * * does not tell anyone what it will cost.

The Google wiring closes a real gap I found on the last pass: the calendar and mail subsystems existed and were tested, but nothing in the app signed in or called them. Connections now signs in, and opening the app runs a catch-up pass. The client id is asked for rather than shipped — a Desktop-app OAuth client belongs to the person who made it, and Testing mode with up to a hundred named users needs no verification review and no CASA assessment; publishing one for everybody would drag the whole app into a restricted-scope audit it does not need.

The pass is interruptible and repeatable by construction: events reconcile on the provider's id, messages already turned into a proposal are skipped, and the last-run time is written only at the end. It runs in the background and never delays the board coming up.

Verified: lifeboard 343 tests, CLI 320, offline e2e 17/17.

🤖 Generated with Claude Code

ivanmkc and others added 2 commits September 2, 2026 08:07
…boards

The hard part of conflict detection is restraint, not detection. A rule that
fires on every adjacent pair produces an app people mute in a week. So: timed
events only, inside a fortnight, one conflict per pair with an order-independent
id, and nothing at all when it does not know where either thing is -- an unknown
location is not a problem, and inventing one is how an assistant becomes noise.

The case worth getting right is the one plain overlap detection misses: you land
at 18:40 and dinner is at 19:00 across town. Those two events do not overlap.
Travel time is what makes it a conflict, and the estimator is injected so a
later plan can use real routing.

A clash becomes a proposal, so it lands in the same inbox, is accepted or
declined the same way, and is raised exactly once. Accepting proposes nothing
automatic -- the fix is a decision about someone's day -- and declining changes
nothing.

Scheduling reuses what exists rather than inventing a second scheduler: board
definitions stay in .termchart/boards and running one is `termchart run`,
the same command a crontab would call. The bridge is one more host. It is off unless
asked for with --schedule, because every tick spends money on someone's
subscription and a program that starts doing that because it was launched is one
people learn not to launch. Cadence is reported in words next to the cron, since
"0 7 * * *" does not tell anyone what it will cost.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Closes the gap between having the calendar and mail subsystems and having them
do anything: Connections can now sign in to Google, and opening the app runs a
catch-up pass -- pull the calendar, read what is new, triage it.

The client id is asked for rather than shipped. A Desktop-app OAuth client
belongs to the person who made it, and Testing mode with up to a hundred named
users needs no verification review and no CASA assessment; publishing one for
everybody would drag the whole app into a restricted-scope audit it does not
need. That is a deliberate position, and the screen says so.

The pass is interruptible and repeatable by construction. Calendar events
reconcile on the provider's id, so running it twice updates rather than
duplicating a term of school events; messages already turned into a proposal are
skipped rather than triaged again; and the last-run time is only written at the
end. It runs in the background and never delays the board coming up -- the
family's own records are already on screen, and Google is the slow, failable
part.

Also adds Store.settled(), which resolves once every queued write has landed.
Three tests were waiting on fixed sleeps and failed under load in a full run --
a flaky test is a defect in the suite, and the fix is to wait for the condition
rather than to guess at a longer delay.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ivanmkc
ivanmkc force-pushed the feat/lifeboard-foundation branch from 41823e9 to a55ec34 Compare September 2, 2026 12:12
@ivanmkc ivanmkc changed the title feat(lifeboard): the foundation — canvas package, fact log, offline PWA feat(lifeboard): proactivity, scheduled boards, and Google sign-in Sep 2, 2026
@ivanmkc
ivanmkc changed the base branch from design/lifeboard to lifeboard/08-bridge-jobs September 2, 2026 12:13
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.

1 participant