This commit is contained in:
126
docs/addiction-features/04-weekly-wins-digest.md
Normal file
126
docs/addiction-features/04-weekly-wins-digest.md
Normal file
@@ -0,0 +1,126 @@
|
||||
# 04 — Memory Wins Digest (Weekly)
|
||||
|
||||
**Author:** CC (Block B design pass)
|
||||
**Date:** 2026-05-01
|
||||
**Status:** AWAITING_RATIFICATION
|
||||
**Estimate:** ~250 LOC + ~4-5h wall-clock
|
||||
**Touches:** apps/web (1 component + 1 tab in Memory app), packages/server (1 cron job + 1 route), packages/core (1 generator)
|
||||
|
||||
---
|
||||
|
||||
## User story
|
||||
|
||||
Once a week (Monday morning by default), I want a summary card showing how Waggle's memory paid off the prior week — N facts saved, N agent recalls that used them, estimated minutes saved on context-explaining — so I can quantify the value and feel the compounding effect.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
1. Weekly digest fires once per week (configurable day/hour, default Monday 09:00 local).
|
||||
2. Delivered as a Memory app tab card + an in-app banner on first desktop mount of the week.
|
||||
3. Card content (3 metrics + 1 narrative line):
|
||||
- Frames saved this week: N
|
||||
- Recalls that hit a saved frame: M
|
||||
- Estimated time saved (M × 9min context-restore baseline): ~T minutes
|
||||
- Narrative: "Your top theme this week: <theme>. Top decision: <decision>"
|
||||
4. Card persists in Memory app's "Wins" tab indefinitely — historical record of weekly progress, not just one-time.
|
||||
5. First-week edge case: if user has < 7 days of history, banner suppressed but Wins tab shows "Come back next week for your first digest" placeholder.
|
||||
|
||||
## UI sketch
|
||||
|
||||
```
|
||||
Memory App > Wins tab:
|
||||
┌─ Week of April 24-30 ──────────────────────────────────────┐
|
||||
│ ▲ 12 frames saved ▲ 5 agent recalls ⏱ ~45 min saved │
|
||||
│ │
|
||||
│ Top theme: API rate limiting + auth-rewrite │
|
||||
│ Top decision: Ship migrations Wednesday │
|
||||
│ │
|
||||
│ [Open Memory] [Open Last Decision Source] │
|
||||
└────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─ Week of April 17-23 ──────────────────────────────────────┐
|
||||
│ ▲ 8 frames · ▲ 3 recalls · ⏱ ~27 min saved │
|
||||
│ Top theme: Onboarding wizard polish │
|
||||
└────────────────────────────────────────────────────────────┘
|
||||
|
||||
(older weeks collapsed by default, click to expand)
|
||||
|
||||
Banner on Monday morning:
|
||||
[Trophy icon] This week saved you ~45 min — see the breakdown
|
||||
[Open Wins] [✕]
|
||||
```
|
||||
|
||||
## Data model
|
||||
|
||||
New table `weekly_wins`:
|
||||
```
|
||||
id INTEGER PRIMARY KEY,
|
||||
week_start TEXT NOT NULL UNIQUE, -- 'YYYY-MM-DD' (Monday)
|
||||
frame_count INTEGER NOT NULL,
|
||||
recall_count INTEGER NOT NULL,
|
||||
estimated_minutes_saved INTEGER NOT NULL,
|
||||
top_theme TEXT,
|
||||
top_decision TEXT,
|
||||
top_decision_source_session_id TEXT,
|
||||
generated_at TEXT NOT NULL,
|
||||
delivered_at TEXT -- nullable until banner shown
|
||||
```
|
||||
|
||||
For `recall_count`, need to instrument frame retrieval:
|
||||
- Existing `HybridSearch.search()` already returns frame IDs
|
||||
- Add `RecallEvent` log: every search/retrieval that hits a frame logs `{ frame_id, ts, source: 'agent' | 'manual' }` to a `recall_events` table
|
||||
- Aggregate weekly count per (week, agent-source-only)
|
||||
|
||||
## Server-side generator
|
||||
|
||||
Cron runs Monday 00:30 local (off-peak):
|
||||
1. Query frames where `created_at >= weekStart AND created_at < weekStart+7d`
|
||||
2. Query recall_events where `source='agent' AND ts in [weekStart, weekStart+7d]`
|
||||
3. Compute estimated_minutes_saved = recall_count × 9 (calibrated baseline; configurable)
|
||||
4. Theme extraction: LLM call ("From these N frames, what's the dominant theme in 5-10 words?")
|
||||
5. Top decision: highest-importance critical/important frame matching decision pattern from the week
|
||||
6. Insert row, set delivered_at=null, await client poll
|
||||
|
||||
Estimated minutes baseline (the "9 min context-restore"): documented derivation needed; placeholder until UX research lands.
|
||||
|
||||
## Implementation notes
|
||||
|
||||
- Recall instrumentation is the hardest part — needs hook in `HybridSearch.search()` callsite to log frame IDs returned and identifier of the consumer (agent loop vs manual UI search).
|
||||
- Weekly cron: trivial extension of cron infrastructure; runs `generateWeeklyWins(weekStart)` on schedule.
|
||||
- Wins tab in Memory app: paginate if N > 12 weeks.
|
||||
- Edge: time zones again — week boundary is server-local Monday 00:00. Document.
|
||||
|
||||
## Estimate
|
||||
|
||||
- Recall events table + instrumentation: ~70 LOC (touches HybridSearch + agent-loop)
|
||||
- Generator + cron: ~80 LOC
|
||||
- Server route `/api/weekly-wins`: ~30 LOC
|
||||
- WinsCard + WinsTab components: ~80 LOC
|
||||
- Banner + ack route: ~30 LOC
|
||||
- Tests: ~50 LOC
|
||||
- **Total ~340 LOC, ~4-5h with verification.**
|
||||
|
||||
## Risks + open questions
|
||||
|
||||
1. **Recall instrumentation** is the cost driver — need to wire `HybridSearch` to log every retrieval. Hot path; throttle/buffer logs to avoid SQLite write storms.
|
||||
2. **Estimated-minutes-saved calibration** — 9 min baseline is a guess. Run a small UX study or pilot a percentile estimate. v1: hardcode + flag for revision.
|
||||
3. **First week** — user installs Monday afternoon, what do they see Tuesday? Nothing — wait for next Monday. Banner suppressed for ~7 days.
|
||||
4. **Theme/decision LLM cost** — 1 call/week × ~700 tokens ≈ $0.01/user/week. Negligible.
|
||||
5. **Privacy** — frames may contain sensitive content; theme summary on personal mind only, not Team/shared workspaces. Hard rule: no cross-workspace digests.
|
||||
6. **What counts as a "recall"** — open question. Agent retrieval via `recall_memory` MCP tool? Hybrid search hits during chat? UI-driven Memory app search? Default: instrument all three; aggregate by source.
|
||||
|
||||
## Out of scope (v1)
|
||||
|
||||
- Comparison to prior week ("up 30% from last week") — wait until 4+ weeks of data.
|
||||
- Per-workspace digests — global personal-mind digest only v1.
|
||||
- Email digest delivery — in-app only.
|
||||
- "Share to team" affordance.
|
||||
- Streak integration ("you've maintained a 4-week digest streak"). (Streak feature is separate; wait until both exist.)
|
||||
|
||||
## PM decisions needed
|
||||
|
||||
- [ ] GO / MODIFY / SKIP
|
||||
- [ ] Default delivery day/hour (Monday 09:00 reasonable? Friday end-of-week instead?)
|
||||
- [ ] Recall sources to count (agent only / agent+UI / all)
|
||||
- [ ] Estimated-minutes baseline (9 min default, or skip the metric until calibrated?)
|
||||
- [ ] Banner vs. tab-only delivery (can banner be opt-out?)
|
||||
- [ ] Theme extraction model (Sonnet / Haiku)
|
||||
Reference in New Issue
Block a user