---
task_id: task-2374
type: plan
scope: task
created: 2026-05-02
updated: 2026-05-02
status: completed
---

# 계획서: task-2374 — 옵션 D 시맨틱 재설계

**task**: task-2374
**목표**: `.done` 단일 마커를 `.work-done`(declared) + `.merged`(observed) + `.merge-failed`(escalation) 3-마커로 분리하고, `state.json`을 SoT로 도입하여 task-2364 사례(63분 갭, 잘못 보고)를 구조적으로 차단한다.
**승인**: 회장 (2026-05-02 미팅 옵션 D 채택)
**근거**: `memory/meetings/2026-05-02-done-semantics-redesign.md`, `memory/reports/task-2368.md`

---

## 목표

1. **declared vs observed 분리**: `.work-done`(봇 작업 완료 선언) ≠ `.merged`(GitHub mergedAt 사실 관측)
2. **state.json SoT**: `memory/state/{task_id}.json` = 진실. 마커는 캐시
3. **task.yaml 분류**: `kind: code|meta` + `merge_required: bool`로 시스템·문서 task 분기
4. **호환 shim**: 기존 `.done` 소비자 회귀 0 (`.work-done` 생성 시 `.done` symlink 동시 생성, 6개월 유지)
5. **검증 시나리오 7건 PASS**

## 범위

### 포함
- Phase 1: `finish-task.sh` `.work-done` 생성 + state.json + `.done` 호환 symlink
- Phase 2: `auto_merge.py` `.merged`/`.merge-failed` 생성 + retry counter (5회)
- Phase 3: `done-watcher.py` `.work-done` 감지 + mergedAt 폴링 + atomic `.merged`
- Phase 4: `dispatch.py` task frontmatter `kind`/`merge_required` 파서
- Phase 5: 회귀 테스트 12-cell + meta validator + state schema 문서

### 제외 (다음 페이즈 이후)
- Merkle HMAC 서명 (task-2371 후속 P3)
- Tier별 알림 dwell 90초 dashboard 적용 (task-237Y 별도 dispatch)
- `.done` symlink 제거 (6개월 후)

## 위임 계획

- Phase 1-4 구현: **쿠쿨칸(BE)** — bash/Python 시스템 코드
- Phase 5 테스트: **카마소츠(테스터)** — pytest 회귀 12-cell + meta validator
- G3 독립 검증: **마아트(QC, 횡단조직)** — 회귀 0 검증
- Codex G1 사전 검증: 설계 통과 후 재실행

## 검증 기준

- `tests/dev7/test_done_semantics.py` PASS (12-cell 호환성)
- `tests/dev7/test_meta_task_validator.py` PASS (kind/merge_required 파싱)
- 회귀 0: P0/P1/P2 산출물 변경 없음 (task-scope-guard, post_merge_probe, auto_revert, anu_confirm_bot, daily_digest)
- task-2364 시뮬레이션: `.work-done` 생성 시점 ≠ `.merged` 생성 시점 (mergedAt 검증 후 atomic)
- legacy task: kind 미명시 → 기본값 code + merge_required: true

## 호환 shim 전략 (Codex G1 critical 1건 대응)

`.work-done` 생성 시 `.done` 호환 symlink 동시 생성:
- 기존 소비자 (`auto_merge.py:scan_done_files`, `done-watcher.py:scan_done_files`, `dispatch.py:--resume` line 1709, `dashboard/data_loader.py`, `qc_verify.py`, `g3_independent_verifier.py`, 다수 테스트) 무변경 동작
- 신규 소비자 (이번 task의 reconciler/mergedAt 폴링)는 `.work-done` 직접 인식
- 6개월 후 `.done` symlink 제거 + 기존 소비자 일괄 마이그레이션 (별도 task-237Z)
