Files
waggle-os/docs/addiction-features/03-continuity-banner.md
Oleg Maslov 0c3e2ead3b
Some checks failed
Installer Smoke / installer-smoke (push) Has been cancelled
moving
2026-09-02 10:10:29 +02:00

5.5 KiB

03 — Continuity Moments (Auto-Resume Banner)

Author: CC (Block B design pass) Date: 2026-05-01 Status: AWAITING_RATIFICATION Estimate: ~120 LOC + ~2-3h wall-clock Touches: apps/web (1 file: ChatApp.tsx OR new ContinuityBanner.tsx), packages/server (1 endpoint extension)


User story

When I open Chat after closing it for hours/days, I want a 1-line banner reminding me where I left off — what I last decided, what's still open — and a one-click way to continue or start fresh, so I don't have to re-orient myself manually.

Acceptance criteria

  1. When ChatApp mounts AND messages.length === 0 AND last session for the workspace was within the past 7 days, render a "Picking up where you left off" banner at the top of the chat.
  2. Banner content: 1-line headline ("Yesterday you decided X") + 2 buttons: Continue (loads last session messages) + Start fresh (dismisses banner, opens empty input).
  3. Banner suppressed for fresh workspaces (sessionCount=0) and for sessions older than 7 days (handoff to LoginBriefing's domain).
  4. Dismissing banner via Start fresh sets a per-workspace flag continuity:dismissed:{wsId} so the banner doesn't re-render same session.
  5. Continuity banner replaces neither WorkspaceBriefing nor LoginBriefing — it's a third surface specific to "between-session" memory.

UI sketch

ChatApp top, above message list:
  ┌──────────────────────────────────────────────────────────┐
  │ ⟳ Picking up where you left off                       ✕  │
  │ Yesterday you decided: ship migrations Wednesday.        │
  │ 2 open follow-ups · last session 16h ago                 │
  │                                                          │
  │ [ Continue conversation ]    [ Start fresh ]             │
  └──────────────────────────────────────────────────────────┘

After click Continue: banner fades, last session messages stream into the chat.
After click Start fresh: banner removed for this session, input focused.

Data model

No new tables. Extends existing endpoints:

  • GET /api/workspaces/:id/context — already returns recentThreads[]. Pull recentThreads[0] if its lastActive ≤ 7 days. Add lastDecision field (top decision content from yesterday) — drawable from existing recentDecisions[0].
  • New endpoint POST /api/sessions/:id/load — already exists conceptually as getHistory(workspaceId, sessionId). Confirm wire-up.

Frontend localStorage:

continuity:dismissed:{wsId} = ISO timestamp

Set on Start-fresh click. Banner suppressed for that workspace until next mount where lastActive moves forward (i.e. user has actually had new activity).

Implementation notes

  • Existing WorkspaceBriefing already shows recentThreads[] as a list. Continuity banner is a focused alternative: ONE thread, biggest decision, action-oriented buttons.
  • Decision: keep WorkspaceBriefing for the "browse" affordance (5 recent threads + memories + decisions list) and add ContinuityBanner as the "resume" affordance (1 thread, 1 click to continue). They co-exist, both above chat list, ContinuityBanner above WorkspaceBriefing.
  • Continue button: calls existing session load mechanism — setActiveSession(threadId) then loadSessionHistory(threadId).
  • Decision extraction: recentDecisions[0] from workspace-context already filtered for last 24h elsewhere; reuse.

Estimate

  • ContinuityBanner component: ~70 LOC
  • ChatApp wire-up + localStorage logic: ~30 LOC
  • Server context extension (lastDecision field): ~10 LOC
  • Tests: ~30 LOC (banner render conditions, dismissal flag, time-window logic)
  • Total ~140 LOC, ~2-3h with verification.

Risks + open questions

  1. Three surfaces collide — ContinuityBanner + WorkspaceBriefing + LoginBriefing all surface "what you did last" content. Need clear visual hierarchy: LoginBriefing (cross-workspace), WorkspaceBriefing (this workspace overview), ContinuityBanner (one-click resume).
  2. Stale banner — user opens Chat at 2am after a 12-hour break. Banner says "Yesterday you...". Linguistic edge case (was it really yesterday?). Use existing timeAgo() helper.
  3. Continue vs new session — clicking Continue should load the OLD session's messages OR start a NEW session that references them? v1: load old session messages so user sees full context.
  4. Multiple workspaces — banner only fires for the active workspace. Cross-workspace continuity prompts are LoginBriefing's job.
  5. Fresh user — sessionCount=0 → banner suppressed. But what about a returning user with one stub workspace and no real sessions? Same: suppress.

Out of scope (v1)

  • Voice continuity ("Resume our conversation where I asked about X").
  • Multi-thread continuity (continue the most-impactful thread, not just newest).
  • Smart "you might want to follow up on X" suggestion engine. (That's the Daily Brief's domain.)
  • Cross-device continuity sync (already handled by server-side session storage; no client work needed).

PM decisions needed

  • GO / MODIFY / SKIP
  • Time window — 7 days reasonable? or shorter (3 days)? or 30 days?
  • Dismissal scope — per-session (re-show next mount) or per-day?
  • Continue button behavior — load old messages vs new session w/ context inject
  • Co-existence with WorkspaceBriefing — both above chat OR Continuity replaces Briefing for last-7-day case?