The due-date extraction work originated as feedback during dogfood, but the dogfood strategy doc itself should stay feature-agnostic — it's the generic operating manual for the 2-week dogfood, not a feedback log. - Remove the "시간 표현 포함 노트 수" row from dogfood-strategy §3.1. - Rephrase the due-date spec stub so H1 / §7 / §9 reference the spec's own sample-collection plan instead of relying on the dogfood retro. - Spec is now framed as "independent of slice exit"; entry timing is a separate decision once an accumulated sample meets H1. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
9.3 KiB
Inkling — Due Date 추출 설계 문서 (Stub)
작성일: 2026-04-25 (v0.1, stub) 저자: 김태현 (dlsrks0734@gmail.com) 상태: ⚠️ Stub — 슬라이스 v0.4 dogfood 중 발견된 피드백에서 출발. 본 문서는 후속 spec 의 골격과 결정 대기 항목만 담으며, 정식화 전에 §7 의 미정 항목들이 답해져야 한다. 선행 문서:
docs/superpowers/specs/2026-04-24-inkling-vertical-slice-design.mdv0.4 (슬라이스 본문)docs/superpowers/strategy/strategy.md§2.2 (Clarify 단계의 의미 부여), §7-원칙4 (AI 확신도 낮게)
0. 목적
캡처된 노트 본문에 시간 표현이 들어가면 (오늘, 내일, 이번 주, 다음 주, 다음 달, N일 뒤, N월 N일, 금요일까지 등) 로컬 KST 기준으로 ISO 날짜를 추출해 due_date 후보로 제안한다. AI 가 단정하지 않고 사용자가 수락·편집·무시할 수 있는 제안형 라벨로 노출한다 (Strategy §7-원칙4).
1. 가설
| # | 가설 | 측정 |
|---|---|---|
| H1 | 누적 캡처 노트 중 시간 표현 포함 비율이 ≥ 30% | 본 spec 자체 표본 — 누적 50건 노트의 본문을 정규식 + 본인 라벨링으로 분류 |
| H2 | 규칙 기반 파서가 일상 한국어 시간 표현의 ≥ 80% 를 정확히 변환 | 골든 픽스처 50건 + 단위 테스트 |
| H3 | due_date 후보 수락률 ≥ 60% (제안 중 사용자가 그대로 수락한 비율) | 정식 출시 후 측정 |
H1 이 미달이면 본 spec 자체가 불필요 — 정식화 전 H1 표본 평가가 먼저다.
2. 범위
2.1 In-scope
- 하이브리드 추출: 규칙 기반 파서가 1차 시도 → 매칭 없을 시에만 AI 프롬프트에 위임. 슬라이스의 비동기 AI 단계와 동일 큐에서 동작.
- 상대 표현:
오늘,내일,모레,이번 주 *요일,다음 주,다음 달,N일/N주/N개월 뒤. - 절대 표현:
N월 N일,YYYY-MM-DD,MM/DD. 연도 미명시 시 가까운 미래로 해석. - 기준 시점: KST 자정 (
Date.now()+Asia/Seoul시간대). ContinuityService 의 KST 주 경계 정의와 동일 라이브러리 재사용. - UI: NoteCard 에
📅 YYYY-MM-DD작은 회색 라벨. AI 라벨 정책과 동일하게 사용자 편집 시 라벨 사라짐. 인라인 편집/삭제 가능. - 수정 추적:
due_date_edited_by_user컬럼 추가, AI 재실행이 사용자 편집을 덮어쓰지 않음 (slice §3.3 invariant 2 와 동일 패턴).
2.2 Out-of-scope
- 캘린더 알림·스케줄러 (별도 spec)
- 시각 단위 추출 (
오후 3시,15:30) — 본 spec 은 날짜만, 시각은 후속 - 음력 / 절기 / "월말", "주말 안에" 같은 모호 표현 — AI 위임으로만 처리, 정확도 보장 안 함
- 반복 일정 (
매주 월요일) - 외부 캘린더 연동 (Google, Outlook)
3. 파서 vs AI 분기 정책
입력 텍스트
↓
규칙 파서 (정규식 + chrono-style)
↓
매칭 있음? ──→ ISO 날짜 + confidence: high
│
└─ 매칭 없음 + 시간 후보 어휘 감지 ──→ AI 프롬프트 확장 (due_date 필드)
↓
AI 응답에 ISO 있음? ──→ confidence: medium
AI 응답 비었음? ──→ due_date null
규칙 파서는 동기·결정론적·테스트 가능. AI 분기는 슬라이스의 AiWorker 큐를 그대로 사용 (별도 호출 추가 안 함, 같은 generate 응답에 필드 추가).
confidence 메타는 DB 에 저장하지 않고 UI 라벨 색조로만 표현 (high = 진한 회색, medium = 옅은 회색).
4. 데이터 변경
4.1 Migration v2 (forward-only)
ALTER TABLE notes ADD COLUMN due_date TEXT;
ALTER TABLE notes ADD COLUMN due_date_edited_by_user INTEGER NOT NULL DEFAULT 0;
due_date 형식: YYYY-MM-DD (KST 자정 기준). null = 추출 안 됨.
4.2 NoteRepository 변경
updateAiResult시그니처에dueDate?: string | null추가, edited-flag CASE WHEN 가드 적용setDueDate(noteId, date)사용자 수정 메서드 신설,due_date_edited_by_user = 1셋
4.3 zod 스키마 확장
AiResponse 에 due_date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).nullable().optional() 추가. AI 가 빈 응답 또는 잘못된 형식 반환 시 정상 누락 처리 (스키마 검증 실패로 전체 응답 reject 안 함 → strict → loose 변환).
5. 프롬프트 변경 (AI 분기 시에만)
기존 프롬프트 끝에 추가:
입력 텍스트에서 마감일 또는 일정 날짜를 의미하는 표현이 있으면 ISO 형식 (YYYY-MM-DD) 으로 추출. KST 기준 오늘은 {{TODAY_KST}}. 추출 불가능하면 null.
{{TODAY_KST}} 는 LocalOllamaProvider.generate 시점에 주입. 시간대 처리는 main process 에서.
6. UX 카피 (Strategy 준수)
| 상황 | 카피 |
|---|---|
| 추출 성공 | 📅 {YYYY-MM-DD} (작은 회색 라벨) |
| 사용자 편집 후 | 📅 {YYYY-MM-DD} (회색 → 검정, AI 라벨 제거) |
| 만료 임박 (≤ 1일) | 📅 {YYYY-MM-DD} 노란 배경 |
| 만료됨 | 📅 {YYYY-MM-DD} 회색 + 취소선. "실패", "지각", "놓침" 같은 단어 금지 (slice §1.1 카피 정책 상속) |
만료 노트 처리 정책은 본 spec 에서 결정 — 자동 삭제 ❌, 자동 done ❌, 단지 시각적 표시만.
7. 결정 대기 항목 (정식화 전 답할 질문)
본 spec 을 정식화하기 전 답해야 할 항목 — 누적 캡처 표본·자체 사고 실험·라이브러리 비교 등으로 결론 도달:
- 얼마나 자주 시간 표현이 들어가나? (H1 검증, 표본 50건 분류)
- "오늘 PR 리뷰" 같은 노트는 due 가 정말 오늘인가, 아니면 단순 맥락어인가? — false positive 비율 추정
- due_date 가 있는 노트를 다시 보고 싶은 트리거는 무엇인가? (Inbox 자체 / 별도 뷰 / 알림)
📅라벨이 NoteCard 의 어느 슬롯에 붙어야 자연스러운가? (제목 옆, 태그 옆, 별도 줄)- AI 가 추출한 due_date 가 틀렸을 때 사용자가 어떻게 알아채나? — 카피·색조로 confidence 차이를 충분히 전달할 수 있나
- 만료된 노트를 별도 필터로 보고 싶은가, 아니면 인라인 처리만으로 충분한가?
8. 단계별 산출물
본 spec 정식화 후 plan 작성 시 예상 task 묶음 (본 stub 시점에선 추정만):
- 데이터: migration v2, NoteRepository 시그니처 확장 (단위 테스트 포함)
- 추출:
DateExtractor모듈 (정규식 + 자체 KST 변환). 골든 픽스처 50건. AI 위임 분기 라우팅 - AI: schema/prompt 확장, AiWorker 응답 매핑 변경
- UI: NoteCard 라벨 슬롯, EditableField 재사용, 만료 색조
- 마이그레이션 안전성: 기존 노트의
due_date_edited_by_user = 0디폴트,due_date NULL처리 검증
9. Slice 와의 관계
본 spec 은 슬라이스 v0.4 와 독립이다. 슬라이스 dogfood 중 발견된 피드백이 출처지만, 슬라이스 종료 조건에는 포함되지 않는다.
- 슬라이스의 3 가설 (3초 마찰 / AI 품질 / 행동 루프) 중 어느 것도 due_date 없이 검증 가능
- migration v2 + 컬럼 2개 + UI 슬롯 = 작지 않은 변화. 슬라이스 invariant 2 ("AI 재실행은 user-edited 필드 덮어쓰기 금지") 의 적용 표면을 확장하므로 슬라이스 안정성이 먼저 검증된 상태에서 진입하는 게 안전
- 본 spec 의 정식화·실행 시점은 별개 결정 — 누적 표본으로 H1 충족이 확인되면 진입
10. 라이브러리 후보
| 라이브러리 | 평가 |
|---|---|
chrono-node |
영어·한국어 일부 지원, 활성. 한국어 커버리지가 핵심 표현 외에는 약함 |
| 자체 정규식 | 핵심 표현 (오늘, 내일, N일 뒤) 만 6~8개 패턴으로 충분. 결정론적·테스트 쉬움. 권장 |
dayjs + 사용자 정의 파서 |
한국어 표현은 직접 처리, 시간대 변환은 dayjs 의 tz 플러그인. 의존성 증가 |
권장: 자체 정규식 + Intl.DateTimeFormat + KST 변환 헬퍼. 외부 의존성 추가 없음, 슬라이스의 ContinuityService 가 이미 KST 변환 로직 보유 → 재사용.
부록 A. 골든 픽스처 후보 (정식화 시 확장)
"오늘 PR 리뷰" → null 또는 today (양가)
"내일 회의 준비" → tomorrow
"다음 주 월요일까지 슬라이드" → next-mon
"3일 뒤 데모" → today+3
"5월 1일 휴가 신청" → 2026-05-01
"이번 주 안에 리팩터링" → 이번 주 일요일
"월말 마감" → 해당 월 말일 (AI 위임 후보)
"주말까지" → 이번 주 일요일 (AI 위임 후보)
"퇴근 전" → today (시각 단위는 본 spec 범위 밖이지만 fallback)
각 케이스의 confidence 등급 + 사용자 가설 행동(수락 / 편집 / 무시)을 본 spec 정식화 시 본인이 직접 라벨링한다. 이 라벨링이 H2 / H3 측정의 근거.
부록 B. 미정 정책
- "오늘" 의 시간대 — 자정 기준인가, 24시간 후인가? (KST 자정으로 잠정 결정, 정식화 시 검증)
- 사용자 명시적 due_date 와 AI 추출 due_date 의 시각적 구분 (현재 안: AI 라벨 색조)
- due_date 검색·필터 UI — 본 spec 범위 vs 별도 spec