#!/usr/bin/env python3
"""dispatch.py — 호환 shim (task-2388 Phase ε).

dispatch.py 4336줄이 dispatch/ 패키지 6 모듈로 분리되었다.
이 파일은 외부 호출자 호환을 위한 얇은 shim:
- `python3 dispatch.py --team ... --task-file ...` 스크립트 실행 진입점
- `import dispatch`는 패키지(dispatch/__init__.py)를 우선 로드하므로 영향 없음

분리 모듈:
- dispatch/_state.py: 상수 + optional imports + logger
- dispatch/task_id.py: task-2380 4-layer fix
- dispatch/retry.py: task-2387 status 가드
- dispatch/prompt.py: task-2386 슬림 prompt
- dispatch/audit.py: bot_pool + allowed_resources + capability + affected_files + warnings + team
- dispatch/core.py: dispatch + cancel + main + composite + PRD
"""

from __future__ import annotations

import os
import sys
from pathlib import Path

# dispatch/ 패키지가 import 가능하도록 부모 디렉토리를 sys.path에 등록
_REPO_ROOT = Path(__file__).resolve().parent
if str(_REPO_ROOT) not in sys.path:
    sys.path.insert(0, str(_REPO_ROOT))

from dispatch.core import main  # noqa: E402

# ── task-2712 §5.2 dispatch.py inner instrumentation + spawn verification ──
# bot collision / DISPATCH_FALSE_OK / capability null / task md missing / cron
# registration failure 5 entry 에서 exit 전 disk handoff marker 박제. spawn
# verification 은 _verify_bot_spawn (§5.2.1, N=15s) 를 경유한다.
try:  # 모듈 부재(fresh checkout 등)에도 dispatch 본기능은 영향 없음 (비차단)
    sys.path.insert(0, str(_REPO_ROOT / "scripts" / "harness" / "v36"))
    from failure_callback_dispatcher import (  # noqa: E402
        write_handoff_marker as _fcb_write_handoff,
    )
    from terminal_state_classifier import _verify_bot_spawn  # noqa: E402,F401
except ImportError:  # pragma: no cover (모듈 부재만 흡수 · NameError 등 programming error 는 전파)
    _fcb_write_handoff = None
    _verify_bot_spawn = None  # type: ignore


def _dispatch_emit_handoff(terminal_state, failure_kind, task_id="unknown", **kw):
    """§5.2 dispatch inner instrumentation: failure handoff marker 박제 (비차단).

    bot_collision→BLOCKED · dispatch_false_ok/capability_null/cron_registration_
    failure→INFRA_DEFECT · task_md_missing→PERMISSION_FAIL.
    """
    if _fcb_write_handoff is None:
        return None
    events_dir = os.environ.get(
        "FAILURE_CALLBACK_2712_EVENTS_DIR",
        str(_REPO_ROOT / "memory" / "events"),
    )
    try:
        return _fcb_write_handoff(
            task_id, terminal_state, failure_kind=failure_kind,
            events_dir=events_dir, **kw,
        )
    except Exception:
        return None


def _main_with_failure_guard() -> None:
    """main() 을 fail-closed 로 감싼다: dispatch 단계 crash 시 INFRA_DEFECT
    handoff marker 박제 후 원래 예외 re-raise (exit_code 보존)."""
    _task_id = "unknown"
    for i, a in enumerate(sys.argv):
        if a in ("--task-id", "--task") and i + 1 < len(sys.argv):
            _task_id = sys.argv[i + 1]
        elif a.startswith("--task-file") and i + 1 < len(sys.argv):
            _task_id = Path(sys.argv[i + 1]).stem
    try:
        main()
    except BaseException:
        _dispatch_emit_handoff(
            "INFRA_DEFECT", "dispatch_runtime_crash", task_id=_task_id
        )
        raise


if __name__ == "__main__":
    _main_with_failure_guard()
