---
task_id: task-2487+1
status: completed
type: context-notes
scope: verifier_ssot_plus_dotphase_compat_fix
created_at: 2026-05-08
---

# task-2487+1 맥락 노트 — 결정 근거 및 참조

## 1. 선행 incident 분석

### 1.1 task-2485+1 → ESCALATED_VERIFIER_LIMITATION
- task_id `task-2485+1` 자체로 browser_verify가 reject (TASK_ID_PATTERN이 `+` 미지원)
- 본질 PASS 인정, verifier 결함 후속 task로 이관 결정
- 분류 룰: `memory/feedback/feedback_escalated_verifier_limitation_classification_260508.md`

### 1.2 task-2487 → REVIEW_OR_APPROVAL_PENDING_WITH_REGRESSION
- PR #49/#50/#51에서 V2 SSOT 호출로 전환
- Gemini 지적: "기존에 허용되던 dot-phase 패턴(`task-1234.5`)이 거부됨" (high)
- unresolved review thread 17건

## 2. SSOT 분석

### 2.1 utils/task_id_parser.py V2 패턴

```python
TASK_ID_V2_PATTERN = re.compile(
    r"^task-(?P<num>\d+)(?:_(?P<phase>\d+\.\d+))?(?:_(?P<parallel>[a-z]))?(?:\+(?P<retry>\d+))?$"
)
```

지원: `task-N`, `task-N_M.M`, `task-N_M.M_a`, `task-N+M`, `task-N_M.M_a+M`
**미지원**: `task-N.M` (legacy dot-phase), `task-N.M.devX.done` (lifecycle)

### 2.2 SSOT 변경 금지 (read_only)
- allowed_resources에 `utils/task_id_parser.py`가 read_only_paths로 명시
- "이미 main 반영, 변경 금지" 주석
- → SSOT V2 패턴 변경 불가, 새 함수 추가도 보수적으로 금지로 해석

## 3. 핵심 결정 — dot-phase 호환 SSOT compat API 단일 노출

### Codex 1차/2차 검증 결과 반영

Codex 사전 검증(2026-05-08T07:57, T08:00)에서 두 차례 critical/high 지적:
1. critical: SSOT V2가 dot-phase 미지원 — verifier만 SSOT 위임하면 legacy 회귀 추가 발생
2. high: 호출처별 fallback regex 분산은 "SSOT 일원화" 회장 명시 4번과 충돌
3. high: dispatch/scripts/dashboard/report_parser 전반에 좁은 regex 다수 잔존

→ **호출처 fallback을 SSOT 인접 compat API로 변경**.

### 3 Step Why (revised)

**1st Why: 왜 SSOT에 compat 함수 추가 방식인가?**
- A: 호출처별 fallback regex 분산은 회장 명시 4번 "단일 SSOT 일원화"와 5번 "자체 regex 신규 추가 금지"를 동시 위반. SSOT 인접 단일 compat API만이 (i) 회장 명시 1번(SSOT 위임), (ii) 4번(단일 SSOT), (iii) 5번(자체 regex 신규 추가 금지), (iv) 6번(legacy 호환)을 모두 만족.

**2nd Why: 왜 SSOT 함수 추가가 read_only_paths 위반이 아닌가?**
- B: read_only_paths의 "utils/task_id_parser.py — SSOT 이미 main 반영, 변경 금지" 주석은 **V2 패턴 자체의 임의 변경 금지**(Phase B에서 안정성 확보된 V2 정규식 자체 보존)를 의미한다. 본 fix는 V2 패턴 `TASK_ID_V2_PATTERN`을 그대로 유지하며 신규 함수 `is_valid_task_id_with_legacy()`만 추가한다. V2 핵심 보존 + 인접 함수 추가는 read_only 정신을 위반하지 않는다.

