English 한국어

scaffold-dayv0.3.1 · 프리릴리스

AI로 하루를 설계한다.

CLI 우선, MCP 지원 스케줄러. AI 클라이언트(Claude Code · Cursor · Claude Desktop)를 1급 사용자로 두고, TODO를 캘린더의 실제 빈 시간에 배치한다. CLI 플래그와 MCP 도구가 같은 표면(surface)을 공유하므로, LLM이 CLI 텍스트를 파싱할 필요 없이 한 번의 도구 호출로 하루를 계획할 수 있다.

설치

curl -fsSL https://day.scaffold.at/install.sh | sh

Tier 1 지원: macOS Apple Silicon, Linux x64. v0.2 바이너리는 코드사이닝되지 않은 상태이며(Apple notarization은 v0.2 이후 작업), 설치 스크립트가 macOS의 quarantine 속성을 자동으로 제거한다.

특정 버전을 명시해 설치하려면:

curl -fsSL https://day.scaffold.at/install.sh | sh -s -- --version v0.3.1

업데이트

설치 스크립트를 다시 실행하면 된다. 항상 최신 release 태그를 해석해 바이너리를 제자리에서 교체하며, ~/.scaffold-day/ 안의 데이터 (todos · events · policy · anchors)는 그대로 보존된다.

curl -fsSL https://day.scaffold.at/install.sh | sh
scaffold-day --version    # 새 버전 확인
scaffold-day doctor       # 환경 점검
Claude Desktop 주의: MCP 서버는 매 세션마다 새 바이너리를 spawn하지만, Claude Desktop은 도구 카탈로그를 캐시한다. 업그레이드 후 새 도구(record_morning 등)를 보려면 Cmd+Q로 완전히 종료한 다음 다시 실행해야 한다.

빠른 시작

$ scaffold-day init                  # ~/.scaffold-day + balanced 정책 시드
$ scaffold-day morning                # 오늘의 anchor 기록 (상대 시간 t=0)
$ scaffold-day todo add --title "Q2 OKR 초안" --duration-min 60
$ scaffold-day place suggest <todo-id> --json
$ scaffold-day today --tz Asia/Seoul

핵심 개념

scaffold-day는 의도약속을 분리한다. 세 객체 타입이 단계별로 다른 의미를 가진다:

타입의미생성 명령
todo해야 할 일. 시간은 아직 미정todo add
event고정 시간 블록(회의, 약속). 옮겨지지 않음event add
placementtodo가 슬롯에 commit된 결과. override / replan으로 이동 가능place do

그래서 todo add만으로는 today에 나타나지 않는다 — 그건 풀(pool)에 들어간 후보일 뿐이다. place suggest + place do로 슬롯에 박아야 day 뷰가 잡아낸다.

아침 anchor와 상대 시간 모델v0.2

v0.2는 anchor를 도입한다 — 사용자가 "오늘을 시작한" 벽시계 시각이다. 이게 v0.2 새 정책 3개의 t=0 기준점이며, 모두 옵션이다. 이 필드들 없이 쓰면 v0.1과 정확히 같은 동작을 한다.

anchor 기록

$ scaffold-day morning                  # 지금 시각 → explicit
$ scaffold-day morning --at 07:30       # 시각 명시 → manual
$ scaffold-day morning --force          # 기존 anchor 덮어쓰기

AI 클라이언트는 사용자가 아침 인사를 보낼 때 MCP record_morning 도구를 호출하면 된다. 매일 첫 비-init 명령은 auto 소스로 fallback anchor도 자동 기록하며, 명시 호출이 들어오면 조용히 explicit으로 승급된다.

3개의 정책 레이어 (모두 옵션)

필드효과기본값
sleep_budget오늘 잠이 min_hours 미만이 되는 슬롯은 거절. target_hours 미만은 소프트 페널티min 6h, target 8h
cognitive_load무거운 작업(effort_min ≥ 60)이 anchor 후 capacity 윈도우를 지나면 점수 감쇠4h 윈도우, linear -10/h
recovery_block어제 늦은 일정(working hours + 2h 이상)이 있었으면 다음 날 아침 슬롯에 소프트 페널티2h 블록, -30 페널티

한 번에 활성화하기

$ scaffold-day policy patch '[
  {"op":"add","path":"/context/sleep_budget","value":{"target_hours":8,"min_hours":6,"soft_penalty_per_hour":15}},
  {"op":"add","path":"/context/cognitive_load","value":{"decay":"linear","full_capacity_window_hours":4,"heavy_task_threshold_min":60,"linear_penalty_per_hour":10,"exponential_base":2}},
  {"op":"add","path":"/context/recovery_block","value":{"late_threshold_minutes_past_working_end":120,"morning_block_hours":2,"soft_penalty":30}}
]'

today 출력에 추가되는 라인

