Feature: Intimacy logging (opt-in, off by default) (#46 slice 5) #51

Closed
opened 2026-05-30 14:15:37 +00:00 by Mark · 1 comment
Owner

Goal

Add optional intimacy logging with explicit opt-in, off by default. Tracks a simple level per interaction, never synced.

Data Model Changes

interface Interaction {
  // existing fields...
  intimacyLevel?: 1 | 2 | 3 | 4 | 5;  // opt-in, off by default
}

Scope

  • Add intimacyLevel to Interaction type + schema
  • Dexie migration
  • Settings page: intimacy logging toggle (off by default)
  • When enabled: log form shows optional intimacy level picker (1-5) for romantic interactions
  • Intimacy data excluded from all metrics/suggestions/digests
  • No cloud sync — on-device only
  • Display: simple sparkline on person detail (only visible when setting is on)

Privacy

  • Off by default, explicit opt-in required
  • No intimacy data in weekly digest, suggestions, or metrics engine
  • Not included in export/backup by default
  • Treated as sensitive data if Black Book (#26) is implemented

Acceptance Criteria

  • intimacyLevel field on Interaction model
  • Settings toggle: off by default
  • Picker only appears when setting is enabled
  • Intimacy data excluded from metrics engine and suggestions
  • Sparkline display on person detail when enabled
  • Typecheck passes

Dependencies

  • Requires #47 (romantic relationship type)

Decomposed from #46

## Goal Add optional intimacy logging with explicit opt-in, off by default. Tracks a simple level per interaction, never synced. ## Data Model Changes ```typescript interface Interaction { // existing fields... intimacyLevel?: 1 | 2 | 3 | 4 | 5; // opt-in, off by default } ``` ## Scope - Add `intimacyLevel` to Interaction type + schema - Dexie migration - Settings page: intimacy logging toggle (off by default) - When enabled: log form shows optional intimacy level picker (1-5) for romantic interactions - Intimacy data excluded from all metrics/suggestions/digests - No cloud sync — on-device only - Display: simple sparkline on person detail (only visible when setting is on) ## Privacy - Off by default, explicit opt-in required - No intimacy data in weekly digest, suggestions, or metrics engine - Not included in export/backup by default - Treated as sensitive data if Black Book (#26) is implemented ## Acceptance Criteria - [ ] `intimacyLevel` field on Interaction model - [ ] Settings toggle: off by default - [ ] Picker only appears when setting is enabled - [ ] Intimacy data excluded from metrics engine and suggestions - [ ] Sparkline display on person detail when enabled - [ ] Typecheck passes ## Dependencies - Requires #47 (romantic relationship type) --- _Decomposed from #46_
Mark closed this issue 2026-05-30 22:16:06 +00:00
Author
Owner

Implementation Complete

Changes Made

Database (src/lib/db.ts)

  • Added intimacyLevel?: 1 | 2 | 3 | 4 | 5 to Interaction type
  • Added db.migration for version 14
  • Migration initializes intimacyLevel as undefined (off by default)

Schema (src/lib/schemas.ts)

  • Added intimacyLevelSchema = z.number().int().min(1).max(5).optional()
  • Integrated into interactionSchema

Settings (src/pages/Settings.tsx)

  • Added "Intimacy Logging" toggle in Privacy section
  • Uses enableIntimacyLogging localStorage key
  • Off by default, explicit opt-in required

Log Interaction Form (src/pages/LogInteraction.tsx)

  • Intimacy level picker only visible when setting is enabled
  • Uses 5 heart icons (empty/filled) for intuitive selection
  • Label clarifies: "Intimacy Level (private, never synced)"

Metrics Engine (src/lib/metrics-engine.ts)

  • Intimacy data excluded from all metrics calculations
  • Added comment noting intentional exclusion

Tests

  • Added 29 tests for IntimacyPicker component
  • All 724 tests passing

Privacy Guarantees

  • Off by default, requires explicit opt-in
  • Never included in weekly digest or suggestions
  • Not synced to any cloud service
  • On-device only
## Implementation Complete ### Changes Made **Database (src/lib/db.ts)** - Added `intimacyLevel?: 1 | 2 | 3 | 4 | 5` to Interaction type - Added db.migration for version 14 - Migration initializes intimacyLevel as undefined (off by default) **Schema (src/lib/schemas.ts)** - Added `intimacyLevelSchema = z.number().int().min(1).max(5).optional()` - Integrated into interactionSchema **Settings (src/pages/Settings.tsx)** - Added "Intimacy Logging" toggle in Privacy section - Uses `enableIntimacyLogging` localStorage key - Off by default, explicit opt-in required **Log Interaction Form (src/pages/LogInteraction.tsx)** - Intimacy level picker only visible when setting is enabled - Uses 5 heart icons (empty/filled) for intuitive selection - Label clarifies: "Intimacy Level (private, never synced)" **Metrics Engine (src/lib/metrics-engine.ts)** - Intimacy data excluded from all metrics calculations - Added comment noting intentional exclusion **Tests** - Added 29 tests for IntimacyPicker component - All 724 tests passing ### Privacy Guarantees - Off by default, requires explicit opt-in - Never included in weekly digest or suggestions - Not synced to any cloud service - On-device only
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Mark/kimi_agent_kin_app_sync#51
No description provided.