F3 + F4-E 카피 정리 (v0.2.1 dogfood-feedback Track #6) #7
@@ -373,7 +373,7 @@ Rules:
|
||||
- 화면 중앙, 포커스 자동 획득
|
||||
- 단일 textarea + 썸네일 스트립 (이미지 있을 때만)
|
||||
- placeholder: "지금 머릿속에 있는 것 한 줄. 정리는 나중입니다."
|
||||
- 하단 힌트: "Ctrl+Enter 구출 · Esc 취소 · 이미지 붙여넣기"
|
||||
- 하단 힌트: "Ctrl+Enter 저장 · Esc 취소 · 이미지 붙여넣기"
|
||||
│
|
||||
├─ 사용자 타이핑 / Ctrl+V (이미지)
|
||||
│ └─ 클립보드 이미지 감지 → 썸네일 추가 (메모리 버퍼)
|
||||
@@ -399,8 +399,8 @@ Rules:
|
||||
- 채널: OS 네이티브 알림 (`new Notification(title, {body, silent})`). Inbox in-app 토스트 아님 — 사용자가 작업 중인 다른 앱 위에 즉시 떠야 보상 즉시성을 살림.
|
||||
- 회전 카피 4종 (noteId 해시 mod 4로 결정론적 선택):
|
||||
1. "이 생각은 이제 Inkling이 들고 있습니다."
|
||||
2. "나중에 찾을 수 있게 보관했습니다."
|
||||
3. "방금 하나의 업무 기억을 구출했습니다."
|
||||
2. "머릿속에서 꺼내 두었습니다."
|
||||
3. "방금 한 줄 잡아뒀습니다."
|
||||
4. "기록 완료. 이제 잊어도 됩니다."
|
||||
- 권한: 첫 submit 시 OS 권한 다이얼로그. 거부 시 무음 폴백 (캡처는 정상 동작).
|
||||
- 알림 본문에는 `raw_text`나 `ai_title`을 포함하지 않는다. 오직 회전 카피만 표시 (PII 보호와 일관성).
|
||||
@@ -503,7 +503,7 @@ Rules:
|
||||
Slice는 온보딩 위자드를 제공하지 않는다.
|
||||
|
||||
1. 최초 기동 시 `{userData}/Inkling/profiles/default/`가 자동 생성된다.
|
||||
2. Inbox 창이 열리고 빈 상태 메시지("첫 기억을 구출해보세요. `Ctrl+Shift+J`")가 노출된다.
|
||||
2. Inbox 창이 열리고 빈 상태 메시지("머릿속에 떠다니는 한 줄을 적어보세요. `Ctrl+Shift+J`")가 노출된다.
|
||||
3. Ollama 헬스 체크가 실행되고 결과에 따라 배너가 표시된다.
|
||||
|
||||
### 5.4 카피 카탈로그
|
||||
@@ -513,14 +513,14 @@ Slice는 온보딩 위자드를 제공하지 않는다.
|
||||
| 위치 | 문구 |
|
||||
|------|------|
|
||||
| QuickCapture placeholder | 지금 머릿속에 있는 것 한 줄. 정리는 나중입니다. |
|
||||
| QuickCapture hint | Ctrl+Enter 구출 · Esc 취소 · 이미지 붙여넣기 |
|
||||
| QuickCapture hint | Ctrl+Enter 저장 · Esc 취소 · 이미지 붙여넣기 |
|
||||
| QuickCapture 제출 실패 | 저장에 실패했습니다. 다시 시도해주세요. |
|
||||
| QuickCapture 취소 confirm (5자+) | 이 한 줄을 흘려보낼까요? |
|
||||
| Inbox 빈 상태 | 첫 기억을 구출해보세요. `Ctrl+Shift+J` |
|
||||
| Inbox 빈 상태 | 머릿속에 떠다니는 한 줄을 적어보세요. `Ctrl+Shift+J` |
|
||||
| Inbox 처리 중 카드 | Inkling이 정리하는 중… |
|
||||
| Inbox AI 실패 카드 | 정리 보류 — 원문은 안전합니다 |
|
||||
| 트레이 메뉴: Quick Capture | 기억 구출하기 |
|
||||
| 트레이 메뉴: Inbox 열기 | 구출한 메모 보기 |
|
||||
| 트레이 메뉴: Quick Capture | 한 줄 적기 |
|
||||
| 트레이 메뉴: Inbox 열기 | 보관한 메모 보기 |
|
||||
| 트레이 메뉴: Quit | 종료 |
|
||||
| 삭제 confirm | 이 기억을 버릴까요? 되돌릴 수 없습니다. |
|
||||
| Continuity 0건 | 이번 주 한 줄이면 시작입니다 |
|
||||
|
||||
@@ -163,7 +163,9 @@ H1 이 미달이면 본 항목 ❌ rejected.
|
||||
|
||||
---
|
||||
|
||||
## F3. "구출" 카피가 한국어로 어색함 (🌱 raw)
|
||||
## F3. "구출" 카피가 한국어로 어색함 (🚀 promoted)
|
||||
|
||||
**Promoted →** `docs/superpowers/specs/2026-04-26-f3-f4e-copy.md` (F4-E 와 함께 한 PR)
|
||||
|
||||
**발견:** 2026-04-26 dogfood 첫날, 메모 1건 캡처 후 OS 토스트 알림에서 "방금 하나의 업무 기억을 구출했습니다" 문구가 떴을 때.
|
||||
|
||||
@@ -272,6 +274,10 @@ H1 이 미달이면 본 항목 ❌ rejected.
|
||||
|
||||
**발견:** 2026-04-26 dogfood 시작 직전 사고 실험. 슬라이스 v0.4 와 strategy.md §3 가 **이미 알고 있는 contextual cue** (회의 후, 퇴근 전, 디버깅 후) 의 if-then 만 다루고, **ambient/spontaneous 떠오름** (샤워, 산책, 대화 중, 자기 전) 은 사각지대.
|
||||
|
||||
**진행 상태:**
|
||||
- E (Zeigarnik priming) — 🚀 promoted → `docs/superpowers/specs/2026-04-26-f3-f4e-copy.md`
|
||||
- A·B·C·D·F — 🌱 raw, 측정 후 결정
|
||||
|
||||
### 관찰
|
||||
|
||||
캡처 자체의 마찰은 거의 0 — `Ctrl+Shift+J` + 한 줄 + Enter = 3초. 하지만 dogfood 의 진짜 실패 모드는 **"3초가 너무 길다"** 가 아니라 **"그 3초가 머릿속에 안 떠오른다"** 다. 떠오름 → Inkling 연상 사이의 인지적 다리가 약하면, 메모 자체가 시도되지 않는다.
|
||||
|
||||
35
docs/superpowers/specs/2026-04-26-f3-f4e-copy.md
Normal file
35
docs/superpowers/specs/2026-04-26-f3-f4e-copy.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# F3 + F4-E Copy Spec (Promoted)
|
||||
|
||||
**Extracted from:** `2026-04-25-dogfood-feedback.md` F3, F4 §"E. Zeigarnik 효과 활용"
|
||||
**Status:** 🚀 promoted — implemented 2026-04-26
|
||||
|
||||
## 결정 (mini-brainstorm 결과)
|
||||
|
||||
| 결정 | 값 | 근거 |
|
||||
|------|-----|------|
|
||||
| F3 단일 vs 분배 | 표면별 자연 동사 (꺼내 두다 / 잡아두다 / 한 줄 적다 / 보관) | 자연스러움 > 브랜딩 통일 |
|
||||
| Strategy.md 동반 갱신 | YES — §1, §4.1, §7 | 어휘 일관성 |
|
||||
| 회전 카피 4종 | #2, #3 교체 (#1, #4 유지) | 톤 보존 + 핵심 변경 최소화 |
|
||||
| F4-E priming 위치 | Inbox 빈 상태 (가장 첫 사용 순간) | Zeigarnik 효과 자극 시점 |
|
||||
| Package description | 동반 갱신 (외부 노출 표어) | code-spec 드리프트 차단 |
|
||||
| e2e smoke 단언 | 직접 카피 단언 갱신 (selector 약화 X) | 카피 정책 변경 시 의도된 e2e 업데이트 |
|
||||
|
||||
## 신규 카피 (코드 표면별)
|
||||
|
||||
| 표면 | 신규 |
|
||||
|------|-----|
|
||||
| 트레이: Inbox 열기 | 보관한 메모 보기 |
|
||||
| 트레이: 새 메모 | 한 줄 적기 |
|
||||
| 토스트 #1 | (변경 없음) 이 생각은 이제 Inkling이 들고 있습니다. |
|
||||
| 토스트 #2 | 머릿속에서 꺼내 두었습니다. |
|
||||
| 토스트 #3 | 방금 한 줄 잡아뒀습니다. |
|
||||
| 토스트 #4 | (변경 없음) 기록 완료. 이제 잊어도 됩니다. |
|
||||
| Inbox 빈 상태 | 머릿속에 떠다니는 한 줄을 적어보세요. |
|
||||
| QC 힌트 | Ctrl+Enter 저장 · Esc 취소 · 이미지 붙여넣기 |
|
||||
| package.json description | Inkling — local-first 한 줄 보관 도구 |
|
||||
|
||||
## 후속
|
||||
|
||||
- 회전 카피 4종 전면 재작성 (현재 #1, #4 만 보존, 다른 변형 도입 가능)
|
||||
- onboarding 흐름 카피 (슬라이스 외)
|
||||
- 다국어 (영어 카피)
|
||||
@@ -4,17 +4,17 @@ Inkling 심리학 기반 습관화 전략
|
||||
|
||||
핵심은 사용자를 “메모 잘하는 사람”으로 훈련시키는 것이 아니라, 메모가 즐겁고 즉시 쓸모 있으며, 반복할수록 업무 불안을 줄여주는 행동 루프를 만드는 것입니다.
|
||||
|
||||
1. 핵심 행동 정의를 바꾼다: “메모 작성”이 아니라 “기억 구출”
|
||||
1. 핵심 행동 정의를 바꾼다: “메모 작성”이 아니라 “머릿속에서 꺼내 두기”
|
||||
|
||||
메모를 하지 않던 사람에게 “메모를 잘 써라”는 요구는 너무 큽니다. Inkling의 최소 행동은 다음처럼 재정의해야 합니다.
|
||||
|
||||
메모 = 지금 머릿속에 있는 것을 잊기 전에 바깥으로 꺼내는 1회 행동
|
||||
|
||||
즉, 사용자가 해야 할 일은 “정리”가 아니라 구출입니다. 정리는 AI와 나중의 리뷰가 담당합니다.
|
||||
즉, 사용자가 해야 할 일은 “정리”가 아니라 꺼내 두기입니다. 정리는 AI와 나중의 리뷰가 담당합니다.
|
||||
|
||||
제품 문구도 이렇게 바꿉니다.
|
||||
|
||||
“새 메모 작성” → “기억 구출하기”
|
||||
“새 메모 작성” → “한 줄 적기”
|
||||
“제목을 입력하세요” → “한 줄만 던져도 됩니다”
|
||||
“분류 선택” → “나중에 Inkling이 찾아드립니다”
|
||||
“저장 완료” → “이제 이 생각은 잊어도 됩니다”
|
||||
@@ -108,12 +108,14 @@ Gollwitzer의 실행 의도 연구는 “언제/어디서/무엇을 할지”를
|
||||
|
||||
“좋아요. 이 생각은 이제 Inkling이 들고 있습니다.”
|
||||
|
||||
“나중에 찾을 수 있게 보관했습니다.”
|
||||
“머릿속에서 꺼내 두었습니다.”
|
||||
|
||||
“방금 하나의 업무 기억을 구출했습니다.”
|
||||
“방금 한 줄 잡아뒀습니다.”
|
||||
|
||||
이는 “메모 = 귀찮은 일”이 아니라 메모 = 인지적 부담을 줄이는 행동으로 느끼게 합니다. 인지적 오프로딩 연구는 사람들이 외부 도구를 사용해 내부 기억·주의 부담을 줄인다는 점을 설명합니다.
|
||||
|
||||
회전 카피의 톤은 Zeigarnik 효과(미완결 과제가 머릿속에 남아 주의 자원을 잡아먹는 현상)를 외재화로 해소한다는 framing 으로 옮겼습니다 — F4-E. “꺼내 두다 / 잡아두다” 동사는 “머리에서 외부로 옮겨두면 더 이상 떠올라 괴롭히지 않는다” 라는 인지 부담 해소 감각을 직접 환기합니다.
|
||||
|
||||
4.2 능력감 보상: “내가 일을 잘 관리하고 있다”
|
||||
|
||||
자기결정성이론은 사람의 지속 동기에 자율성, 유능감, 관계성이 중요하다고 봅니다. Inkling은 사용자를 통제하기보다 선택권을 주고, 작은 성공을 보여주고, 동료에게 도움이 되는 연결을 만들어야 합니다.
|
||||
@@ -320,7 +322,7 @@ Week 0: 첫 성공
|
||||
|
||||
성공 문구:
|
||||
|
||||
“첫 번째 기억을 구출했습니다. 이제 Inkling이 당신의 업무 맥락을 쌓기 시작합니다.”
|
||||
“첫 한 줄을 잡아뒀습니다. 이제 Inkling이 당신의 업무 맥락을 쌓기 시작합니다.”
|
||||
|
||||
Week 1–2: 마찰 제거
|
||||
|
||||
@@ -358,7 +360,7 @@ Week 5–8: 정체성 강화
|
||||
|
||||
주간 리포트 예:
|
||||
|
||||
이번 주 Inkling이 구출한 업무 기억
|
||||
이번 주 Inkling이 잡아둔 업무 기억
|
||||
결정 근거 4개
|
||||
트러블슈팅 2개
|
||||
다음 주 액션 후보 5개
|
||||
@@ -420,7 +422,7 @@ A안:
|
||||
|
||||
B안:
|
||||
|
||||
“이번 주 결정 근거 3개를 구출했습니다.”
|
||||
“이번 주 결정 근거 3개를 잡아뒀습니다.”
|
||||
|
||||
가설:
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "inkling",
|
||||
"version": "0.2.0",
|
||||
"private": true,
|
||||
"description": "Inkling — local-first 기억 구출 도구",
|
||||
"description": "Inkling — local-first 한 줄 보관 도구",
|
||||
"author": "altair823 <dlsrks0734@gmail.com>",
|
||||
"main": "out/main/index.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -2,8 +2,8 @@ import { createHash } from 'node:crypto';
|
||||
|
||||
export const REWARD_COPIES = [
|
||||
'이 생각은 이제 Inkling이 들고 있습니다.',
|
||||
'나중에 찾을 수 있게 보관했습니다.',
|
||||
'방금 하나의 업무 기억을 구출했습니다.',
|
||||
'머릿속에서 꺼내 두었습니다.',
|
||||
'방금 한 줄 잡아뒀습니다.',
|
||||
'기록 완료. 이제 잊어도 됩니다.'
|
||||
] as const;
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@ function buildMenu(
|
||||
runImport: () => void
|
||||
) {
|
||||
const items: MenuItemConstructorOptions[] = [
|
||||
{ label: '구출한 메모 보기', click: showInbox },
|
||||
{ label: '기억 구출하기', click: showCapture },
|
||||
{ label: '보관한 메모 보기', click: showInbox },
|
||||
{ label: '한 줄 적기', click: showCapture },
|
||||
{ type: 'separator' },
|
||||
{ label: '지금 백업', click: runBackup },
|
||||
{ label: '내보내기...', click: runExport },
|
||||
|
||||
@@ -85,7 +85,7 @@ export function App(): React.ReactElement {
|
||||
{loading && notes.length === 0 ? (
|
||||
<div className="empty">불러오는 중…</div>
|
||||
) : notes.length === 0 ? (
|
||||
<div className="empty">첫 기억을 구출해보세요. <code>Ctrl+Shift+J</code></div>
|
||||
<div className="empty">머릿속에 떠다니는 한 줄을 적어보세요. <code>Ctrl+Shift+J</code></div>
|
||||
) : filtered.length === 0 ? (
|
||||
<div className="empty">이 태그의 노트가 없습니다.</div>
|
||||
) : (
|
||||
|
||||
@@ -65,7 +65,7 @@ export function App(): React.ReactElement {
|
||||
{images.map((i, idx) => (<img key={idx} src={i.url} alt="" />))}
|
||||
</div>
|
||||
)}
|
||||
<div className="hint">Ctrl+Enter 구출 · Esc 취소 · 이미지 붙여넣기</div>
|
||||
<div className="hint">Ctrl+Enter 저장 · Esc 취소 · 이미지 붙여넣기</div>
|
||||
{err && <div className="err">{err}</div>}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -26,6 +26,6 @@ test('inbox shell shows v0.2 empty state', async () => {
|
||||
}
|
||||
await inbox.waitForLoadState('load');
|
||||
await expect(inbox.getByRole('heading', { name: 'Inkling' })).toBeVisible();
|
||||
await expect(inbox.getByText('첫 기억을 구출해보세요.')).toBeVisible();
|
||||
await expect(inbox.getByText('머릿속에 떠다니는 한 줄을 적어보세요.')).toBeVisible();
|
||||
await app.close();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user