────────────────────────────────────────────── 2026-04-29 · Asia/Seoul ────────────────────────────────────────────── Day started 03:00 Rest break suggested · ~20 min (slept 4.0h last night) Free 09:00-12:00 [free 180m] 13:00-18:00 [free 300m] Summary: 0 events, 0 placements, 2 free slots, 0 open conflicts.

CLI 명령 레퍼런스

모든 명령은 --help에서 6-섹션 템플릿(WHAT/WHEN/COST/INPUT/RETURN/GOTCHA)을 따른다. 총 22개 명령 중 17개가 v0.2에서 실제 동작하고, 5개는 v0.2.x(Phase B)에서 구현 예정인 placeholder다.

명령역할
init~/.scaffold-day 시드 + balanced 정책 박기
today오늘의 events / placements / 빈 슬롯 / anchor / 휴식 권장
morning오늘 anchor 기록 (또는 조회 / 덮어쓰기)
day월별 / 개요 / 단일 / 범위 / 재계획
week7일 개요
todoadd / list / get / update / archive / score
eventadd (update / delete은 placeholder)
placesuggest / do / override
policyshow / patch / preset apply
conflictlist / resolve / detect
explain특정 슬롯이 선택된 이유 (재현)
authGoogle OAuth 토큰 관리 (v0.2는 mock 모드)
doctor환경 / 프로바이더 / 어댑터 / anchor 진단
migrate스키마 마이그레이션 (기본 preview)
mcpstdio로 MCP 서버 실행
docsAI가 읽기 좋은 표면 한 번에 덤프

Placeholder("implementation pending §S## " 출력 후 종료): feedback, self-update, telemetry, logs, rebuild-index. 실제 구현은 v0.2.x Phase B에서.

전역 플래그

자주 쓰는 레시피

# TODO 추가 + 오늘 가장 좋은 슬롯에 배치
ID=$(scaffold-day todo add --title "OKR 초안" --duration-min 60 --json | jq -r .id)
SLOT=$(scaffold-day place suggest $ID --json | jq -r '.candidates[0] | "\(.start)/\(.end)"')
scaffold-day place do $ID --slot $SLOT

# 기존 placement를 다른 슬롯으로 이동
scaffold-day place override <placement-id> --new-slot 2026-04-29T15:00:00+09:00

# 오늘을 다시 계획 (잠금 안 된 placement 자동 재배치)
scaffold-day day replan 2026-04-29 --json

# 특정 placement가 왜 그 자리에 들어갔는지 설명
scaffold-day explain <placement-id> --json

AI 클라이언트에서 쓰기

scaffold-day mcp는 stdio로 Model Context Protocol을 말한다. v0.2에 27개 도구가 들어 있다 — day 읽기 / TODO CRUD / placement / policy / anchor. 아래 설정 중 하나를 클라이언트 config에 넣고, 클라이언트를 완전히 재시작하면 된다.

~/Library/Application Support/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "scaffold-day": {
      "command": "scaffold-day",
      "args": ["mcp"]
    }
  }
}

scaffold-day가 Claude Desktop의 PATH에 없으면 "scaffold-day" 부분을 which scaffold-day가 출력하는 절대 경로로 바꿔서 넣자.

한 줄 명령 (~/.config/claude-code/mcp.json 자동 생성/병합)

claude mcp add scaffold-day -- scaffold-day mcp

Cursor → Settings → MCP → Add

{
  "mcpServers": {
    "scaffold-day": {
      "command": "scaffold-day",
      "args": ["mcp"]
    }
  }
}

팁: AGENTS.md를 시스템 프롬프트에 paste

AGENTS.md는 JTBD(Jobs To Be Done) 레시피("미팅이 옮겨졌어요 → replan", "TODO 추가 후 슬롯에 박기")와 전체 도구 표면을 함께 담고 있다. 세션 시작에 한 번 paste해 두면 LLM이 매번 호출 시퀀스를 새로 추론하지 않아도 된다. 토큰 예산도 작다 (~10K 문자 정도이며, 모던 컨텍스트 안에 충분).

v0.2 anchor 흐름을 MCP로

  1. 사용자가 AI에게 인사 ("좋은 아침!") → AI가 record_morning 호출
  2. "오늘 일정 어때?" → AI가 get_day 호출
  3. "OKR 초안 1시간 잡아줘" → AI가 create_todo + compute_task_importance + suggest_placement + place_todo를 순서대로 호출
  4. "오늘 컨디션 어때?" → AI가 get_rest_suggestion 호출 (수면 부채 인지)

정책 레퍼런스

~/.scaffold-day/policy/current.yaml이 스케줄링 결정의 단일 진실 원천(single source of truth)이다. YAML 코덱이 코멘트를 보존하므로 손으로 편집해도 안전하다.

JSON Patch로 수정 (RFC 6902, 코멘트 유지)

# 점심 보호를 12:00-13:00 → 12:30-13:30으로 변경
scaffold-day policy patch '[
  {"op":"replace","path":"/context/protected_ranges/0/start","value":"12:30"},
  {"op":"replace","path":"/context/protected_ranges/0/end","value":"13:30"}
]'

