diff --git a/docs/12_core_loop_execution_roadmap.md b/docs/12_core_loop_execution_roadmap.md index 85f439d..8ba7c07 100644 --- a/docs/12_core_loop_execution_roadmap.md +++ b/docs/12_core_loop_execution_roadmap.md @@ -16,6 +16,8 @@ Last Updated: 2026-03-15 - `09_app_entry_detailed_spec.md` - `10_refocus_system_spec.md` - `11_away_return_recovery_spec.md` +- `15_app_stats_entry_flow_spec.md` +- `18_paused_session_reentry_spec.md` - `16_product_alignment_audit_plan.md` --- @@ -186,6 +188,26 @@ VibeRoom은 아래 방식으로 진행한다. - `14_weekly_review_reframe_spec.md` - `15_app_stats_entry_flow_spec.md` +### Phase 5.5. Session Routing / Paused Re-entry Alignment + +문서: + +- `18_paused_session_reentry_spec.md` + +목적: + +- `running focus -> /space` +- `running break -> /space` +- `paused focus -> /app` +- explicit continue 이후 `/space` auto-resume +- paused session 위의 new start를 takeover flow로만 허용 + +상태: + +- 상세 기획 문서 작성 완료 +- 구현 전 +- 다음 구현 slice + ### Phase 6. Premium Ambience System 목적: @@ -319,8 +341,9 @@ Away / Return이 끼어들기 전, 다음으로 예정된 축은 아래 두 가 ### 다음 대기 +- `Paused Session Re-entry` 구현 - `/space` recovery browser QA -- Weekly Review Reframe +- Weekly Review recovery 집계 연결 - Premium Ambience System ### 방금 완료 @@ -338,6 +361,10 @@ Away / Return이 끼어들기 전, 다음으로 예정된 축은 아래 두 가 - `/space`에서 goal complete로 setup 상태로 돌아온 직후에만 secondary review teaser가 보인다 - full review 강제 이동 없이 작은 후행 경로로 `/stats`를 연다 - 다음 구현은 weekly review의 실제 recovery 집계 연결이다 +- `Paused Session Re-entry` spec + - running / paused / break의 route policy를 한 문서에서 고정했다 + - `/app`은 paused session의 resume gate가 되고, explicit continue 이후 `/space`에서는 자동 resume해야 한다 + - paused session 위의 새 시작은 takeover flow로만 허용한다 --- diff --git a/docs/17_product_alignment_findings.md b/docs/17_product_alignment_findings.md index 1f027a8..6f49817 100644 --- a/docs/17_product_alignment_findings.md +++ b/docs/17_product_alignment_findings.md @@ -67,6 +67,7 @@ Last Updated: 2026-03-15 | ALN-007 | P2 | Weekly Review discoverability | review는 `/app`의 primary ritual이어야 함 | 데이터 gate와 currentSession 조건에 따라 사용자에게 “아예 없는 기능”처럼 느껴질 수 있음 | `src/widgets/focus-dashboard/ui/FocusDashboardWidget.tsx`, `docs/15_app_stats_entry_flow_spec.md` | open | low-data 상태와 resume 상태를 포함한 discoverability 정책 재정의 | | ALN-008 | P1 | `잠시 비우기`와 `Break`의 제품 의미 | break는 reward/reset, pause는 recovery로 분리돼야 함 | 현재는 카피와 트레이는 개선됐지만, 제품 차원의 최종 정의와 시각 분리까지 완전히 닫히진 않았음 | `docs/10_refocus_system_spec.md`, `docs/11_away_return_recovery_spec.md`, `src/widgets/space-focus-hud/ui/GoalCompleteSheet.tsx`, `src/widgets/space-focus-hud/ui/ReturnPrompt.tsx` | open | `잠시 비우기`, active break, return(break)를 하나의 최종 state model로 재정의 | | ALN-009 | P3 | Spec / current-state drift | 다음 세션 문서가 실제 구현과 맞아야 함 | intent card, goal complete, review entry 관련 오래된 표현이 여러 spec에 남아 있었음 | `docs/10_refocus_system_spec.md`, `docs/13_space_intent_card_collapsed_expanded_spec.md`, `docs/90_current_state.md`, `docs/session_brief.md`, `../../current_context.md` | fixed-awaiting-browser | 이후 라운드부터는 fix와 문서 갱신을 같은 커밋에서 닫는지 점검 | +| ALN-010 | P1 | paused session 재진입 정책 | running은 바로 `/space`, paused는 `/app` resume gate, explicit continue 이후에는 자동 resume이어야 함 | 현재 route / CTA / handoff 규칙이 문서 하나로 고정돼 있지 않아, `/app`, `/space`, review 진입의 상태 의미가 다시 흔들릴 수 있음 | `docs/18_paused_session_reentry_spec.md`, `src/widgets/focus-dashboard/ui/FocusDashboardWidget.tsx`, `src/widgets/space-workspace/ui/SpaceWorkspaceWidget.tsx`, `src/features/focus-session/model/useFocusSessionEngine.ts` | open | `18_paused_session_reentry_spec.md` 기준으로 routing, paused resume gate, auto-resume handoff, takeover flow를 순서대로 구현 | --- @@ -85,6 +86,7 @@ Last Updated: 2026-03-15 - `Goal Complete` 2단계 구조의 인지 부담 - low-data / resume 상태에서 review discoverability - `잠시 비우기`와 진짜 break의 최종 state model +- paused session의 route / resume / takeover contract --- @@ -115,9 +117,10 @@ Last Updated: 2026-03-15 ### 3. 다음 수정 라운드의 우선순위 -1. ALN-008 -2. ALN-006 -3. ALN-007 +1. ALN-010 +2. ALN-008 +3. ALN-006 +4. ALN-007 --- diff --git a/docs/18_paused_session_reentry_spec.md b/docs/18_paused_session_reentry_spec.md new file mode 100644 index 0000000..066111c --- /dev/null +++ b/docs/18_paused_session_reentry_spec.md @@ -0,0 +1,459 @@ +# 18. Paused Session Re-entry Spec + +Last Updated: 2026-03-15 + +이 문서는 VibeRoom에서 **진행 중인 세션 / 멈춘 세션 / 쉬는 시간**을 어떻게 다르게 취급할지, +그리고 사용자가 `/app`에 들어왔을 때 어떤 경로로 다시 `/space`에 진입해야 하는지를 정의한다. + +핵심 목적은 하나다. + +> session state에 따라 `/app`과 `/space`의 역할을 정확히 나누고, +> 사용자가 “지금 내가 어떤 상태인지”를 설명할 수 있는 premium UX를 만든다. + +관련 문서: + +- `09_app_entry_detailed_spec.md` +- `10_refocus_system_spec.md` +- `11_away_return_recovery_spec.md` +- `15_app_stats_entry_flow_spec.md` +- `16_product_alignment_audit_plan.md` +- `17_product_alignment_findings.md` +- `../../product_principles.md` +- `../../current_context.md` + +--- + +## 1. 문제 정의 + +지금까지의 혼란은 대부분 여기서 시작됐다. + +- `세션` +- `타이머` +- `pause` +- `break` +- `return` + +을 충분히 분리하지 않고 써 왔다. + +그 결과: + +- 사용자는 `타이머가 멈춰 있으면 다 paused인가?`를 헷갈린다 +- `/app`에서 `resume`이 primary인지, `새로 시작`이 가능한지 흐려진다 +- `잠시 비우기`와 `break`의 의미가 섞인다 + +이 spec은 그 상태 정의를 먼저 고정한다. + +--- + +## 2. 한 줄 정의 + +> running session은 바로 `/space`로 복귀시키고, +> paused session은 `/app`에서 다시 이어갈지 정하게 하되, +> 사용자가 `이어가기`를 눌렀다면 `/space`에서는 다시 묻지 않고 바로 resume한다. + +--- + +## 3. 상태 정의 + +### Session + +사용자가 현재 책임지고 있는 하나의 focus block. + +조건: + +- goal이 있다 +- 아직 명시적으로 닫지 않았다 +- 다시 이어갈 수 있다 + +### Running Focus + +- 현재 focus 타이머가 진행 중 +- 사용자는 같은 goal 안에서 작업 중 + +### Paused Focus + +- 사용자가 의도적으로 pause를 눌렀다 +- 같은 goal은 아직 살아 있다 +- 기본값은 `resume` + +### Running Break + +- focus block은 끝났다 +- break 타이머가 진행 중이다 +- 이건 paused session이 아니다 + +### Return + +- 사용자가 pause를 누르지 않고 떠났다가 돌아온 상태 +- system이 recovery 선택지를 먼저 제안하는 상태 + +### Closed Session + +- `여기서 마무리하기`로 끝낸 상태 +- 더 이상 current session이 아니다 + +--- + +## 4. 제품 원칙 + +### 1. Running은 다시 결정하게 하지 않는다 + +이미 running이면 사용자의 다음 행동은 “다시 정하기”가 아니라 “복귀”다. + +즉: + +- `/app`에서 hero를 다시 보여주지 않는다 +- 바로 `/space`로 보낸다 + +### 2. Paused는 자동 재생하지 않는다 + +pause는 사용자의 명시적 멈춤이다. + +즉: + +- `/app`에 들어왔다고 자동 resume하지 않는다 +- 사용자가 직접 `이어가기`를 눌러야 한다 + +### 3. Explicit Continue 이후에는 다시 묻지 않는다 + +사용자가 `/app`에서 `이어가기`를 눌렀다면, +그건 이미 “다시 하겠다”는 결정을 내린 것이다. + +즉: + +- `/app -> /space -> 다시 start 클릭` 금지 +- `/space` 진입과 동시에 resume해야 한다 + +### 4. `/app`은 decision surface, `/space`는 execution surface + +- `/app`: 이어갈지 / 다시 정리할지 / 새 목표로 전환할지 +- `/space`: 실제로 일하는 곳 + +이 둘이 같은 결정을 두 번 요구하면 실패다. + +### 5. 새 시작은 current session이 없을 때만 direct + +paused session이 있는데 새 목표를 바로 시작하게 하면 +회피 루프와 상태 오염이 생긴다. + +즉: + +- current session이 없을 때만 direct start +- current session이 있을 때 새 start는 explicit takeover flow로만 허용 + +--- + +## 5. 라우팅 정책 + +### Rule A. Running Focus + +상태: + +- current session 존재 +- `state = running` +- `phase = focus` + +처리: + +- `/app` 진입 시 즉시 `/space` + +이유: + +- 이미 실행 중인 일은 다시 commitment gate에 세우면 안 된다 + +### Rule B. Running Break + +상태: + +- current session 존재 +- `state = running` +- `phase = break` + +처리: + +- `/app` 진입 시 즉시 `/space` + +이유: + +- break도 현재 세션의 일부다 +- `/app`에서 다시 decision을 시키면 break/return 의미가 흐려진다 + +### Rule C. Paused Focus + +상태: + +- current session 존재 +- `state = paused` +- `phase = focus` + +처리: + +- `/app` 진입 +- `resume gate` 노출 + +이유: + +- pause는 사용자의 의도적 멈춤이므로 존중해야 한다 +- 하지만 같은 goal을 다시 이어갈지 결정할 여지를 줘야 한다 + +### Rule D. No Session / Closed Session + +상태: + +- current session 없음 + +처리: + +- `/app` 진입 +- single-goal start hero 노출 + +--- + +## 6. `/app` paused state UX + +### 목적 + +사용자가 “멈춘 세션이 아직 살아 있다”는 것을 즉시 이해하고, +한 번의 결정으로 `/space`에 다시 들어가게 만드는 것. + +### 정보 구조 + +resume card 안에는 아래만 둔다. + +- 현재 goal +- 마지막 microStep +- 현재 상태 문구 + - 예: `잠시 멈춘 세션이 있어요` +- primary CTA +- quiet secondary actions + +### Primary CTA + +- `이어서 몰입하기` + +동작: + +- 클릭 +- `/space`로 이동 +- 자동 resume + +### Secondary + +- `한 조각 다시 잡기` +- `주간 review 보기` + +### Tertiary + +- `새 목표로 전환` + +중요: + +- new start가 아니다 +- takeover flow 진입점이다 + +--- + +## 7. `/space` 재진입 동작 + +### Resume CTA 이후 + +`/app`에서 `이어서 몰입하기`를 눌렀다면: + +- `/space`로 이동 +- 별도의 start 버튼 재요구 금지 +- 부드러운 transition 후 자동 resume + +추천: + +- 300~800ms 정도의 soft transition +- 필요하면 아주 짧은 re-entry settle animation + +금지: + +- `/space`에서 다시 `시작`을 누르게 하는 것 +- resume 직후 또 다른 decision tray를 띄우는 것 + +### Refocus CTA 이후 + +`한 조각 다시 잡기`를 눌렀다면: + +- refocus를 먼저 거친다 +- 그 후 `/space` 진입과 함께 자동 resume + +즉, refocus는 decision이고, `/space`는 execution이다. + +--- + +## 8. Takeover Flow + +paused session이 있을 때 새 goal direct start는 허용하지 않는다. + +대신 아래 흐름으로만 간다. + +### Trigger + +- `/app` paused state에서 `새 목표로 전환` + +### Confirm Sheet + +질문: + +- `현재 멈춘 세션을 어떻게 할까요?` + +선택지: + +- `이어서 하기` +- `이 세션은 여기서 정리하고 새로 시작` +- `취소` + +### 동작 원칙 + +- `이어서 하기` + - sheet 닫기 + - resume card 유지 + +- `이 세션은 여기서 정리하고 새로 시작` + - current session을 명시적으로 닫는다 + - 그 다음 `/app` single-goal start 상태로 전환한다 + +- `취소` + - sheet 닫기 + +중요: + +- silent abandon 금지 +- paused session 위에 새 session을 덮어쓰기 금지 + +--- + +## 9. Weekly Review와의 관계 + +paused state에서도 review는 열 수 있어야 한다. + +하지만 위계는 아래처럼 고정한다. + +### paused state + +- primary: `이어서 몰입하기` +- secondary: `한 조각 다시 잡기` +- quiet secondary: `주간 review 보기` + +즉: + +- review를 숨기면 안 된다 +- resume보다 앞세우면 안 된다 + +--- + +## 10. 금지사항 + +- running session인데 `/app` hero를 보여주는 것 +- paused 상태에서 `/app` 진입만으로 자동 resume +- `/app`에서 `이어가기`를 눌렀는데 `/space`에서 다시 start를 요구하는 것 +- paused session 위에서 direct new start 허용 +- break를 paused session처럼 취급하는 것 +- takeover 없이 silent abandon 하는 것 + +--- + +## 11. 구현 순서 + +### Slice 1. Session Routing Contract + +범위: + +- `/app` 진입 시 current session state에 따른 route policy 고정 + +포함: + +- `running focus -> /space` +- `running break -> /space` +- `paused focus -> /app` +- `no session -> /app` + +완료 조건: + +- 상태별 route policy가 코드와 문서에서 동일하다 + +### Slice 2. `/app` Paused Resume Gate + +범위: + +- paused state의 resume card UX 정리 + +포함: + +- primary `이어서 몰입하기` +- `한 조각 다시 잡기` +- quiet `주간 review 보기` +- state copy 정리 + +완료 조건: + +- paused 사용자가 다음 행동을 2초 안에 이해할 수 있다 + +### Slice 3. `/space` Auto-Resume Handoff + +범위: + +- `/app` resume CTA 이후 `/space` 진입 시 자동 resume + +포함: + +- explicit continue 이후 double-confirm 제거 +- transition quality 보정 + +완료 조건: + +- `/app -> /space -> start` 이중 클릭이 사라진다 + +### Slice 4. Takeover Flow + +범위: + +- paused session 위에서 new start를 하고 싶을 때의 명시적 처리 + +포함: + +- confirm sheet +- close-and-start-new 경로 +- silent abandon 방지 + +완료 조건: + +- paused session 상태에서 새 목표 전환이 상태 오염 없이 가능하다 + +### Slice 5. Browser QA + +반드시 확인할 시나리오: + +1. running focus 상태에서 `/app` 진입 +2. running break 상태에서 `/app` 진입 +3. paused focus 상태에서 `/app` 진입 +4. paused -> `이어서 몰입하기` +5. paused -> `한 조각 다시 잡기` +6. paused -> `주간 review` +7. paused -> `새 목표로 전환` + +--- + +## 12. 성공 기준 + +- 사용자가 현재 상태를 설명할 수 있다 +- running이면 `/space`, paused면 `/app`이라는 규칙이 일관된다 +- paused에서의 primary CTA는 항상 `resume`이다 +- explicit continue 이후에는 다시 start를 요구하지 않는다 +- new start는 current session이 없을 때만 direct다 + +--- + +## 13. 최종 판단 + +VibeRoom이 world-class가 되려면 +`멈춤`, `쉬기`, `복귀`, `새 시작`을 같은 것으로 취급하면 안 된다. + +가장 중요한 원칙은 이거다. + +> 이미 실행 중인 것은 바로 복귀시키고, +> 의도적으로 멈춘 것은 다시 결정하게 하되, +> 다시 하겠다고 결정한 뒤에는 한 번 더 묻지 않는다. diff --git a/docs/session_brief.md b/docs/session_brief.md index 1de52d6..e91fcde 100644 --- a/docs/session_brief.md +++ b/docs/session_brief.md @@ -14,9 +14,11 @@ Last Updated: 2026-03-15 ## 현재 우선순위 -1. `Core Loop Alignment` static audit -2. `Core Loop Alignment` browser audit -3. `Weekly Review` recovery 집계 연결 +1. `Paused Session Re-entry` Session Routing Contract +2. `/app` Paused Resume Gate +3. `/space` Auto-Resume Handoff +4. `Paused Session Takeover Flow` +5. `Core Loop Alignment` browser audit ## 최근 세션 상태 @@ -99,6 +101,12 @@ Last Updated: 2026-03-15 - full review 강제 이동 없이 `/stats`를 여는 secondary entry로만 동작한다. - 방금 끝낸 흐름을 반영한다고 과장하지 않는 카피로 정리했다. - 다음 구현은 weekly review의 실제 recovery 집계 연결이다. +- paused session 재진입 정책을 별도 source of truth로 고정했다. + - `running focus -> /space` + - `running break -> /space` + - `paused focus -> /app` + - `/app`의 explicit continue 이후 `/space`에서는 다시 start를 묻지 않고 자동 resume해야 한다. + - paused session 위의 새 시작은 direct가 아니라 takeover flow로만 허용한다. - `Product Alignment Audit` 운영을 시작했다. - `16_product_alignment_audit_plan.md`를 기준 문서로 추가했다. - `17_product_alignment_findings.md`에 core loop의 P1/P2 mismatch를 수집하기 시작했다. diff --git a/docs/work.md b/docs/work.md index a0818a5..1263ef5 100644 --- a/docs/work.md +++ b/docs/work.md @@ -18,63 +18,100 @@ ## 작업 1 -- 제목: `Product Alignment Audit` findings ledger 시작 +- 제목: `Paused Session Re-entry` Session Routing Contract - 목적: - - `16_product_alignment_audit_plan.md` 기준으로 core loop 전반의 기획-구현 불일치를 하나의 ledger로 수집한다. - - 더 이상 발견 즉시 감으로 수정하지 않고, severity와 affected flow 기준으로 정리한다. + - `18_paused_session_reentry_spec.md` 기준으로 running / paused / break 상태의 route policy를 코드에 고정한다. + - `/app`과 `/space`가 같은 session state를 두고 서로 다른 해석을 하지 않게 만든다. - 변경 범위: - - `/app` - - `/space` - - `/stats` - - 관련 카피 / query handoff / plan tier + - current session route gating + - `/app` 진입 정책 + - `/space` direct re-entry 정책 - 제외 범위: - visual redesign 직접 착수 금지 - - 새로운 feature spec 확장 금지 - - `/settings`, `/admin` 구현 변경 금지 + - takeover flow UI 구현 금지 + - weekly review 집계 확장 금지 - 완료 조건: - - `17_product_alignment_findings.md`가 생성된다 - - 최소한 P1 / P2 finding이 route, promise, actual behavior, affected file 기준으로 정리된다 - - 이미 수정된 항목과 아직 열린 항목이 분리된다 -- 진행 상태: - - 완료 -- 검증: - - 문서 self-review -- 커밋 힌트: - - docs(product): alignment findings ledger 시작 - -## 작업 2 - -- 제목: `Core Loop Alignment Audit` static slice -- 목적: - - `/app`, `/space`, `/stats`의 route-flow matrix와 state contract matrix를 만든다. - - primary/secondary entry, CTA promise, 실제 상태 전환이 맞는지 정리한다. -- 변경 범위: - - route/flow inventory - - state contract matrix - - copy-behavior mismatch 정리 -- 제외 범위: - - visual polish 직접 수정 금지 - - recovery browser QA 금지 -- 완료 조건: - - `/app`, `/space`, `/stats`의 primary CTA와 secondary CTA가 표로 정리된다 - - pause / return / complete / review handoff의 상태 의미가 문서화된다 - - static mismatch가 severity와 함께 분류된다 + - `running focus -> /space` + - `running break -> /space` + - `paused focus -> /app` + - `no session -> /app` + 규칙이 코드와 문서에서 일치한다 - 진행 상태: - 다음 작업 - 검증: - source-of-truth 문서 대조 - 커밋 힌트: - - docs(flow): core-loop alignment matrix 추가 + - feat(flow): session routing contract 정리 + +## 작업 2 + +- 제목: `/app` Paused Resume Gate +- 목적: + - paused session 사용자가 `/app`에서 현재 상태를 이해하고, 한 번의 결정으로 다시 들어가게 만든다. +- 변경 범위: + - paused resume card + - `이어서 몰입하기` + - `한 조각 다시 잡기` + - quiet `주간 review 보기` +- 제외 범위: + - new start takeover flow 금지 + - bulk visual redesign 금지 +- 완료 조건: + - paused 사용자가 2초 안에 다음 행동을 이해할 수 있다 + - review는 보이지만 resume보다 앞서지 않는다 +- 검증: + - `/app` paused state browser QA +- 커밋 힌트: + - feat(app): paused resume gate 추가 ## 작업 3 +- 제목: `/space` Auto-Resume Handoff +- 목적: + - `/app`에서 explicit continue를 눌렀다면 `/space`에서 다시 start를 누르지 않게 만든다. +- 변경 범위: + - `/app -> /space` handoff + - resume trigger + - re-entry transition +- 제외 범위: + - takeover flow 금지 + - break semantics 재정의 금지 +- 완료 조건: + - `/app -> /space -> start` 이중 클릭이 사라진다 + - explicit continue 이후에는 `/space`에서 바로 실행 상태로 들어간다 +- 검증: + - paused -> continue 브라우저 QA +- 커밋 힌트: + - feat(space): paused auto-resume handoff 연결 + +## 작업 4 + +- 제목: `Paused Session Takeover Flow` +- 목적: + - paused session 위에서 새 목표를 시작하고 싶을 때 상태 오염 없이 명시적으로 전환하게 만든다. +- 변경 범위: + - takeover confirm sheet + - close-and-start-new 경로 + - silent abandon 방지 +- 제외 범위: + - weekly review 확장 금지 + - visual redesign 직접 착수 금지 +- 완료 조건: + - paused 상태에서 direct new start는 불가능하다 + - 사용자는 기존 paused session을 어떻게 처리할지 먼저 고른다 +- 검증: + - paused -> new start 브라우저 QA +- 커밋 힌트: + - feat(app): paused session takeover flow 추가 + +## 작업 5 + - 제목: `Core Loop Alignment Audit` browser slice - 목적: - - static audit에서 나온 핵심 흐름을 브라우저에서 실제로 검증한다. - - 문서와 코드가 맞더라도 실제 체감이 어긋나는지를 잡는다. + - paused re-entry까지 포함한 핵심 흐름을 브라우저에서 실제로 검증한다. - 변경 범위: - `/app` first entry - - `/app` resume + - `/app` paused resume - `/app -> /stats -> /app` - `/space` pause / return / next beat / complete - `/space` complete -> setup -> weekly review teaser