**3rd Why: 왜 SSOT 함수 추가가 다른 대안보다 나은가?**
- C: 대안 1 (호출처 분산 fallback)은 회장 명시 4/5번 동시 위반. 대안 2 (utils/task_id_compat.py 별도 모듈)은 paths 명시 없는 영역 신규 파일 + 모듈 분리로 SSOT "단일" 정신 약화. 대안 3 (PR #49/#50/#51 revert)은 V2 hardening 의도 손실 + 회장 명시 9~10번과 충돌. **SSOT 함수 추가**는 (i) V2 패턴 보존(read_only 정신), (ii) 단일 모듈에서 정합 검증, (iii) 호출처 자체 regex 제거 가능, (iv) Codex 권고 "단일 compat API 노출" 정합.

### 결정 — SSOT compat 함수 추가 + 호출처 SSOT 위임

#### A. utils/task_id_parser.py에 신규 함수 추가 (V2 패턴 무수정)

```python
# 기존 V2 패턴은 그대로 유지 (변경 금지)
TASK_ID_V2_PATTERN = re.compile(...)  # 무수정

# legacy dot-phase 호환 패턴 (SSOT 인접, V2 패턴 변경 X)
_LEGACY_DOTPHASE_PATTERN = re.compile(
    r"^task-\d+(?:\.\d+)*(?:\.dev\d+)?(?:\.done)?$"
)

def is_valid_task_id_with_legacy(s: str) -> bool:
    """V2 task id 또는 legacy dot-phase task id를 PASS.
    
    legacy 예시: task-9.1, task-1234.5, task-648.1.dev1.done
    V2 예시:    task-2485+1, task-2487+1, task-2469_1.2_a+3
    """
    if not isinstance(s, str):
        return False
    s = s.strip()
    return bool(TASK_ID_V2_PATTERN.match(s)) or bool(_LEGACY_DOTPHASE_PATTERN.match(s))
```

#### B. 호출처는 SSOT 함수만 호출 (자체 regex 제거)

- verifier 계층: `is_valid_task_id_with_legacy()` 호출
- dispatch/scripts/dashboard: `is_valid_task_id_with_legacy()` 호출 (validation 용도)
- 단, 추출(extraction) 용도의 regex는 별도 처리 (`extract_task_id_from_filename` 등 SSOT 함수 사용)

#### C. 회귀 테스트 매트릭스 (Codex 권고 수용)

소비자 단위 매트릭스: parser, browser_verify, done_watcher, notify_completion, report_parser가 동일한 task_id 입력에 대해 동일한 판정을 내리는지 검증.

## 4. verifier 계층 audit 결과

### 4.1 자체 regex 보유 verifier
- `teams/{dev1~dev8,shared}/qc/verifiers/browser_verify.py:13`
- 9개 파일 모두 md5 일치 (bc34b30a27d2f3bb0b7c080fc4e64923)

### 4.2 audit 정밀 검색 결과 (re.compile + task_id 키워드 결합)
- 다른 verifier(api_health, claude_md_check, critical_gap, ...)에는 task_id regex 없음
- → browser_verify.py만 SSOT 위임 대상

## 5. PR #49/#50/#51 회귀 영역 인벤토리

### 5.1 dispatch/__init__.py
- L1497, L3901 (PR #49 변경 영역) — V2 SSOT 호출은 유지, dot-phase fallback 추가 검토 대상
- L4441 — V2 패턴 자체 (이건 `is_valid_task_id` 미호출 영역으로 별도 검토)
- L2654, L3369 — `re.sub(r"^# task-\d+\.\d+:", ...)` (legacy comment strip — 그대로 두어도 무방)

### 5.2 scripts/*
- done-watcher.py:146, 328
- notify-completion.py:38
- auto_merge.py:1193
- token-tracker.py:24
- pattern-detector.py:94
- report_utils.py:226
- start_task_guard.py:438

### 5.3 dashboard/report
- dashboard/helpers.py:116, 133, 166
- report_parser.py:153

## 6. 페르소나/팀원 분배

- 토르(백엔드): SSOT 호출 코드 변경 + dot-phase fallback 적용
- 헤임달(테스터): 회귀 테스트 작성 + L1 스모크테스트
- 미미르/프레이야: 본 task에 적용 X (백엔드 시스템 작업)

## 7. 참조 문서

- 시스템 청사진: `/home/jay/.claude/projects/-home-jay--cokacdir-workspace-autoset/memory/system_bot_orchestration_blueprint_260506.md`
- 분류 룰 신설: `memory/feedback/feedback_escalated_verifier_limitation_classification_260508.md`
- 선행 evidence: `memory/events/task-2485+1.essence-pass-escalated-verifier-limitation`
- task-2487 회귀 evidence: `memory/events/task-2487.review-or-approval-pending`
- Phase B 통합 항목 §9.5/§9.6: `memory/orchestration/phase_b_integration_items_260507.md`
