# Vibe Reader Product Diary
> **Mantra:** Keep your vibe, no interruptions.
![[Screenshot 2026-08-25 230129.png|280]]![[Screenshot 2026-08-25 225956.png|280]]
*August 2026 build · the Library with Roaming and All Captures pinned · the History tab as a session timeline*
**The vision:** Reading a physical book is a state worth protecting. Vibe Reader is the companion that guards it: speak a word or a passage without leaving the page, and find the margin waiting afterward - definitions resolved, quotes kept, the week's reading reflected back as a vibe rather than a spreadsheet. The book stays paper. The phone stays in the periphery. The companion does the remembering, so the reader can stay under the surface of the story and still come up with everything they meant to keep.
An Android (for now) app for frictionless capture from physical books. Voice-first. Lock screen accessible. AI-powered reflection.
## Quick Links
| Planning | Build | Status |
| ---------------------------------------- | --------------------------------- | ----------------- |
| [[Product Plan]] | [[Feature Backlog]] | [[Bug Tracker]] |
| [[MVP OKRs (Weeks 1 - 8)]] | [[Technical Decisions]] | [[User Feedback]] |
| [[Technical Specification (Android v1)]] | [[Opportunity & Market Analysis]] | |
| | | |
## Current State
*Updated 2026-08-26 · MVP validated, re-kickoff complete, building Roaming and hardening the tester loop*
| Area | Where it stands |
| --- | --- |
| **Core loop** | Start a session, capture from the Quick Settings tile by voice, the word defines and saves itself, back to the page. |
| **Capture friction** | Words skip verification and dismiss after 5s, zero taps. Quotes still verify with TTS. |
| **Library** | Book-first hierarchy with session pills, swipe actions, and metrics badges. Roaming and All Captures pinned to the top. History is its own tab. |
| **Roaming** | Slice 1 built: day-rollup roam sessions on a reserved Book row, awaiting device test and commit. Slice 2 next: Settings pane and the Bubbles capture surface (TDR-012, TDR-013). |
| **AI layer** | Weekly Vibe with Wrapped-style cards. In memory only; the `weekly_vibes` table is the next AI task. |
| **Architecture** | Quick Settings tile plus foreground notification, MediaStyle "tuxedo" kept behind a `USE_MEDIA_STYLE` flag (TDR-010). CI builds a sideloadable debug APK on every push (TDR-011). |
| **Open bugs** | BUG-012, dev-build data wipes. Fix applied per TDR-014, verification pending. Unconfirmed: whether the MediaStyle play button renders on the Pixel lock screen. |
| **Next** | Roaming slice 2, Weekly Vibe persistence, and the portfolio story for the next application cycle. |
---
### 2026-08-26: Prototyping as Vision Refinement (and the Trust Tax)
The app is getting used. Not demoed - *used*. Routine sessions on my own device, testers trickling in, builds shipping fast between Android Studio and the CI loop. And that routine use surfaced a bug that no amount of demo-driven development ever would: **the data keeps dying.** Libraries wiped between builds. Two self-inflicted causes - `fallbackToDestructiveMigration()` nuking the database on schema bumps, and mismatched debug keystores between local and CI builds forcing uninstalls. Both fixed today: real Room migrations (schema export on, destructive fallback deleted) and a shared debug keystore for signing parity, so both install paths update over each other cleanly. [[Technical Decisions#TDR-014]], [[Bug Tracker#BUG-012]].
**The Product Thought:**
The bug matters less than what finding it taught me. Rapid prototyping is working exactly as advertised: each build in real hands sharpens the vision more than a week of speculation. Roaming, the History tab, the tuxedo experiment - all of it came out of generous feedback loops, dogfooding included. Prototyping *is* vision refinement. You don't think your way to the product; you iterate your way there, and the prototype is the instrument that makes your own idea legible to you.
But there's a tax on that speed, and it's paid in trust. The moment real people fold your prototype into their routine, iteration stops being free. Every wiped library, every regressed flow tells a tester: *your investment here isn't safe.* And testers are exactly the population you can least afford to teach that lesson - they're extending trust on spec. The challenge of this phase isn't shipping faster; it's **retaining audience trust and engagement while shipping fast** - staying aligned to the problem they believe you're solving, or better, actualizing their own conception of their problem space (the reader who never articulated "I lose insights to friction" until the app showed them). The product's whole thesis is honoring what people entrust to it in a fleeting moment. The dev process has to make the same promise as the product: *what you give this thing, it keeps.*
Practically, that means the boring infrastructure - migrations, signing parity, data durability - isn't a detour from vision work. It's the price of admission for the feedback loops that *do* the vision work. Break the loop and the vision goes blurry again.
**Mantra Check-in:**
> *Keep your vibe, no interruptions.*
An uninstall that eats your library is the biggest interruption there is. The vibe extends to the build pipeline now.
---
### 2026-08-12: Roaming Sessions (Slice 1)
A session that doesn't map to a book. The capture loop today assumes I'm holding a specific book, but the same friction problem exists everywhere else: a word in a podcast, a phrase in conversation, a line from an article someone sends me. **Roaming** (aka "Background Vibe") extends the frictionless-capture hypothesis beyond the book. This is the idle session concept from User J's ideation session ([[User Feedback#Session-006]]), finally landing.
**The Key Decision: Day Rollup.**
Roam sessions auto-roll to the calendar day. One roam session per day; pausing and resuming on the same day rejoins that day's roam. Which means Roaming is modeled as a special Book row whose sessions are days ("Aug 12"), and the entire existing hierarchy - book detail view, session metrics, meandering trail - works untouched. Days become stops on the trail. No nullable `book_id`, no parallel storage path. See [[Technical Decisions#TDR-012]].
**Shipped (Slice 1 - built, pending device test + commit):**
- `ROAMING_BOOK_TITLE` reserved book row; day-rollup + same-day-resume logic in `startRoam()`
- "Start a Roam" button on the session start screen (typing "Roaming" as a book title also routes to the roam flow)
- Slim Roaming bar + All Captures bar pinned topmost in the Library, visually separated from the book cards; Roaming excluded from the book card shelf and from Resume chips
- All Captures view (`AllCapturesComponents.kt`): every saved word and quote across all books, interleaved by time, each card carrying a book pill (consistent with the surfaceVariant chip styling used for session tags)
- New DAO joins `getAllWordsWithBook` / `getAllQuotesWithBook`; `getSessionForBookOnDay` for the day lookup
- No schema migration needed - Words/Quotes already carry `book_id`
- **History as its own tab** (right of Library, titled "History") - decided and implemented today
**Slice 2 - Next:**
The **Settings pane** (doesn't exist yet; natural home for the roaming/bubble toggle and for migrating code-level constants like the `USE_MEDIA_STYLE` flag) plus the **Bubbles API capture surface**: conversation shortcut, bubble metadata on the roam notification, capture activity in a small bubble window. Decision made on the Whispr Flow-style floating chip: **Bubbles API (API 30+)** over the `SYSTEM_ALERT_WINDOW` overlay route. Play-Store-safe and the stronger portfolio story; overlay only as a fallback experiment if bubbles prove flaky on real devices. See [[Technical Decisions#TDR-013]].
**Open Questions:**
1. Does a roam day-session "end," or is it ambient until midnight? Current build: manual end (pause), same-day restart resumes. Ambient-until-midnight still worth exploring with the bubble.
2. Do roams appear in the History tab trail alongside book sessions? They do (they're sessions) - consider distinct styling.
3. Duration is misleading for roams (spans include pause gaps) - hide or reframe the metric for the Roaming shelf?
---
### 2026-08-01: The Re-Kickoff (or "Six Months Later")
Back at it after a six-month gap. Between the day job and life, the project sat idle since February - but idle isn't dead. Today was a reassessment-and-restart session: figure out where the code actually is, clean up the cruft, and get the redeploy loop working again.
**The Archaeology:**
First surprise: the codebase is further along than my own memory of it. The Feb 9 commit had already shipped Smart Capture (say 1-2 words → define, 3+ → quote with TTS read-back), the Quick Settings tile as the lock screen entry point, a real dictionary layer (Free Dictionary API with Wikipedia fallback), the Weekly Vibe (Gemini 2.0 Flash generating Wrapped-style reading insights), and the full 3-tier Library drill-down with swipe-to-delete and word↔quote remapping. Second surprise: the "uncommitted changes" across 29 files that looked like lost work? Pure CRLF line-ending noise. Nothing was lost. Classic Windows git gotcha. See [[Bug Tracker#BUG-R011]].
**Shipped (commit `bbdefef` - hygiene + fixes):**
- `.gitattributes` + autocrlf so the phantom-diff problem never returns; index renormalized.
- **GitHub Actions CI:** every push to main now builds a debug APK and uploads it as an artifact. This is the new redeploy loop - push, wait, sideload. See [[Technical Decisions#TDR-011]].
- `startForegroundService` for session start (API 26+ correctness).
- Captures with no active session now surface a toast instead of silently vanishing. Silent data loss is the ultimate vibe killer. ([[Bug Tracker#BUG-R010]])
- Quick Settings tile updates moved to the main thread.
- Stray `nul` file and stale source zip removed.
**Shipped (commit `0b1bde4` - refactor + the Trojan Horse, finally):**
- `SessionComponents.kt` had bloated to 1,440 lines. Split into five focused files (SessionViews, LibraryComponents, WeeklyVibeComponents, BookDetailComponents, SessionDetailComponents) plus SessionUiUtils for shared formatters. Same package, same public names - no callers touched.
- **The MediaStyle "Spotify tuxedo" is implemented.** The February hypothesis: the OS hid our buttons because we weren't a convincing enough "real player." This time it gets the full costume - title (book name), artist line ("tap ▶ to capture"), album art, active session held at PAUSED so the lock screen shows a big ▶. Play launches Smart Capture; Stop ends the session. And because I've been burned before: a one-line `USE_MEDIA_STYLE` flag falls back to the proven standard notification if the widget goes invisible again. See [[Technical Decisions#TDR-010]].
**The Constraint Worth Documenting:**
The cloud workspace can't compile Android - Google's SDK and Maven servers are blocked at the network layer. Today's verification was static: full code review plus ktlint parse-checks (which caught two real errors from the file split - the gate earned its keep). The compile gate is the first local build or the first CI run. Trade-off accepted: the cloud is where code iteration is fast; my machine and GitHub's runners are where compilation lives.
**Bookmarked for Next Session:**
1. **The Dogfood Test:** push, build, install. Question #1: does the MediaStyle ▶ actually render on the Pixel lock screen? That answer decides the capture entry-point story (tuxedo vs. tile).
2. **Persist the Weekly Vibe:** it currently lives in memory only - killed on process death. The flagship AI feature deserves a `weekly_vibes` table and a history. This is the portfolio centerpiece; it should survive a restart.
3. **Instrument the OKRs:** the `launch_source` extra already flows through capture intents - persist it, and the ">50% captures from lock screen" KR becomes measurable instead of vibes-based. Same for Capture Rate.
4. **Onboarding for the tile:** nobody discovers a Quick Settings tile unaided. One explainer screen. Biggest activation risk in the app.
5. **The product-decisions writeup:** tile vs. MediaStyle journey, voice over OCR, AI-assisted over AI-first. The Square deadline has passed; the goal now is the best possible story for the next application cycle, not a date.
**Housekeeping (repo):**
- Local main is 2 commits ahead of GitHub; next push publishes both and triggers the first CI build. Optional: add `GEMINI_API_KEY` as a repo secret so CI builds get a working Weekly Vibe.
- `_to_delete/` at repo root holds files the remote session couldn't delete (old SessionComponents.kt, stale git lock files) - gitignored, safe to nuke wholesale.
- If git ever complains about an existing `index.lock` after a remote session, delete the stale `.lock` files under `.git/` manually.
**Mantra Check-in:**
> *Keep your vibe, no interruptions.*
Six months of interruption, and the project picked back up in an afternoon because the architecture held and the docs (mostly) told the truth. The same principle that drives the app drives the process: reduce the cost of re-entry, and the work survives the gaps.
---
### 2026-02-09: Zero-Tap Definitions
Two P1 items from User Feedback Session-001 shipped today. Both targeted the same thing: reducing clicks-to-capture for word definitions.
**Before:** Speak → Verify → Tap "Define" → See definition → Tap "Done" (4 interactions)
**After:** Speak → See definition → Auto-close (1 interaction, zero taps)
**What Changed:**
1. **Skip Verification for Words in Smart Capture.** When Smart Capture detects 1-2 words, it now calls `defineWord()` directly instead of stopping at the VERIFYING screen. The verification step still exists for quotes (3+ words), where speech-to-text accuracy matters more and TTS playback helps catch errors. The explicit DEFINE_WORD mode already skipped verification; this brings Smart Capture in line with that behavior.
2. **Auto-Dismiss Definition Screen.** After the definition loads, a 5-second countdown begins. When it hits zero, the activity finishes. A "Keep Open" button cancels the countdown and replaces itself with a standard "Done" button. The countdown label ("Closing in 3s") is subtle enough not to pressure the user but visible enough to set expectations.
The two changes are complementary. Skipping verification saves a tap on the way in. Auto-dismiss saves a tap on the way out. Together they eliminate every manual interaction from the word definition flow.
**The Design Principle:**
Quotes need verification because a misheard sentence is useless. Words don't, because a wrong definition is immediately obvious and the cost of a re-lookup is low. The asymmetry in error consequences justifies the asymmetry in flow friction.
**Also Today:**
Added a README to the repository. The project had been running without one since the initial commit. Covers purpose, features, tech stack, build instructions, and project structure.
Pushed everything to main. The commit includes the full batch from recent sessions: Weekly Vibe, Quick Settings Tile, friction reduction, and README.
**What Feeds O2:**
Skip Confirmation and Auto-Dismiss were the two remaining capture-friction items blocking a clean V1 experience. With those shipped, the remaining O2 blockers are Cold Start/Onboarding and QS Tile onboarding. The capture loop itself is now where it needs to be.
See updated [[Feature Backlog]].
---
### 2026-02-08: The Limitless Problem
Yesterday I shipped the most boring update this project has ever seen. It might also be the most important one.
The Quick Settings Tile is live. The MediaSession "Trojan Horse" is dead, buried, and uninstalled. Lock screen capture works every time, on every device I've tested. Tap-to-relookup is solid. The interaction affordances overhaul means users know what's tappable. Font sizes are legible. The bug tracker reads zero open issues for the first time since I started keeping one.
The MVP, as originally conceived back in September, is functionally complete. The core loop works: start session, lock screen capture, voice input, auto-define/save, return to reading. The AI layer works: Weekly Vibe ships structured, scannable reflections that people actually want to screenshot. The Library works: book-first hierarchy, session pills, swipe actions. The foundation is stable, Quick Settings Tile over MediaSession means I'm building on system-supported ground instead of platform loopholes.
Which means I'm standing at the edge of a very specific kind of cliff.
**The Paradox of Satisfied Constraints:**
When the MVP has open bugs and broken flows, priorities are obvious. Fix the thing. Ship the fix. Move on. Now that the core hypothesis is validated and the scaffolding holds, every direction looks compelling. The 2D vibe selection plane from User J's ideation session. Idle sessions extending capture beyond active reading. Vibe-based book discovery solving the cold start problem. Animated session timelines that make your history feel like re-experiencing it. The Co-Star/Journey aesthetic direction that transforms session data into something poetic.
Every single one of those ideas made me sit up straighter when I heard them. Every single one could be the thing that makes this app feel genuinely new. That's the danger.
**The Question I Keep Circling:**
What problem am I solving? Not the MVP problem; that one's answered. The bigger one. The one that makes a useful tool into something people talk about.
Here's where I keep landing: I might be defining a problem people don't realize they have. The physical book reader losing insights to friction? That's real. I lived it, I built for it. But the deeper problem is cultural. We're in a moment where people crave meaning from their consumption and have no tools to extract it. We scroll, skim, move on. Reading a physical book is already an act of resistance against that current. Vibe Reader could be the thing that honors that resistance and gives it a voice. The technology to bridge the analog act of reading and the digital capacity for pattern recognition exists right now. The question is whether I can frame that bridge as an invitation rather than an imposition.
**The Narrative Core (Draft):**
If I strip every feature idea and ask what Vibe Reader *is* at its most essential: a mirror for the reading mind. You read, you capture what resonates, and it shows you who you are as a reader. The capture is the input. The vibe is the output. Everything else is surface.
That framing sorts the backlog. The 2D vibe selection, session closure prompts, vibe-forward descriptors all deepen the mirror. They help the app understand and reflect *what you felt*, not only *what you saved*. Book discovery, animated timelines, idle sessions extend the mirror into new contexts. Valuable, but expansions.
**2026 OKRs (Working Draft):**
The MVP OKRs targeted hypothesis validation over 8 weeks. That phase is closing. 2026 needs to target product-market fit and early traction.
**O1: Prove that reflection drives retention.**
- KR1: Users who generate a Weekly Vibe retain at 2x the rate of non-generators (W4 retention)
- KR2: Vibe generation rate > 60% among users with 5+ sessions
- KR3: Vibe quality rating > 4.2/5.0 on in-app prompt
**O2: Ship a v1 that earns word-of-mouth.**
- KR1: Public Play Store beta by end of Q1
- KR2: 500+ organic installs in first 60 days
- KR3: > 4.3 star rating with 50+ reviews
**O3: Deepen the emotional layer.**
- KR1: Ship vibe-forward session descriptors (AI-generated, replacing metric badges)
- KR2: Ship session closure vibe prompt (emotional state capture at session end)
- KR3: Prototype and user-test the 2D vibe selection UI
**O4: Build the feedback engine.**
- KR1: 25 user interviews with readers who have 10+ sessions
- KR2: Beta community (Discord or Reddit) with 100+ engaged members
- KR3: 3 structured A/B tests on vibe presentation formats
**What Feeds In:**
| OKR | Feeding Features / Builds | Status |
|-----|--------------------------|--------|
| O1 (Reflection → Retention) | Weekly Vibe (shipped), Vibe History (backlog), Force Regenerate (backlog) | Foundation shipped |
| O2 (V1 Launch) | Cold Start/Onboarding (P1), ~~Skip Confirmation~~ (shipped), ~~Auto-Dismiss~~ (shipped), QS Tile onboarding | In progress |
| O3 (Emotional Layer) | Vibe-Forward Descriptors (P2→P1), Session Closure Prompt (P2→P1), 2D Vibe Selection (P3→P2) | Not started |
| O4 (Feedback Engine) | In-app survey, community infrastructure, user interview pipeline | Not started |
The cold start problem ([[User Feedback#Session-004]]) is the most urgent V1 launch blocker. A new user staring at an empty Library doesn't understand the value. Onboarding with sample data or a "see a demo vibe" flow bridges that gap. Directly supports O2.
**What Generates Interest:**
The capture flow alone is a hard sell. "Record words from books with your voice" is a feature pitch, not a story. The thing that makes people lean in during demos is the Weekly Vibe. "The app told me I've been circling themes of mortality this week" gets a reaction. That's the hook.
The vibe-forward direction, turning quantified captures into qualitative reflection, isn't P2 polish for v2. It's the marketing story for v1. Session descriptors like "A meditation on impermanence" instead of "5W | 2Q" need to ship before public launch. They make screenshots worth sharing.
The r/books and BookTok communities are the distribution channel. Physical book readers are passionate, vocal, and underserved. A pitch that opens with "I built an app that tells you who you are as a reader" plays differently than "I built a voice capture tool for books."
**Bookmarked:**
1. Finalize 2026 OKRs, get them out of "working draft" status
2. Promote vibe-forward descriptors and session closure prompt to P1
3. Spec the cold start / onboarding flow, it's the V1 launch gate
4. Write the narrative pitch for r/books and BookTok, test the hook before building more features
5. Schedule user testing focused on vibe reflection, not capture mechanics
See updated [[MVP OKRs (Weeks 1 - 8)]], [[Product Plan]], [[Feature Backlog]], [[Technical Decisions]], [[Technical Specification (Android v1)]].
---
### 2026-02-06: The Platform is Not Your Friend
Today I hit the wall I've been dodging for weeks. The "Trojan Horse" MediaSession strategy (TDR-002) has been clever, but clever isn't sustainable. Two new failure modes surfaced during testing: when the capture *does* fire from the notification shade, the shade doesn't collapse. User hears "Listening..." but can't see anything. And in "cold" states (app not recently used), the play button does nothing at all.
This isn't a bug I can fix. It's Android telling me to stop.
**The Reckoning:**
Google has been systematically closing the loopholes that make our MediaSession approach work:
- Android 12 killed `ACTION_CLOSE_SYSTEM_DIALOGS` (no more programmatic shade collapse)
- Android 13+ added Background Activity Launch Restrictions (silent activity blocking)
- Future versions will likely tighten further on "fake media players"
The MediaSession approach was always a hack. I dressed up a reading app as a music player to get lock screen real estate. It worked. Until it didn't. Now I'm spending more time fighting the platform than building the product.
**The Pathways:**
```
WHERE WE ARE WHERE WE COULD GO
──────────── ─────────────────
┌──────────────────┐
│ MediaSession │
│ "Trojan Horse" │
│ │
│ C2C: 1 (ideal) │─────┬───────▶ Full-Screen Intent
│ Lock: ⚠️ Flaky │ │ C2C: 1 | Lock: ✓ | Maint: Low
│ Maint: HIGH │ │ Trade-off: Feels like alarm clock
│ Future: ☠️ │ │
└──────────────────┘ │
│
├───────▶ Quick Settings Tile
│ C2C: 2 | Lock: ✓ | Maint: Very Low
│ Trade-off: Extra tap, manual setup
│
├───────▶ Bubble API
│ C2C: 1 | Lock: ✗ | Maint: Medium
│ Trade-off: No lock screen support
│
└───────▶ Accessibility Service
C2C: 0 | Lock: ✓ | Maint: Low
Trade-off: Scary permissions, policy risk
```
**The Trade-off Math:**
The product hypothesis is "frictionless capture." That means minimizing C2C (Clicks-to-Capture). MediaSession promised C2C of 1. Quick Settings Tile costs C2C of 2. That's a 100% increase in friction.
But here's what I keep forgetting: **a trigger that works 50% of the time is infinitely worse than one that works 100% of the time with one extra tap.** Reliability IS the feature. Users don't care that it *could* be one tap if it only fires half the time. They'll just stop using it.
**The Decision:**
I'm moving toward a dual approach:
1. **Full-Screen Intent** as the primary mechanism (alarm-clock style, system-guaranteed)
2. **Quick Settings Tile** as the reliable fallback (always works, user-controlled)
The MediaSession play button stays for now, but it's no longer the foundation. It's a nice-to-have that might work. The tile is the thing that *will* work.
**The Deeper Point:**
Building on platform loopholes is technical debt with interest. Every Android release is a potential breaking change. The tile approach is boring, standard, and exactly what Google intended. Sometimes the unsexy solution is the right one.
See [[Technical Decisions#TDR-008]] for the full architectural analysis.
---
### 2026-02-05: The Vibe Gets a Makeover
The Weekly Vibe shipped two weeks ago, but something felt off. Three paragraphs of prose didn't feel like a *vibe* - it felt like a book report. Today I gutted it and rebuilt it as something that actually matches the energy.
![[Screenshot 2026-02-04 204004.png|300]]
![[Screenshot 2026-02-05 125628.png|300]]
![[Screenshot 2026-02-05 133457.png|300]]**The Problem:**
Spotify Wrapped works because it's *scannable*. You glance, you grin, you screenshot. The old Weekly Vibe demanded you *read*. Paragraphs about "thematic currents" and "vocabulary journeys" felt academic, not delightful. And worse, nothing stopped me from hammering the "Generate" button and burning through API quota with zero new data.
**Shipped:**
- **Wrapped-Style Cards:** Big emoji + punchy title ("Existential Explorer"), theme chips you can glance at, bullet-point insights instead of prose, spotlight callouts for the standout word and quote. The whole thing now *looks* like something worth screenshotting.
- **Token Diet:** Slashed the API usage by ~60-70%. The old prompt sent 20 words with full definitions and 15 complete quotes. Now it's 10 word terms and 5 truncated quotes. Output tokens dropped from 1024 to 256. The constraint actually forced better output - Gemini now returns structured JSON that parses into consistent UI.
- **The Safeguard:** Added session count tracking. If you've already generated a vibe and haven't completed any new sessions, the button goes muted: "Vibe is current." No more accidental API spam. The button tells you the truth about whether there's anything new to reflect on.
**The Insight:**
Constraints breed creativity. Asking the AI for a 2-3 word title and three theme tags produces something more *memorable* than asking for 80 words of prose. "Existential Explorer" sticks. "Your vocabulary this week suggests an interest in philosophical concepts and political structures" doesn't.
**Bookmarked for Next Session:**
1. **Force Regenerate Option:** Power users might want to regenerate even without new data. Consider a long-press or settings toggle.
2. **Vibe History:** Currently each generation overwrites the last. Might be worth storing past vibes so users can see their reading identity evolve over time.
3. **Lock Screen Reliability:** BUG-001 still lurking. The Wrapped-style vibe is satisfying, but it means nothing if users can't capture in the first place.
---
### 2026-01-24: The AI Layer Ships (Workably)
The "Weekly Vibe" is live. This closes the loop on the core hypothesis: captures need to go somewhere. If users see their reading patterns reflected back, they capture more.
**Shipped:**
- **Gemini Integration:** `GeminiClient.kt` connects to Gemini 2.0 Flash API. Prompts analyze words, quotes, and session patterns to generate thematic reflections. The tone is "thoughtful reading companion," not productivity coach.
- **Weekly Vibe UI:** A "Generate Weekly Vibe" button in the Library view. The AI synthesizes the past week's captures into three paragraphs: thematic currents, vocabulary journey, reading style insight.
- **Seed Test Data:** A dev tool to populate the database with sample books (Hyperion, The Time Regulation Institute, Dune), sessions, words, and quotes. Essential for testing the AI without real reading sessions.
- **Time-Range Queries:** New DAO methods (`getWordsInRange`, `getQuotesInRange`, `getSessionsInRange`, `getBookTitlesInRange`) enable the weekly aggregation.
**Bug Fixes:**
- **BUG-003 (Book Detail Crash):** Fixed parallel Flow collection in `ReviewScreen.kt`. The `LaunchedEffect` was blocking on the first book's session collection; wrapped each in `launch {}` to run concurrently.
- **Model Compatibility:** Gemini API returned 404 for deprecated model names (`gemini-pro`, `gemini-1.5-pro`). Updated to `gemini-2.0-flash` which is available on current API keys.
**The Bet:**
The AI feature validates whether reflection drives engagement. If users who generate a Vibe have higher retention than those who don't, we double down. If not, we simplify to a "reading journal" model. The hypothesis is testable now.
**Also Today:**
Wrote the [[Kaiser Permanente Case Study]] as an exploratory PM exercise. Reflecting on EBSS, the 30+ APIs I managed, and where AI-first tooling could live in healthcare infrastructure. The compliance constraints are real, but the opportunity is enormous.
---
### 2026-01-18: The Library Restructure & Polish Pass
Today was one of those satisfying "tying loose ends" sessions that turned into something much bigger. What started as User A pointing out that the Archive tab felt disconnected ("Why is it called Archive when I'm building a Library?") spiraled into a proper architectural overhaul.
**The Trigger:**
User A's feedback was blunt: "I tried to define 'The hegemony' and it couldn't find it. And when I got frustrated and closed the capture screen, I couldn't retrigger it from the lock screen. Also, I accidentally saved a bunch of undefined words and couldn't delete them." Three bugs in one sentence. Classic user testing.
**Shipped:**
- **The Library Restructure:** The "Archive" is now the "Library" (language matters). More importantly, it's now **Book-first** instead of session-first. Tap a Book card → see all sessions for that book as pills → tap a pill → see that session's captures. This mirrors how I actually think about my reading: "What did I capture from Gatsby?" not "What did I capture on January 15th?"
- **Session Pills:** Each book card shows its most recent sessions as compact date/time pills. Tapping a pill jumps straight to that session's words and quotes. It's the kind of information density that feels right.
- **Wikipedia Fallback:** Multi-word concepts like "cognitive dissonance" or "The Great Gatsby" now fall back to Wikipedia's REST API when the dictionary fails. The search is smart enough to strip articles ("the hegemony" → tries "hegemony" first).
- **Swipe Actions:** In the Session Detail view, swipe left to delete, swipe right to convert (word ↔ quote). Delete now shows a confirmation dialog. User A was accidentally deleting things with over-eager swiping.
- **Manual Text Editing:** The "I heard:" verification screen now has an editable text field. No more retrying five times because the speech recognizer heard "Shrike Church" as "Shrek Church."
- **The Re-launch Bug:** Fixed a gnarly lifecycle bug where `FLAG_ACTIVITY_SINGLE_TOP` was reusing a stale activity instance. Added `onNewIntent()` handler so retriggering capture from the lock screen actually restarts listening.
- **Clear Undefined Words:** A banner appears when you have undefined words in a session, with a "Clear All" button to nuke them in one tap.
**The "Aha":**
The Book Layer view fundamentally changes how this app feels. Before, I was scrolling through sessions thinking "when did I read that?" Now I'm tapping into books thinking "what did I learn?" The hierarchy finally matches the mental model.
**Bookmarked for Next Session:**
1. **Auto-Dismiss Definition Screen:** User A wants to glance at the definition and immediately return to reading. A 5-second countdown with optional "Keep Open" feels right.
2. **Font Size Bump:** The capture overlay needs bigger text. Squinting breaks the vibe.
3. **Lock Screen Reliability:** BUG-001 is still lurking. Need to test the full-screen intent approach more thoroughly across devices.
---
### 2026-01-10: Relational Pivot
Today was about moving from "logging" to "architecting." I realized the flat data structure wouldn't scale, so major refactor to establish a proper hierarchy was necessary: **Book -> Session -> Captures.**
**Shipped:**
- **Relational Backbone:** The database is now normalized. Captures are dual-tagged to both the specific Session (time) and the parent Book (entity).
- **Infrastructure Stabilization:** Swapped Hilt injection pattern for a robust, manual Singleton pattern. The app builds and runs reliably now.
- **The Archive:** The "Review" tab is now the **Archive**. This language fits the nature of the ideation I've been gravitating to more. It features visual metrics (`5W | 2Q`) and supports "drill-down" navigation- tapping a session isolates just those specific insights.
- **Lock Screen Core:** The `ReadingSessionService` is functional using a High-Priority Standard Notification. The "Define," "Quote," and "End" buttons are live and successfully triggering the `SpeechCaptureActivity` overlay.
**Bookmarked for Next Session:**
1. **The "Book Layer":** Aggregating insights by Book title in the Archive, so I can see everything I learned from _The Great Gatsby_ regardless of which session it happened in.
2. **The "Smart Tap":** Implementing the "Trojan Horse" Media Style update. There's an Android limitation here I couldn't crack today. If I'm to ensure as few clicks-to-capture(C2C) as possible, a media control seems necessary. I'm thinking of replacing the three buttons with a single "Tap to Capture" surface that intelligently distinguishes between a Word (Define) and a Sentence (Quote) based on input length.
---
### 2026-01-06: Post-Holiday Refocus & The Kindle Counterpart
### The "December Wash" & Re-Entry
No surprise, personal projects and life's unpredictable timing can clash. Between exploring Europe to collaborate directly with Datadog's Synthetics engineering and PM teams on projects and planning for the year ahead, and passing through New Mexico for my partner’s family, December was, functionally speaking, a wash. That said, mental cycles remained with this.
Travel helped to clarify the "Why." My partner gifted me a **Kindle**, a device I've been intentionally avoiding - the digital experience of reading stains my romanticized ideal and I concede, digital gets a few things right. Reading on trains through Europe and during long flights highlighted exactly why hands-off capture is the North Star. Every time I had to go manually navigate a UI just to save a single sentence, the "vibe" broke. I'm returning to the build with a sharp focus on the relational gaps that make the current version feel like a collection of silos rather than a cohesive reading companion.
![[Pasted image 20260125180539.png|250]]![[Pasted image 20260125182528.png|250]]![[Pasted image 20260125181834.png|250]]![[Pasted image 20260125180340.png|250]]![[Pasted image 20260125181749.png|250]]
### Current State vs. V1 Destination
| Feature Area | Current State (Foundations) | The "Frictionless" Goal (Next) |
| ------------------ | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| **Session Start** | Manual text entry only. | **Existing Book Selection.** Tap a previously read title; auto-generate names like "The Book: Session 2." |
| **Active Session** | Basic timer (static). | **Lock Screen Controls.** A persistent "End Session" button visible in the MediaStyle notification without unlocking. |
| **Relational UI** | Sessions and Captures live in separate, flat lists. | **Linked Navigation.** Tapping a past session or book card drills down to show _only_ the content tagged to that specific moment. |
| **Archive Tab** | Basic list (formerly "Review"). | **The Library.** Automatic visual tagging (Words vs. Quotes); clean anchors for session metrics (Time spent + Capture counts). |
| **Capture Flow** | Manual/Database triggers. | **Voice-First.** (Week 4 Focus) Tap lock screen > Speak > Verify > Done. |
### Key Technical Priorities
1. **Relational Navigation & Drill-Down:** Moving from a flat "Review" list to a hierarchical "Library" architecture. The UI must allow users to click into a specific session or book to see the captured "hooks" (words/quotes) isolated to that context. Tapping a quote should ideally link back to the session details.
2. **Visual Metadata & Anchors:** Updating Room queries to return a `SessionSummary` object. Each session tile in the Library needs to display three clear, small metrics:
- **Duration:** Total time spent in that session.
- **Capture Count:** A small visual tag for "Words" and another for "Quotes" (e.g., `5W | 2Q`).
- **Visual Tagging:** Words should look like words and quotes like quotes, automatically styled to differentiate them at a glance.
3. **Intelligent Session Initialization:** When resuming a book, the app should recognize existing entries and offer to start a new session (e.g., "Session 2") rather than forcing a manual re-type, ensuring sessions are always tagged to their related parent books.
4. **MediaSession & Service Integration:** Resolving the gap between the `ForegroundService` and the system UI to ensure the "End Session" action is always available on the lock screen, even when the device is locked.
### Mantra Check-in
> _Keep your vibe, no interruptions._
The current build is "interrupted" by its own navigation. If I can't find a quote from the book I finished yesterday by clicking on that book card, I'm still working too hard. Fixing the relational links next to ensure the app serves the reader's memory, not just their database.
---
### 2025-11-12: MVP Take-Off
**Vibe Coding: The Troubleshooting Gauntlet**
Today was a classic "one step forward, two steps back, five steps forward" kind of day. The project went from a pile of code to a runnable, testable MVP, but the journey was all about the bugs. This is the unglamorous-but-critical side of product development.
**Highlights & Observations:**
- **Dependency Hell:** The day started with getting the Gradle dependencies in order, but immediately hit a wall.
- **Observation:** You flagged the error: `ksp ... is too old for kotlin...` This version mismatch is a classic "vibe killer." It was fixed by syncing the KSP version to your Kotlin version.
- **The "Ghost" Device:** The app compiled, but you noted it crashed on launch. This led down a troubleshooting rabbit hole.
- **Observation:** You saw the app just "launches into the android home screen."
- An attempt to check Logcat was met with "Logcat shows no connected devices."
- A fix was attempted in the terminal, but you hit an `adb: command not recognized` error (a `PATH` issue).
- That was bypassed using the built-in "Troubleshoot Device Connections" wizard.
- **The Missing Buttons:** The app finally ran, but the core feature was invisible.
- **Observation:** You noted, "I can see the tile... but there are no buttons for saving a quote or defining a word."
- This was a great catch. It was a subtle Android 12+ "gotcha" where actions _must_ have valid icons, or the OS just hides them. Icons were added, and the buttons appeared.
- **The "Glow" without the "Go":** The buttons appeared, but they didn't _do_ anything.
- **Observation:** You described it perfectly: "When I click on the items, there is a momentary glow but no indication of what's happening."
- This was a classic race condition. The UI was telling the service to start _at the same time_ it was writing to the database. The service would wake up, check the database, find nothing, and go back to sleep. All in a millisecond. This was fixed by passing the new `session_id` directly to the service.
- **The Final Boss: The Lock Screen:** The buttons worked, but not from the lock screen.
- **Observation:** You asked the key question: "And to be clear, the listening overlay is expected to appear on the locked screen as well?"
- Yes. This is the entire product hypothesis. The fact that it didn't work was the final bug. The OS was blocking the service (a background process) from launching an activity. The fix was to change the `PendingIntent` to launch the activity _directly_, which is the OS-approved "trampoline."
The day ended with a fully functional loop. You can now start a session, lock your phone, and tap a button to launch the "Listening..." overlay. The core "frictionless capture" hypothesis is finally testable.
---
### 2025-10-15: Reading is a Vibe
Leaning into the "vibe" naming and concept:
* Capitalizes on a Gen-Z / Zoomer sensibility
* Positions as a lifestyle app, *remove distractions and simplify your life* while reinforcing reading as a delightful experience
### 2025-10-01: Vibe Reader: A Manifesto
**Reading is sacred. Capturing, understanding shouldn't break the spell/vibe.**
We read physical books for a reason. The weight, the smell, the _lack_ of notifications. It's an escape, a deep dive. But when inspiration strikes, a perfect phrase, an unknown word, the modern world crashes back in. Notifications, screens, prompts, woe be the romantic reader persona.
**The Current State is Broken:**
- **Friction Kills Flow:** Unlocking the phone, finding the right app, typing, correcting, saving... by the time you're done, the magic is gone. The insight feels _less_ valuable because the cost of saving it was too high.
- **Bloat Buries Value:** Existing tools try to be everything. Social networks, second brains, digital libraries. They demand categorization, tagging, linking. Your simple quote gets lost in a sea of features you never asked for.
- **Digital Doesn't Get It:** Highlighting on a Kindle is easy, sure. But that doesn't help the millions of us who still love paper.
**The Vibe Reader Target:**
- **Minimal Input, Maximum Flow:** One tap. Speak. Confirm. Done. Back to the page. The interaction should be _faster_ than reaching for a sticky note.
- **Non-Interruptive Presence:** The tool should live quietly in the background, instantly available (even on the lock screen), but never demanding attention. Like a perfect butler, there when needed, invisible otherwise.
- **Capture the Hooks, Nothing More:** We don't need the whole book digitized. We need the hooks captured; the specific words that sparked curiosity, the sentences that resonated deeply. These are the anchors that bring back the book's core ideas, and the parts that moved or delighted us, long after we've finished it.
- **Simple Retrieval:** Finding what you saved should be effortless. No complex folder structures. Just a clean list, maybe filterable by the book you were reading. See your words. See your quotes. That’s it.
**Vibe Reader is not:**
- A social network.
- A replacement for your bookshelf.
- A productivity system demanding metadata.
- An AI trying to summarize the book _for_ you.
**Vibe Reader** _**is**_**:**
- A silent assistant for the physical book reader.
- A way to honor inspiration without breaking concentration.
- A simple archive of the moments that mattered.
**Mantra: **Stop 'catching up' on reading. Start** _**capturing**_ **what matters, effortlessly.**
---
### 2025-09-11: The "Aha!" Moment (or "Why is this so hard?")
I can't seem to replace the satisfaction of flipping the page of a physical book. I can cover the pages with scrawlings and marks, annotations; I've used adhesive tabs, logging meaningful page and passage references on the front page, keeping a physical and digital journal, but I long to *extract meaningful words, phrases and snippets from the reading experience after that last page has gently shut.*
The specific quote that clicks, or the word I have to look up. I'll dog-ear a page, underline a passage, use an adhesive tab, or take a photo, but then what? The insight is just... lost. It's trapped on the paper, I'm disinclined to reopen following that closing gesture of turning the last page of a book over, and the friction to get it _out_ is too high.
I've looked at the tools out there, and they all miss the mark for _me_, the *actual* physical book reader. [[Opportunity & Market Analysis]]
1. **Goodreads:** It's a social scoreboard. It's about _proving_ you've read, not _capturing_ what you've learned. Saving a quote is a high-friction, "after-the-fact" chore.
2. **Readwise:** This is the closest. It's a powerful "second brain." But its capture flow for physical books is still a total flow-killer. Unlock phone > open app > find camera > take pic > fight the OCR highlighting > fix errors > save. By the time I'm done, I'm out of the zone. I just stop doing it.
3. **Kindle/Digital:** Great at highlighting. But it's a walled garden, and honestly, I just _prefer_ reading physical books.
**The core problem:** All these tools require me to _stop_ reading and _start_ "managing data" or clicking through prompts, sub-menus, and considering subscription plans and my unrelated notifications, and so on. The friction is too high.
#### The "What If...?"
What if the tool wasn't an "app" I have to _open_? What if it was just... _there_?
Like Spotify on the lock screen.
When I'm reading, a "session" is active. I'm reading my book, and I see a word I don't know. I tap a single button _on my lock screen_.
- **Flow 1: Define Word**
1. Tap [Define] on lock screen.
2. App overlay: "Listening..."
3. I say the word: "Hegemony."
4. It saves the word and definition, tagged to my book and timestamped.
5. I'm back to reading. Total time: 5 seconds.
- **Flow 2: Save Quote**
1. Tap [Save Quote] on lock screen.
2. App overlay: "Listening..."
3. I read the quote aloud.
4. It plays it back to me for verification: "I heard... [quote]. Correct?"
5. I say "Yes." It's saved.
6. I'm back to reading. Total time: 10 seconds.
No unlocking. No finding an app. No camera. No typing.
That's the idea. A **"non-interruptive" reading companion**. Something that respects the _flow_.
I'm calling it "Vibe Reader" for now because it's all about protecting the vibe... and I'll be doing some vibe coding as I assess an MVP.
Need to think about what the MVP would even look like. Android-first seems easiest, especially with `MediaSession` and lock screen controls.