2.6 KiB
Dream Diary — "what I consolidated last night"
Date: 2026-07-09 · Status: approved (founder Q&A) · Branch: worktree-channels-arc
Origin: CowAgent teardown steal #1 (docs/analysis/cowagent-vs-waggle-2026-07-09.md).
Waggle already runs real nightly memory curation (compaction, harvest sync, index repair, lane
extraction) but reports it only to log.info — the user never sees the substrate working. The
diary narrates those real events. It must never fabricate.
Founder decisions (locked)
| Decision | Choice |
|---|---|
| Narrative | Deterministic stats sentence always; LLM polish on top (built-in proxy fast tier). LLM down → deterministic stands. |
| Placement | Home cockpit card ("While you slept") + expandable 7-day history. Suppressed until the first dream exists. |
Architecture
packages/server/src/local/dream-journal.ts—DreamJournal: one JSON per day at<dataDir>/dreams/YYYY-MM-DD.json(atomic tmp+rename).record(action, stats)appends a structured event + recomputes the deterministicsummaryfrom aggregated day counters. Product layer on purpose — NOT hive-mind-core (no OSS port obligation).- Event sources — the four existing
memory_consolidationcron branches inlocal/index.ts:memory_compact(temporaryPruned/deprecatedPruned/pframesMerged),harvest_sync(frames/items/sources/couldNotVerify),index_reconcile(ftsFixed/vecFixed),memory_lane_extract(lane counters). Zero-count runs are recorded (honest "quiet night"). Failures are not diary events (already logged elsewhere). - LLM polish — lazy:
GET /api/dreamsreturns deterministic text immediately; if a day has events but nonarrative, it schedules ONE guarded background polish call (in-flight set), persisted into the day file; next poll shows it. Zero-activity nights skip the LLM (cost). - Route —
routes/dreams.ts:GET /api/dreams?days=7(isLocalRequest-guarded) →[{date, events, summary, narrative?}], newest first. - UI —
apps/web/src/components/os/home/DreamDiaryCard.tsxon HomeCockpit: moon icon, latest day's narrative (fallback summary), expandable previous days. Hidden when no data.
Tests
Journal: record/aggregate/summary wording, atomic persistence across instances, zero-night summary, date rollover. Route: shape, days clamp, lazy-polish single-flight, LLM-failure fallback (narrative stays absent, summary intact). Web: card renders narrative, falls back to summary, hides with no data, history expand.
Verification
npx tsc --noEmit -p packages/server/tsconfig.json · server vitest · apps/web vitest · web build.