name: Task Guard
# task-2449 Fix 6: CI kill-switch (별도 workflow — ci.yml 보호)
# 회장 절대 기준: taskctl을 거치지 않고는 main을 절대 변경할 수 없다.
#
# 주의:
#   - 본 workflow는 .github/workflows/ci.yml과 독립적으로 동작합니다.
#   - 기존 8 required CI checks (cancel-kill-switch / qc-check / hidden-path-audit
#     / lock-in-check / merge-safety-check / gemini-review-gate / ci/guard / guard)
#     은 절대 수정하지 않습니다 (task-2440/2445 ruleset 보호).
#   - ruleset 등록은 회장이 직접 처리합니다.

on:
  pull_request:
    branches: [main]
  push:
    branches-ignore: [main]

jobs:
  task-state-check:
    name: taskctl-state-guard
    runs-on: ubuntu-latest
    timeout-minutes: 5
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Extract task-id from branch / PR title
        id: extract
        run: |
          BRANCH="${{ github.head_ref || github.ref_name }}"
          PR_TITLE="${{ github.event.pull_request.title || '' }}"
          TASK_ID=$(echo "$BRANCH" | grep -oE 'task-[0-9]+(\+[0-9]+)?' | head -n1 || true)
          if [[ -z "$TASK_ID" ]]; then
            TASK_ID=$(echo "$PR_TITLE" | grep -oE 'task-[0-9]+(\+[0-9]+)?' | head -n1 || true)
          fi
          echo "task_id=$TASK_ID" >> "$GITHUB_OUTPUT"
          echo "[guard.yml] resolved task_id='$TASK_ID' (branch=$BRANCH)"
      - name: Check taskctl state — block CANCELLED
        if: steps.extract.outputs.task_id != ''
        env:
          TASK_ID: ${{ steps.extract.outputs.task_id }}
          WORKSPACE: ${{ github.workspace }}
        run: |
          set -euo pipefail
          if [[ ! -f scripts/taskctl.py ]]; then
            echo "[guard.yml] scripts/taskctl.py 미존재 — skip (task-2449 미배포)"
            exit 0
          fi
          STATE_JSON=$(python3 scripts/taskctl.py status "$TASK_ID" --machine 2>/dev/null || echo '{}')
          CURRENT=$(echo "$STATE_JSON" | python3 -c "
          import json, sys
          try:
              d = json.loads(sys.stdin.read())
              print(d.get('current_state') or '')
          except Exception:
              pass
          " || true)
          echo "[guard.yml] $TASK_ID current_state='$CURRENT'"
          if [[ "$CURRENT" == "CANCELLED" ]]; then
            echo "::error::task $TASK_ID state=CANCELLED — CI FAIL"
            exit 1
          fi
      - name: Run guard.sh pre-push (graceful)
        if: steps.extract.outputs.task_id != ''
        env:
          TASK_ID: ${{ steps.extract.outputs.task_id }}
          WORKSPACE: ${{ github.workspace }}
        run: |
          # capability snapshot + task.md 모두 미존재 시 skip (MVP 신뢰 모델)
          # — dispatch 미수행 / 신규 task / 외부 PR 등 정상 경로
          SNAP="memory/capabilities/${TASK_ID}.json"
          TASK_FILE="memory/tasks/${TASK_ID}.md"
          if [[ ! -f "$SNAP" && ! -f "$TASK_FILE" ]]; then
            echo "[guard.yml] capability snapshot + task.md 모두 미존재 — graceful skip"
            exit 0
          fi
          if [[ -f scripts/guard.sh ]]; then
            bash scripts/guard.sh pre-push "$TASK_ID" || {
              echo "::error::guard.sh pre-push FAIL ($TASK_ID)"
              exit 1
            }
          fi
      - name: Run qc_report_guard (graceful)
        if: steps.extract.outputs.task_id != ''
        env:
          TASK_ID: ${{ steps.extract.outputs.task_id }}
        run: |
          # qc-result 미존재 시 skip (보고서 미작성 단계)
          QC_RESULT="memory/events/${TASK_ID}.qc-result"
          if [[ ! -f "$QC_RESULT" ]]; then
            echo "[guard.yml] qc-result 미존재 — graceful skip"
            exit 0
          fi
          if [[ -f scripts/qc_report_guard.py ]]; then
            python3 scripts/qc_report_guard.py --task-id "$TASK_ID" --workspace "$GITHUB_WORKSPACE" || {
              echo "::error::qc_report_guard FAIL ($TASK_ID)"
              exit 1
            }
          fi
      - name: Result
        run: echo "[guard.yml] task-state-check PASS"
