{
  "pass": false,
  "risks": [
    {
      "severity": "critical",
      "description": "구현물 부재: 설계서가 요구하는 `utils/canonical_workspace_resolver.py` 와 `tests/regression/test_canonical_workspace_resolver_2517.py` 가 현재 저장소에 없습니다. 이 상태로는 P0 hardening, CLI, 회귀 14건, import smoke 어느 것도 검증되지 않습니다."
    },
    {
      "severity": "critical",
      "description": "완료 조건과 변경 제한이 서로 충돌합니다. 설계서는 6 hook이 모두 `resolve_canonical_workspace()` 로 시작하고 동일 `CanonicalWorkspace` 인스턴스를 공유해야 한다고 요구하지만, 동시에 `expected_files` 외 수정 금지와 `task-2518/2519 wiring 직접 시도 금지`를 명시합니다. 현재 `scripts/finish-task.sh`, `scripts/guard.sh`, `scripts/start_task_guard.py` 는 resolver를 호출하지 않으므로, 허용된 2개 신규 파일만으로는 '구조적 제거'와 '6 hook 통합' 완료를 달성할 수 없습니다."
    },
    {
      "severity": "high",
      "description": "현재 dirty 판정 로직과 설계 목표가 정면 충돌합니다. `scripts/start_task_guard.py` 는 전체 `git status --porcelain` 결과로 clean 여부를 판정하고, `scripts/finish-task.sh` 도 광범위한 예외 패턴 기반 dirty 검사를 수행합니다. 따라서 설계서의 `evaluate_scope_dirty(ws, expected_files)` 를 신규 모듈에만 추가해도 task-2516+1의 'dirty workspace false detection'은 실제 운영 경로에서 제거되지 않습니다."
    },
    {
      "severity": "high",
      "description": "cwd/worktree 판정이 이미 여러 소스에 분산돼 있어 새 resolver가 도입돼도 단일 진실원천이 되지 않을 위험이 큽니다. 현재 `scripts/finish-task.sh` 는 `task-timers.json` 및 task 문서에서 `PROJECT_PATH` 를 추론하고, `utils/worktree_resolver.py` 는 별도 glob 규칙을 사용하며, `scripts/start_task_guard.py` 는 `.worktrees/<task>-<bot>` 패턴을 직접 강제합니다. 설계서에는 기존 resolver들과의 우선순위/폐기 전략이 없습니다."
    },
    {
      "severity": "medium",
      "description": "`assert_main_fresh(ws)` 의 'stale 5초 이상 차이 시 FAIL' 요구가 모호합니다. 현재 코드베이스는 `origin/main` freshness를 SHA 일치로만 다루며 시간 기준 메타데이터를 저장하지 않습니다. 어떤 시점을 기준으로 5초를 계산하는지, fetch 금지/실패 상황을 어떻게 처리하는지 정의가 부족해 테스트와 운영 동작이 갈릴 가능성이 큽니다."
    }
  ],
  "suggestions": [
    "우선 이 task의 완료 범위를 둘로 분리해야 합니다. 1단계는 `canonical_workspace_resolver` 신규 모듈과 단위/회귀 테스트 추가, 2단계는 별도 wiring task에서 `finish-task.sh`, `guard.sh`, `start_task_guard.py` 등 호출부 통합입니다. 현재 문서처럼 두 단계를 동시에 완료 조건에 넣으면 충족 불가능합니다.",
    "'4 ambiguity 구조적 제거'를 이 task에서 주장하려면 최소한 실제 호출부 한 곳 이상이 resolver 결과를 사용해야 합니다. 그렇지 않다면 완료 조건의 표현을 '인터페이스 제공 및 fixture 검증' 수준으로 낮추는 것이 맞습니다.",
    "기존 workspace 판정 경로(`PROJECT_PATH` 추론, `utils/worktree_resolver.py`, `.worktrees/<task>-<bot>` 규칙)와 새 resolver 사이의 우선순위를 문서에 명시하세요. 특히 어떤 소스를 authoritative로 보고, 어떤 기존 로직은 deprecated로 간주하는지 결정이 필요합니다.",
    "`assert_main_fresh` 는 시간 기반보다 'resolve 시 lock한 `main_head_sha` 와 재검증 시점의 `origin/main` SHA 비교'로 계약을 단순화하는 편이 안전합니다. 5초 규칙이 꼭 필요하면 타임스탬프 필드와 테스트 전략을 함께 정의해야 합니다.",
    "운영 경로의 회귀를 막으려면 `evaluate_scope_dirty` 와 기존 `git status` 기반 검사 사이의 연결 지점을 먼저 설계하세요. 그렇지 않으면 신규 테스트가 통과해도 실제 hook에서는 동일한 false detection이 계속 발생합니다."
  ],
  "source": "codex_companion",
  "fallback_reason": null,
  "error": null,
  "target_dir": "/home/jay/workspace",
  "target_dir_source": "workspace_root_fallback",
  "task_id": "task-2517",
  "timestamp": "2026-05-08T23:35:16.261556+00:00"
}