Life Cockpit prototype의 핵심은 예쁜 task list가 아니다. 사용자의 실행 상태가 어떻게 변하는지 기록하는 객체 lifecycle이다.
첫 slice는 다섯 객체만 다룬다.
Task -> Quest -> Session -> RouteLog
| 원칙 | 의미 |
|---|
| state는 적게 | 상태가 많으면 사용자가 선택하기 전에 지친다 |
| event는 명확하게 | 사용자가 한 행동과 시스템이 만든 변환을 분리한다 |
| transition은 되돌릴 수 있게 | 실패는 dead end가 아니라 retry/recover route로 이어진다 |
| invariant는 안전선 | medical claim, guilt score, hidden sensing은 lifecycle에 들어오지 않는다 |
Task는 사용자가 원래 해야 한다고 느끼는 일이다. prototype에서는 task를 완성시키는 것이 아니라 quest로 변환할 재료로 본다.
| 항목 | 값 |
|---|
| State | inbox, ready, active, done, parked |
| Event | capture, score, activate, complete, park |
| Invariant | 원문 title은 보존한다. quest title로 덮어쓰지 않는다 |
| Transition | 의미 |
|---|
inbox -> ready | 최소 필드가 채워져 추천 후보가 될 수 있다 |
ready -> active | quest가 선택되어 session이 시작된다 |
active -> done | session outcome이 done이고 task 자체도 충분히 끝났다 |
ready -> parked | 지금 상태에서는 추천하지 않는 편이 낫다 |
EnergyState는 진단명이 아니라 사용자가 현재 실행 조건을 고르는 짧은 label이다.
| 항목 | 값 |
|---|
| State | 저전압, 과열, 헌터모드, 회피중, 산만함 |
| Event | select_state, change_state |
| Invariant | 상태 label은 medical diagnosis처럼 표현하지 않는다 |
| State | 추천 bias |
|---|
저전압 | 낮은 friction, 가까운 reward |
과열 | 작은 scope, fallback route |
헌터모드 | 높은 value, challenge |
회피중 | proxy action, indirect entry |
산만함 | 짧은 timebox, 환경 정리 |
Quest는 task를 지금 착수 가능한 행동으로 낮춘 것이다. quest는 task를 대체하지 않는다. task의 한 진입로다.
| 항목 | 값 |
|---|
| State | candidate, selected, used, rejected |
| Event | compile, select, start_session, reject |
| Invariant | 한 번에 3개를 넘겨 보여주지 않는다 |
| Transition | 의미 |
|---|
candidate -> selected | 사용자가 route 하나를 고른다 |
selected -> used | session이 실제로 시작된다 |
candidate -> rejected | 사용자가 지금 맞지 않는 route로 표시한다 |
Session은 quest를 실행한 10분 라운드다. session의 목적은 생산성 점수가 아니라 route 결과를 남기는 것이다.
| 항목 | 값 |
|---|
| State | planned, running, finished, abandoned |
| Event | start, finish, abandon, record_outcome |
| Invariant | outcome은 done, fork, retry, recover 중 하나다 |
| Outcome | 다음 transition |
|---|
done | route를 positive pattern 후보로 남긴다 |
fork | 새 하위 task 또는 route note를 만든다 |
retry | quest를 더 작게 다시 compile한다 |
recover | 실행 대신 회복 route로 전환한다 |
RouteLog는 “잘했다/못했다”가 아니라 route learning이다.
| 항목 | 값 |
|---|
| State | recorded, reviewed, promoted |
| Event | record, review, promote_rule |
| Invariant | guilt copy, productivity score, diagnosis label을 저장하지 않는다 |
| Field | 내용 |
|---|
task_title | 원래 task |
energy_state | 선택한 상태 |
quest_title | 변환된 route |
outcome | done/fork/retry/recover |
route_note | 다음 추천에 쓸 짧은 관찰 |
아래 invariant는 prototype이 커져도 깨지면 안 된다.
- 원래 task와 변환된 quest를 모두 보존한다.
- 한 화면의 quest 후보는 3개 이하로 유지한다.
- session outcome은 죄책감 점수가 아니라 route learning으로 저장한다.
- medical diagnosis, treatment, medication advice는 데이터 모델에 넣지 않는다.
- hidden sensing은 사용자가 이해하고 끌 수 있는 계약 전까지 넣지 않는다.
- local-first data를 기본값으로 둔다.
실제 Rails prototype으로 내린다면 시작점은 아래 정도가 충분하다.
EnergyState is enum-like value object
초기에는 복잡한 graph보다 lifecycle event가 더 중요하다. relation을 늘리기 전에 Task -> Quest -> Session -> RouteLog 한 바퀴를 끝까지 닫는다.