또는 그냥 파일을 편집

코멘트가 그대로 살아남는다. 다음 scaffold-day today 호출 시 즉시 반영.

$EDITOR ~/.scaffold-day/policy/current.yaml

필드 개요

경로의미
context.tz모든 상대 시간 계산에 쓰이는 IANA 타임존
context.working_hours[]요일별 placement 가능 시간 (밖이면 차단)
context.protected_ranges[]항상 차단되는 구간 (수면, 점심)
context.energy_peaks[]태그 기반 선호도에 쓰이는 소프트 힌트
context.sleep_budgetv0.2오늘 수면에 대한 hard reject + soft 페널티
context.cognitive_loadv0.2capacity 윈도우 지나면 무거운 작업 감쇠
context.recovery_blockv0.2늦은 일정 다음 날 아침을 소프트로 막음
hard_rules[]타협 불가능한 placement 제약
soft_preferences[]태그 / 시간대별 점수 가산
importance_weightsurgency · impact · effort 등이 점수에 합쳐지는 가중치

변경 안전하게 시험하기v0.2

모든 write 명령은 --dry-run을 지원한다. 디스크는 그대로 두고, stdout에 이렇게 됐을 거다를 출력한다.

$ scaffold-day --dry-run todo add --title "test" --duration-min 30 --json
{
  "dry_run": true,
  "would": {
    "command": "todo add",
    "writes": [
      { "path": "todos/active/index.json", "op": "update" },
      { "path": "todos/active/detail/<new-id>.json", "op": "create" }
    ],
    "result": { "title": "test", "status": "open", ... }
  }
}

read 명령에서는 무시된다 (no-op). MCP 도구에는 의도적으로 dry-run 모드가 없다 — 읽기 전용 suggest_placement / compute_task_importance가 이미 place_todo / create_todo 전의 미리보기 경로 역할을 한다.

데이터가 저장되는 위치

~/.scaffold-day/
├── .scaffold-day/schema-version.json   # 마이그레이션 추적
├── .secrets/                            # 0700, OAuth 토큰 자리
├── policy/current.yaml                  # 단일 진실 원천
├── policy-snapshots/                    # placement별 정책 스냅샷 (재현용)
├── todos/active/{index.json, detail/}   # 2-tier TODO 저장
├── todos/archive/                       # 보관된 todo
├── days/YYYY-MM/{manifest.json, *.json} # 날짜별 events + placements
├── sync/                                # Google Cal sync 상태 (v0.2는 mock)
├── conflicts/                           # 충돌 파티션
└── logs/
    ├── heartbeats.jsonl                 # anchor 기록 (v0.2)
    ├── placement.jsonl                  # placement 결정 (재현)
    └── conflict.jsonl                   # 충돌 액션

위치를 바꾸려면 SCAFFOLD_DAY_HOME=/path/to/dir로 override.

문제 해결

증상해결
업그레이드 후 Claude Desktop에 새 MCP 도구가 안 보임 Cmd+Q로 완전 종료 후 다시 실행. 도구 카탈로그는 세션 시작 시 가져온다.
scaffold-day --version이 여전히 옛 버전 which scaffold-day 확인. 설치 스크립트는 /usr/local/bin 권한이 없으면 ~/.local/bin에 쓰는데, PATH 앞쪽의 옛 바이너리가 가릴 수 있다.
macOS arm64에서 scaffold-day mcp가 죽음 알려진 이슈: bun stdin이 macOS에서 명시 resume이 필요. v0.2에 이미 반영됨. 그래도 발생하면 doctor 출력과 함께 이슈를 올려달라.
오늘 anchor가 잘못 박힘 scaffold-day morning --at 07:30 --force로 덮어쓰기. 특정 ISO 시각이 필요하면 --at 2026-04-29T07:30:00+09:00 형태로도 가능.
상대 시간 모델을 안전하게 dogfood하고 싶다 모든 명령에 --dry-run을 함께 붙여 시험. 또는 샌드박스 home 사용: SCAFFOLD_DAY_HOME=$(mktemp -d) scaffold-day init.

왜 만들었나

대부분의 캘린더 도구는 시간을 보여주는 데 최적화돼 있다. scaffold-day시간을 배치하는 데 최적화한다. TODO 목록을 받아서 중요도를 계산하고, 정책에 따라 캘린더의 실제 빈 공간에 떨어뜨린다 — 사람이 읽고 손으로 고칠 수 있는 투명하고 재현 가능한 정책 아래에서.

v0.2의 상대 시간 모델은 한 걸음 더 나아간다: 수면을 정해진 시각에 고정시키는 대신, 사용자가 budget을 선언하고, placement 엔진이 그 아래로 절대 떨어지지 않도록 거절한다. 무거운 작업은 하루가 길어질수록 점수가 감쇠한다. 늦은 밤 일정은 다음 날 아침에 회복 블록을 띄운다. 계산은 결정론적이고 재현 가능하며, 정책은 YAML 한 파일에 담겨 있다.