---
task_id: task-2454
type: context
scope: task
created: 2026-05-05
updated: 2026-05-05
status: in-progress
---

# 맥락 노트: task-2454

**task**: task-2454

---

## 결정 근거

### 결정 1: state 전이는 `taskctl run` subprocess 호출 (직접 .json 수정 금지)
- **이유**: `scripts/taskctl.py` line 132-194는 state JSON에 SHA-256 checksum 필드를 박아두고, 외부 수정 시 "tampering"으로 간주하여 die(exit 1). 직접 갱신 불가.
- **대안 1**: state 파일을 만들지 않음 → 8합격기준 §3.1 #6 "RUNNING 전환" 위반.
- **대안 2**: taskctl.py 수정해서 우회 진입점 추가 → forbidden_paths 위반 (Phase 2 영역).
- **선택**: `subprocess.run(["python3", "scripts/taskctl.py", "run", task_id])` best-effort. 성공하면 RUNNING 전이, 실패하면 lock+evidence는 유지하되 stderr 경고. start_task_guard exit code는 lock 생성 성공 여부로만 결정.

### 결정 2: heartbeat은 외부 호출 모드 (`--update-heartbeat`)로 분리
- **이유**: Codex 권고 — start_task_guard는 종료형 CLI이므로 내부 thread는 의미 없음.
- **대안**: daemon fork → 프로세스 관리 복잡, 봇 종료 시 orphan 위험.
- **선택**: lock JSON에 heartbeat_timestamp 필드 + `--update-heartbeat <task>` 별도 명령. cron이나 봇 자체 호출 책임. 30분 stale 임계는 `--cleanup-stale`이 검사.

### 결정 3: 호출 강제(STEP 0 dispatch 주입)는 Phase 1 forbidden — spec 문서만
- **이유**: dispatch.py는 forbidden_paths. 회장 명시 — 본 Phase에서는 설계만, Phase 2에서 적용.
- **대응**: `start-guard-spec.md`에 STEP 0 cron prompt 템플릿 + dispatch.py 삽입 위치 + Phase 2 마이그레이션 절차 명시.

### 결정 4: mixed commit 감지 시 자동 복구 절대 금지 (회장 명시)
- **이유**: rebase/cherry-pick LLM 자동화 = 더 큰 silent corruption 위험.
- **대응**: `.tasks/locks/<task>.frozen` 마커 + evidence + cokacdir escalation. 추가 commit/push만 차단. 복구는 회장 수동 판단.

### 결정 5: handoff 토큰 제한은 4000자 + path 분리 (회장 명시)
- 4000자 초과 시 외부 파일 (`memory/handoffs/<task>-pending.txt`) 분리 + JSON에 `pending_work_path` 필드만 기록.
- create_handoff.py가 schema validate 자체 수행 후 저장. 실패 시 exit 1.

### 결정 6: handoff 없는 takeover 검증은 `--takeover-from` 옵션 진입점에서
- Phase 1은 `taskctl takeover` 명령 자체는 forbidden. 그러나 §6.2 #4 합격기준에 따라 start_task_guard에 `--takeover-from <branch>` 플래그를 받아서 handoff JSON 부재 시 exit 1.

## 3 Step Why 자문

- **1st Why** (왜 이 설계가 필요한가? A): task-2452 사고에서 메인 워크스페이스에 task-2451 브랜치 잔류 + worktree 미생성으로 6커밋 mixed task 발생 → main 0커밋. 시작 단계 코드 가드 부재가 root cause.
- **2nd Why** (왜 A가 최선인가? B): 문서 안내는 봇이 무시 가능, 코드 가드는 무시 불가. 회장 발화 직접 인용: "코드가 자동으로 막고 자동으로 안내하게 만들어라". 8 합격기준이 측정 가능하게 정의되어 있어 검증 가능.
- **3rd Why** (왜 B가 다른 대안보다 나은가? C): 대안1(task-2440 server-side merge gate)은 이미 존재하지만 시작 단계는 비어있어 client-side 가드 필요. 대안2(post-hoc 감지)는 silent corruption 발생 후 사후 수습 = 사고 자체 방지 못함.
- **결론**: A-B-C 논리적 일관성 확인. 설계 진행 OK.

## Codex G1 리뷰 반영 사항 (2026-05-05 15:41 1차)

| Severity | 우려 | 대응 |
|---|---|---|
| critical | 산출물 부재 | 본 Phase에서 모두 신규 생성 (정상) |
| high | taskctl state 충돌 | 결정 1: subprocess best-effort |
| high | 호출 강제 미연결 | 결정 3: spec 문서로 Phase 2 위임 |
| high | heartbeat thread 종료 | 결정 2: 외부 호출 모드 |
| medium | session-watchdog split-brain | spec에 Phase 2 통합 계획 명시 |
| medium | jsonschema 의존성 | 4.26.0 시스템 가용 확인됨, 명시 |

## 참조 자료

- 회장 진단 원문: `memory/tasks/task-2454.md` §0
- task-2452 사고 raw: `/home/jay/workspace-corruption-backup-2026-05-05/`
- 기존 시스템: `scripts/taskctl.py` (state 모델), `scripts/worktree_manager.py` (worktree 생성), `scripts/session-watchdog.sh` (별도 운영)
- task-2440: server-side merge gate (보완 관계)

## 주의사항

- ★ forbidden_paths 절대 금지: `dispatch.py`, `finish-task.sh`, `taskctl.py`, `worktree_manager.py`, `auto_merge.py` 등
- ★ mixed commit 자동 복구 시도 금지 — 감지+freeze+escalation까지만
- ★ Phase 1은 봇이 매뉴얼로 start_task_guard 호출 — 호출 강제는 Phase 2
- ★ start_task_guard는 종료형 CLI — 백그라운드 daemon화 금지
