From fac019e8a05d94f55cb60b8aab056353f52b2d8e Mon Sep 17 00:00:00 2001 From: altair823 Date: Sat, 25 Apr 2026 17:14:38 +0900 Subject: [PATCH] docs(spec): convert due-date stub into dogfood-feedback collection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reframe the file as a living register for in-flight dogfood feedback rather than a single-feature stub. Each item carries a status label (raw / drafting / ready-for-spec / promoted / rejected) and a fixed six-slot template (관찰 / 제안 방향 / 결정 대기 / 가설·측정 / 범위 / 영향). Items graduate to their own spec file once mature; the entry here then collapses to a one-line link. - F1: Due-date 추출 (drafting) — content from the previous stub normalized to the new template. - F2: 태그 클릭 = 즉시 삭제 + undo 부재 (raw) — NoteCard.tsx:110 binds chip onClick to removeTag, no confirm or undo, and there is no "filter by tag" affordance to match the user's mental model. Direction: split click=filter, ✕-icon=remove with 5s undo toast. README docs map updated to point at the new path. Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 2 +- .../specs/2026-04-25-dogfood-feedback.md | 164 +++++++++++++++ .../2026-04-25-due-date-extraction-design.md | 188 ------------------ 3 files changed, 165 insertions(+), 189 deletions(-) create mode 100644 docs/superpowers/specs/2026-04-25-dogfood-feedback.md delete mode 100644 docs/superpowers/specs/2026-04-25-due-date-extraction-design.md diff --git a/README.md b/README.md index 0990c40..8cd9243 100644 --- a/README.md +++ b/README.md @@ -163,7 +163,7 @@ inkling.md 원본 제품 브리프 v1.4 | 심리학 전략 | `docs/superpowers/strategy/strategy.md` | 행동 변화 모델, 회복 친화 스트릭 | | Dogfooding 전략 | `docs/superpowers/strategy/dogfood-strategy.md` | 2주 자기 dogfood 운영안 | | 슬라이스 설계 | `docs/superpowers/specs/2026-04-24-inkling-vertical-slice-design.md` | v0.4 spec, 부하 전달 결정의 출처 | -| Due Date 추출 (stub) | `docs/superpowers/specs/2026-04-25-due-date-extraction-design.md` | 슬라이스 dogfood 후 정식화할 후속 spec 골격 | +| Dogfood 피드백 | `docs/superpowers/specs/2026-04-25-dogfood-feedback.md` | 슬라이스 dogfood 중 발견된 본인 피드백 수집 (living document) | | 구현 계획 | `docs/superpowers/plans/2026-04-24-inkling-vertical-slice.md` | 33-task TDD 플랜 | | 핸드오프 | `docs/handoff/2026-04-25-linux-to-windows.md` | Linux→Windows 전환 메모 | diff --git a/docs/superpowers/specs/2026-04-25-dogfood-feedback.md b/docs/superpowers/specs/2026-04-25-dogfood-feedback.md new file mode 100644 index 0000000..cb2cf2e --- /dev/null +++ b/docs/superpowers/specs/2026-04-25-dogfood-feedback.md @@ -0,0 +1,164 @@ +# Dogfood 피드백 수집 + +**작성일:** 2026-04-25 (open) +**저자:** 김태현 (dlsrks0734@gmail.com) +**문서 성격:** 슬라이스 v0.4 dogfood 중 발견된 본인 피드백을 수집·정제하는 living document. 각 항목은 후속 spec 으로 승격될 후보다. 정식 spec 이 분기될 만큼 성숙하면 별도 파일로 추출하고 여기엔 링크만 남긴다. + +**선행 문서:** +- `docs/superpowers/specs/2026-04-24-inkling-vertical-slice-design.md` v0.4 (슬라이스 본문) +- `docs/superpowers/strategy/strategy.md` (심리학 전략) +- `docs/superpowers/strategy/dogfood-strategy.md` (dogfood 운영안 — 본 문서와 의존 없음) + +--- + +## 0. 사용 규칙 + +- 새 피드백은 다음 번호 (`F`) 로 추가. 절대 기존 번호 재사용 금지 (외부 링크 안전성). +- 각 항목 상단에 상태 라벨 한 줄: + - 🌱 **raw** — 막 적은 관찰. 가공 안 됨. + - 🔬 **drafting** — 범위·가설·결정 대기 항목 분석 중. + - 📝 **ready-for-spec** — 정식 spec 으로 승격 가능. 다음 단계는 별도 파일 추출. + - 🚀 **promoted** — 별도 spec 파일로 분기 완료. 본 문서엔 요약 + 링크만. + - ❌ **rejected** — 가설 미달 또는 우선순위 외, 닫음. +- 각 항목의 표준 슬롯: **관찰 / 제안 방향 / 결정 대기 / 가설·측정 / 범위 / 영향**. 슬롯이 비어 있으면 비워두고 채워질 때 갱신. + +--- + +## F1. Due Date 추출 (🔬 drafting) + +**발견:** 2026-04-25 dogfood 시작 직전 사고 실험. + +### 관찰 + +캡처된 노트 본문에 `오늘`, `내일`, `이번 주`, `다음 주`, `다음 달`, `N일 뒤`, `N월 N일`, `금요일까지` 같은 시간 표현이 자주 들어간다. 현재 슬라이스는 이걸 그냥 평문 본문에 두고 끝. 사용자는 노트가 "언제까지 해야 하는 일" 인지 다시 본문을 읽어 파악해야 한다. + +### 제안 방향 + +**하이브리드 — 규칙 파서 1차, AI 위임 2차.** + +``` +입력 텍스트 + ↓ +규칙 파서 (정규식 + KST 변환) + ↓ +매칭 있음? ──→ ISO YYYY-MM-DD + confidence: high + │ + └─ 시간 후보 어휘 감지 + 매칭 없음 ──→ AI 프롬프트에 due_date 필드 추가 + ↓ + AI 응답에 ISO 있음? ──→ confidence: medium + AI 응답 비었음? ──→ due_date null +``` + +규칙 파서는 결정론적·테스트 쉬움. AI 위임은 같은 generate 응답에 필드만 추가 — 별도 호출 없음. UI 라벨은 작은 회색 `📅 YYYY-MM-DD`, AI 라벨 정책과 동일하게 사용자 편집 시 진해지고 라벨 사라짐 (Strategy §7-원칙4 "AI 확신도 낮게"). + +### 결정 대기 + +1. 시간 표현이 들어간 노트 비율 — 누적 50건 표본 분류 (가설 H1) +2. "오늘 PR 리뷰" 같은 노트의 due 가 정말 오늘인가, 단순 맥락어인가? false positive 비율 +3. due_date 가 있는 노트의 재방문 트리거 — Inbox 정렬 / 별도 뷰 / 알림 중 어디 +4. NoteCard 의 라벨 슬롯 위치 — 제목 옆, 태그 옆, 별도 줄 +5. 만료된 노트 처리 — 자동 done ❌, 자동 삭제 ❌, 시각적 표시만? 별도 필터? +6. 음력·"월말"·"주말 안에" 등 모호 표현은 AI 위임만으로 충분한가 + +### 가설·측정 + +| # | 가설 | 측정 | +|---|------|------| +| H1 | 누적 캡처 노트 중 시간 표현 포함 비율 ≥ 30% | 표본 50건 본인 라벨링 | +| H2 | 규칙 파서가 일상 한국어 시간 표현의 ≥ 80% 정확 변환 | 골든 픽스처 50건 + 단위 테스트 | +| H3 | due_date 후보 수락률 ≥ 60% | 정식 출시 후 측정 | + +H1 이 미달이면 본 항목 ❌ rejected. + +### 범위 + +- **In:** `오늘`/`내일`/`모레`, `이번/다음 주`, `다음 달`, `N일·주·개월 뒤`, `N월 N일`, `MM/DD`, `YYYY-MM-DD`, KST 자정 기준 +- **Out:** 시각 단위 (`오후 3시`), 음력·절기, 반복 일정 (`매주 월요일`), 외부 캘린더 연동 + +### 영향 + +- **Schema:** migration v2 — `notes.due_date TEXT`, `notes.due_date_edited_by_user INTEGER NOT NULL DEFAULT 0` +- **NoteRepository:** `updateAiResult` 시그니처에 `dueDate?: string | null`, edited-flag CASE WHEN 가드. 신규 `setDueDate(noteId, date)` +- **AI:** zod 스키마에 `due_date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).nullable().optional()`, 프롬프트 끝에 "추출 가능하면 ISO, 아니면 null" + `{{TODAY_KST}}` 주입 +- **Renderer:** NoteCard 라벨 슬롯, EditableField 재사용, 만료 시 회색 + 취소선 (단어는 "실패"/"지각" 금지 — slice §1.1 카피 정책) +- **Lib:** 외부 의존성 0 권장. 자체 정규식 + Intl.DateTimeFormat. ContinuityService 의 KST 헬퍼 재사용 + +### 골든 픽스처 후보 + +``` +"오늘 PR 리뷰" → null 또는 today (양가) +"내일 회의 준비" → tomorrow +"다음 주 월요일까지 슬라이드" → next-mon +"3일 뒤 데모" → today+3 +"5월 1일 휴가 신청" → 2026-05-01 +"이번 주 안에 리팩터링" → 이번 주 일요일 +"월말 마감" → 해당 월 말일 (AI 위임) +"주말까지" → 이번 주 일요일 (AI 위임) +"퇴근 전" → today (시각 단위 fallback) +``` + +각 케이스의 confidence + 가설 행동(수락/편집/무시) 라벨링이 H2/H3 측정의 근거. + +--- + +## F2. 태그 클릭 = 즉시 삭제 + undo 부재 (🌱 raw) + +**발견:** 2026-04-25 dogfood 중. 슬라이스 v0.4 동작. + +### 관찰 + +`NoteCard.tsx:110` 에서 태그 칩의 `onClick` 이 `removeTag(t.name)` 으로 묶여 있다. 즉시 DB 에 반영되고, 확인 다이얼로그도 undo 도 없다. hover title 은 "클릭으로 제거" 로 의도된 동작이지만, 사용자는 태그 UI 의 일반적 관행 (클릭 = 동일 태그 노트 필터링) 을 기대했다. + +문제 두 갈래: + +1. **기능 부재:** "이 태그를 가진 노트만 보기" 가 슬라이스에 없음. 사용자 멘탈 모델과 어긋남. +2. **데이터 손실 마찰:** 평범한 클릭 한 번으로 AI 가 만든 태그가 사라지는데 되돌릴 수 없음. 슬라이스 §1.1 의 "AI 라벨 → 사용자 편집으로 전환" 정체성 흐름과도 충돌 — 삭제는 편집이 아니라 파괴. + +### 제안 방향 + +세 동작을 분리한다. + +| 동작 | 트리거 | 결과 | +|------|--------|------| +| **필터** | 짧은 클릭 | Inbox 가 동일 태그 노트만 표시 (헤더에 "필터: #tag · 해제" 칩) | +| **편집** | 칩 더블클릭 또는 칩 우측 작은 ✕ 아이콘 | 태그 이름 인라인 편집 또는 단일 태그 제거 | +| **재추가 (undo)** | 방금 제거한 직후 토스트 "태그 'foo' 를 제거했습니다 · 되돌리기" 5초 노출 | 클릭 시 즉시 복원 | + +권장 1차 패치 (작음): 클릭 = 필터로 변경 + 칩에 ✕ 아이콘 추가 (✕ 클릭 시 confirm 또는 5초 undo 토스트). 필터는 zustand 상태에 `tagFilter: string | null` 추가 + Inbox 의 `notes.filter` 단계 한 줄. + +권장 2차 (별 spec): 다중 태그 필터 (AND/OR), 태그 편집 (rename / merge), 태그 단위 일괄 작업. + +### 결정 대기 + +1. 클릭 = 필터 라는 가정이 dogfood 본인에게도 성립하는가? — 본인 예상 동작 한 번 더 셀프 체크 +2. AI 태그 vs 사용자 추가 태그 클릭 동작이 같아야 하는가, 달라야 하는가? +3. undo 토스트의 dismissal 정책 — 5초 자동 사라짐 vs 다음 작업까지 유지 +4. 필터링 시 Continuity 배지·Pending 배너의 카운트는 전체 기준인가, 필터된 부분 기준인가? +5. 태그 단일 제거 외에 "이 태그가 붙은 모든 노트에서 제거" 같은 일괄 작업도 묶을지 — 별 spec 으로 분리 권장 + +### 가설·측정 + +| # | 가설 | 측정 | +|---|------|------| +| H1 | 슬라이스의 현재 "클릭 = 삭제" 가 본인 dogfood 에서 ≥ 1회 실수 유발 | 일일 로그의 마찰 사건 | +| H2 | 클릭 = 필터로 바꾸면 본인이 태그를 통해 과거 노트를 재방문하는 빈도 ≥ 주 1회 | 사용 로그 | +| H3 | undo 토스트가 있으면 의도된 태그 제거의 인지 부담 감소 | 정성 평가 | + +### 범위 + +- **In:** 단일 태그 클릭 동작 변경, 단일 태그 제거 시 undo, Inbox 의 단일 태그 필터 +- **Out:** 다중 태그 필터, 태그 rename / merge, 태그 단위 일괄 작업, 태그 자동완성 + +### 영향 + +- **Schema:** 없음 (이 패치 자체는 DB 변경 없음. 일괄 작업이 들어오면 별 spec) +- **Renderer:** `NoteCard.tsx` 의 칩 `onClick` 변경, 칩 우측 ✕ 아이콘 추가, Inbox `App.tsx` 에 필터 상태 + 헤더 칩, undo 토스트 컴포넌트 (RecoveryToast 패턴 재사용 가능) +- **Store:** zustand `tagFilter` 상태 + `setTagFilter`, `notes` 셀렉터에 필터 적용 +- **API:** 변경 없음 (필터는 클라이언트 사이드만) +- **카피:** 슬라이스 §1.1 "실패"/"끊김"/"연속 실패" 금지 정책 그대로. undo 토스트 문구는 "되돌리기" / "방금 제거" 같은 중립 표현 + +--- + +## (다음 항목 자리) + +새 피드백 추가 시 `## F3. 짧은 제목 (🌱 raw)` 헤더로 시작. 표준 슬롯 6개 채우거나 비워둔 채 시작 가능. diff --git a/docs/superpowers/specs/2026-04-25-due-date-extraction-design.md b/docs/superpowers/specs/2026-04-25-due-date-extraction-design.md deleted file mode 100644 index 6e9756f..0000000 --- a/docs/superpowers/specs/2026-04-25-due-date-extraction-design.md +++ /dev/null @@ -1,188 +0,0 @@ -# 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.md` v0.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) - -```sql -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 을 정식화하기 전 답해야 할 항목 — 누적 캡처 표본·자체 사고 실험·라이브러리 비교 등으로 결론 도달: - -1. **얼마나 자주 시간 표현이 들어가나?** (H1 검증, 표본 50건 분류) -2. **"오늘 PR 리뷰"** 같은 노트는 due 가 정말 오늘인가, 아니면 단순 맥락어인가? — false positive 비율 추정 -3. **due_date 가 있는 노트를 다시 보고 싶은 트리거는 무엇인가?** (Inbox 자체 / 별도 뷰 / 알림) -4. **`📅` 라벨이 NoteCard 의 어느 슬롯에 붙어야 자연스러운가?** (제목 옆, 태그 옆, 별도 줄) -5. **AI 가 추출한 due_date 가 틀렸을 때 사용자가 어떻게 알아채나?** — 카피·색조로 confidence 차이를 충분히 전달할 수 있나 -6. **만료된 노트를 별도 필터로 보고 싶은가, 아니면 인라인 처리만으로 충분한가?** - ---- - -## 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