diff --git a/docs/superpowers/specs/2026-04-25-dogfood-feedback.md b/docs/superpowers/specs/2026-04-25-dogfood-feedback.md index 9d15022..9371da1 100644 --- a/docs/superpowers/specs/2026-04-25-dogfood-feedback.md +++ b/docs/superpowers/specs/2026-04-25-dogfood-feedback.md @@ -816,6 +816,113 @@ slice §1.3 종료 조건 ("크래시 0회") 와 별개로, **"데이터 손실 --- +## F7. Due Date 규칙 파서가 합성 표현을 first-match-wins 로 오인 (🔬 drafting) + +**발견:** 2026-04-26 v0.2.1 dogfood 첫 사이클. 본문에 `"내일 모레"` 가 들어간 노트가 due_date = 내일 (today + 1) 로 추출됨. 사용자 의도는 "모레" 또는 "이틀 안" 정도의 모호 표현. + +### 관찰 + +`src/main/services/dueDateParser.ts` 의 매칭 로직: +- 14 high-confidence 규칙을 순회 (모레가 내일보다 우선순위 위) +- 같은 텍스트에 여러 토큰 발견 시 `text.indexOf` 로 **가장 먼저 등장한 위치** 의 토큰 채택 (`내일도 모레도 바쁨` → 내일이라는 기존 fixture 가 이 동작을 lock-in) + +문제 케이스: +- `"내일 모레"` — 합성 표현 (내일+모레 ≈ "곧" / "1-2일 안") 인데 첫 토큰 "내일" 만 잡힘 +- `"오늘 내일 안에"` — 동일 패턴 +- `"이번 주 다음 주"` — 양가 표현 +- `"3일 4일 뒤"` — 범위 표현 + +규칙 파서의 한계 3가지: +1. **합성/양가 표현**: 두 시간 토큰이 인접하면 단일 의미로 해석되는 한국어 관용 (사용자 의도 ≠ 첫 토큰) +2. **범위 표현**: "2~3일 뒤", "이번 주 안에", "다음 주 중", "월말 즈음" — 명확한 ISO 가 없는 본질 +3. **모호 표현**: "곧", "조만간", "여건 되면" — 사람도 ISO 변환 못함 + +현재 동작은 첫 토큰 기반이라 **확신도 낮은 매치도 high confidence 로 표기되어 NoteCard 에 그대로 박힘**. 사용자가 매번 editing 해야 하는 마찰. + +### 제안 방향 + +**5가지 후보, 짧은 시간 / 긴 시간 layered:** + +| ID | 방향 | 비용 | 효과 | 슬라이스 적합 | +|----|------|------|------|--------------| +| **A** | "내일 모레" / "오늘 내일" / "이번 주 다음 주" 등 **합성 패턴 화이트리스트** 추가 — 인접한 두 시간 토큰 발견 시 **확신도 낮춰서 AI 위임** | 작음 | 한정적 (알려진 패턴만) | ✅ 작은 PR | +| **B** | 한 노트에 **여러 high-confidence 매치 발견 시 충돌 감지** → 모두 medium 으로 강등 → AI 위임 | 작음 | 중 — 단일 토큰은 그대로, 다중만 영향 | ✅ 작은 PR | +| **C** | 규칙 매치 결과에 **항상 confidence 정보 + matched span 첨부** + UI 에 `?` 마크 (낮은 확신도) 노출 + 클릭 1번에 빠른 dismiss | 중 | 중-상 — 사용자가 인지 + 빠른 수정 가능 | 중 | +| **D** | **AI 우선 + 규칙은 후위 검증** 으로 흐름 반전 — AI 가 due_date 응답하면 규칙으로 sanity check (확실한 매치만 그대로, 충돌 시 AI 우선) | 큼 | 가장 정확 | 후속 | +| **E** | 규칙 파서 폐기, **AI 단독** | 작음 (코드 삭제) | AI 모델 의존도 ↑, latency 의존, 결정론 손실 | 후속 | + +**권장 조합 (단계적)**: + +1. **즉시 (slice MVP +)**: B + 일부 A — 첫 발견 시 충돌 / 화이트리스트 매치는 medium 으로 강등 (AI 위임). 골든 픽스처에 `"내일 모레" → null` 추가. +2. **다음 cycle**: C — UI 신호 (확신도 표시 + 빠른 편집) +3. **누적 데이터 후**: D 또는 E — AI 우선/단독 흐름 반전 결정. dogfood 1주 데이터 (수용률 / 편집률 / 충돌 발생률) 가 의사결정 기반. + +### 결정 대기 + +1. **합성 패턴 화이트리스트 (A) 의 크기**: 2 토큰 (`내일 모레`, `오늘 내일`, `이번 주 다음 주`, `오늘 내일 모레` 같은 3-token) 까지 — 어디까지가 합리적 범위인가? +2. **충돌 감지 (B) 의 임계값**: "high-confidence 토큰이 동일 텍스트에 N개 이상 등장 시 medium 강등" — N = 2 OK? 또는 토큰 간 거리 (한 줄 안 vs 떨어진 문장) 로 다르게? +3. **fixture 유지**: 기존 `'내일도 모레도 바쁨' → 내일` 테스트는 **현재 동작을 lock-in** 하는 케이스. B 도입 시 이걸 → null 로 바꿔야 일관됨. 의도된 변경? +4. **C 의 UI 위치**: 확신도 `?` 를 어디에 표시? `📅 YYYY-MM-DD ?` (라벨 옆) vs hover tooltip vs 별 색 (회색 = 확신 낮음). +5. **D vs E**: 결정론적 fallback 가치 vs AI 단순화. dogfood 누적 데이터 본 뒤 결정. +6. **F1 spec 의 후속 리스트** 에 본 항목을 추가할지, 별 항목으로 분리할지. **별 항목 권장** (영향 큼, 수정 복잡도 다름). + +### 가설·측정 + +| # | 가설 | 측정 | +|---|------|------| +| H1 | dogfood 1주 동안 합성 표현 ("내일 모레", "이번 주 다음 주" 등) 등장 ≥ 3회 | 본인 라벨링 + grep | +| H2 | A+B 적용 시 false positive 매치율 > 50% 감소 | 적용 전후 1주씩 비교 | +| H3 | C 의 `?` 표시가 사용자 편집 빈도를 ≥ 30% 증가시킴 (자각 → 행동) | 편집 이벤트 카운트 | +| H4 | 본인 dogfood 에서 due_date 가 한 번이라도 잘못 박혀서 무시되는 노트 비율 < 10% (현재 측정 없으나 첫 케이스가 발생함) | 정성 라벨링 | +| H5 | D (AI 우선) 적용 시 latency 영향 ≤ 200ms / 노트 (현재 ~1-3초 대비 무시 가능) | LocalOllamaProvider 응답 시간 측정 | + +### 범위 + +- **In (1차 — A + B):** + - `dueDateParser.ts` — 합성 패턴 화이트리스트 (2-token 인접 시 medium 강등) + 충돌 감지 (≥2 high-confidence 매치 시 모두 medium) + - `tests/unit/dueDateParser.test.ts` — 새 fixture (`"내일 모레" → null`, `"오늘 내일" → null`, `"이번 주 다음 주" → null`) + - 기존 `'내일도 모레도 바쁨' → 내일` fixture 결정 — 유지 vs 변경 + - AiWorker 의 머지 로직 그대로 (`ruleResult.iso ?? aiResponse.dueDate ?? null`) — medium 매치는 iso=null 이므로 자동으로 AI 위임 +- **In (2차 — C):** + - `ParseResult` 에 `matchedSpan: { start, end }` 추가 + - `dueDateParser` 가 confidence 와 함께 매치한 토큰 span 반환 + - AiWorker 가 final result 에 `dueDateConfidence: 'high' | 'medium' | 'low'` 추가 + - DB 컬럼 `due_date_confidence` 신규 (migration v3) — 또는 transient 만 (UI 만 표시, DB 미저장) + - `NoteCard.DueDateBadge` — 확신도 낮음 시 `?` 표시 + tooltip +- **In (후속 — D):** + - AiWorker 흐름 반전: AI 먼저 호출 → 응답에 due_date 있으면 채택 → 규칙은 sanity (AI 응답이 명백히 틀린 경우 — 예: AI 가 과거 날짜 반환) 검증 + - 또는 E: 규칙 파서 deprecate +- **Out:** + - "월말", "주말" 같은 모호 표현 (이미 medium 처리 중) + - 시각 단위 (오후 3시 등) + - 음력 / 절기 + +### 영향 + +- **Schema (1차):** 없음 +- **Schema (2차 C):** migration v3 후보 — `due_date_confidence` 컬럼. 또는 transient 만 (DB 미저장). +- **코드 (1차):** + - `src/main/services/dueDateParser.ts` — 충돌 감지 로직 + 화이트리스트 추가 (~30 줄) + - `tests/unit/dueDateParser.test.ts` — 새 fixture 5+ 케이스 +- **코드 (2차 C):** + - `dueDateParser` 의 `ParseResult` interface 확장 + - `NoteCard.DueDateBadge` 의 props 확장 + 시각 표시 + - IPC / preload / store 의 due_date 타입 동반 갱신 (confidence 도 expose 시) +- **로깅:** + - `AiWorker` 의 `ai.done` 메타에 `dueDateConfidence` 추가 (기존 `dueDateSource: rule|ai|none` 와 함께) +- **문서:** + - 본 항목 promoted 시 `2026-04-MM-due-date-rule-limits.md` (가칭) 으로 추출 + - F1 spec (`2026-04-26-f1-due-date.md`) 의 §"후속" 에 본 항목 링크 추가 +- **slice spec §1.3 영향**: dogfood 종료 조건 "AI 결과 7/10 수용" 의 측정에 due_date confidence 가 들어가야 의미 있는 데이터 됨 — 본 항목이 그 측정 인프라 제공. + +### 비고 + +본 피드백은 **F1 promoted 후 첫 실사용 신호**다. v0.2.1 dogfood 의 의도된 측정 사이클 (≥1주 soak → F4-A·D 결정) 와 같은 흐름에 자연스럽게 합류하는 항목이고, 다음 cut (v0.2.2 또는 v0.3.0) 의 후보. 단계 1 (A+B) 만 작은 PR 로 분리 가능 — 즉시 시도해도 위험 0. + +규칙 파서 폐기 (E) 는 매력적이지만 **AI 가 항상 떠 있는 dogfood 환경 가정** 이 중요. `OllamaBanner` 가 자주 뜨는 환경 (LAN 박스 다운 등) 에선 결정론적 매치가 가치 있음. 이 트레이드오프는 dogfood 1주 데이터 (Ollama uptime · health success rate) 보고 결정. + +--- + ## (다음 항목 자리) -새 피드백 추가 시 `## F7. 짧은 제목 (🌱 raw)` 헤더로 시작. 표준 슬롯 6개 채우거나 비워둔 채 시작 가능. +새 피드백 추가 시 `## F8. 짧은 제목 (🌱 raw)` 헤더로 시작. 표준 슬롯 6개 채우거나 비워둔 채 시작 가능.