# F7 AI-Primary Due Date Spec (Promoted)

**Extracted from:** `2026-04-25-dogfood-feedback.md` F7
**Plan:** `docs/superpowers/plans/2026-04-26-f7-ai-primary-due-date.md`
**Status:** 🚀 promoted — implemented 2026-04-26

## 결정 (mini-brainstorm 결과)

| 결정 | 값 | 근거 |
|------|-----|------|
| Flow 반전 | AI 우선 + rule 은 prompt 후보 힌트 | F7 D 채택 |
| AI 실패 시 fallback | 없음 (due_date null) | 단순화, setDueDate ambiguity 회피 |
| 후보 주입 | `parseAllCandidates` 가 모든 high+medium 매치를 prompt 에 list 로 주입 | AI 종합 판단 |
| `parseDueDate` 보존 | YES (backward compat, 후속 spec 에서 deprecate 결정) | 비파괴 |
| schema 변경 | 없음 | 기존 컬럼 재사용 |
| confidence DB 저장 | 미저장 | F7 §C 후속 |
| PROMPT_VERSION | 3 (semantic 변경) | hints 추가 |

## 범위 (PR 안에 포함됨)

- `src/main/services/dueDateParser.ts` — `parseAllCandidates` 신규 + 기존 `parseDueDate` 보존 (overlapping-span suppression 포함)
- `src/main/ai/prompt.ts` — `buildPrompt(rawText, todayKst, candidates)` 확장, `PROMPT_VERSION = 3`
- `src/main/ai/InferenceProvider.ts` — `GenerateInput.dueDateCandidates: ParseResult[]`
- `src/main/ai/LocalOllamaProvider.ts` — pass-through
- `src/main/ai/AiWorker.ts` — flow 반전 (rule.iso ?? ai → ai.dueDate ?? null), `dueDateSource: 'ai' | 'none'` + `candidatesCount` 로깅
- 테스트 — `parseAllCandidates` 7 + AiWorker flip 1 + 신규 candidates 주입 검증 1, LocalOllamaProvider sig 동기화

## 동작 변화 요약

| 입력 | 기존 (F1) | 신규 (F7) |
|------|----------|----------|
| `'내일 회의'` + AI=`'2026-12-31'` | `'2026-04-27'` (rule 우선) | `'2026-12-31'` (AI 우선) |
| `'내일 모레 회의'` + AI=`null` | `'2026-04-27'` (rule first-match) | `null` (AI 가 ambiguous 인지) |
| `'월말 마감'` + AI=`'2026-04-30'` | `'2026-04-30'` (rule null → AI) | `'2026-04-30'` (AI) |
| 매치 없음 + AI=`null` | `null` | `null` |
| AI 실패 (3 retry exhausted) | `markAiFailed` (due_date 그대로) | `markAiFailed` (due_date 그대로 — 별 fallback 없음) |

## 후속 (F7 §C / D / E 의 다른 부분)

- F7 §C: confidence + matched span 을 DB 에 저장 + UI `?` 표시
- F7 §A·B (즉시 화이트리스트 + 충돌 감지) — D 채택으로 사실상 자연 해결
- E (rule 폐기): `parseAllCandidates` deprecate 가 별 단계
- AI uptime / 수용률 데이터 1주 누적 후 D 의 안정성 평가
- `parseDueDate` 의 deprecate 시점: `parseAllCandidates` 로 모든 호출 마이그레이션 후
