#!/usr/bin/env bash
# 판정: 5.2e decide → proof 추출 → 5.2g verify-proof → 5.2g2 backlog → 5.2h 기록(통과 경로만).
# 선행: post-a.sh 통과. hybrid 면 l3-poll.sh 가 done 이어야 한다 (L1 이 실패한 경우는 L3 를 기다리지 않는다).
# exit 0 = converged (다음: seal-converged.sh) · 12 = 그 밖 (divergent 면 라운드 상한에서 seal-divergent-hybrid.sh)
set -euo pipefail
source "$(dirname "$0")/env.sh" "${1:-}"

L1="$STATE/l1.json"; L2="$STATE/l2.json"; L3="$STATE/l3.json"
MODE="$(jread "$STATE/mode.json" 'j.mode' codex)"
FIRES_L3="$(jread "$STATE/mode.json" 'j.fires&&j.fires.l3?1:0' 0)"
L1_V="$(jread "$L1" 'j.verdict' none)"

# hybrid + L1 통과인데 L3 기록이 없거나 다른 실행 것이면 판정할 수 없다 (5.2f succeeded 와 같은 조건).
if [ "$FIRES_L3" = 1 ] && [ "$L1_V" = converged ]; then
  NONCE="$(cat "$STATE/l3-run-nonce" 2>/dev/null || printf '')"
  if [ -z "$NONCE" ] || [ "$(jread "$L3" 'j.run_nonce||""' "")" != "$NONCE" ]; then
    record_stop 5.2f
    echo "HALT_STAGE=5.2f"; echo "L3 기록이 이 실행의 것이 아니다 (l3-poll.sh 가 done 이 아니다). 판정하지 않는다."; exit 12
  fi
fi

# 5.2e decide. 판정 전에 l2.json 을 고치면 DD13 해시 바인드로 unavailable 이 된다 — 흡수는 판정 뒤에.
DECIDE_EXIT=0
L3_ARG=()
[ -f "$L3" ] && L3_ARG=(--l3-file "$L3")
node "$PLAN_NODE_CLI" decide --mode "$MODE" --plan "$PLAN_REL" \
  --l1-file "$L1" --l2-file "$L2" ${L3_ARG[@]+"${L3_ARG[@]}"} \
  --evidence ".claude/state/plan-review/l2.json" > "$STATE/decision.json" 2> "$MCCP_TMP/decide.err" || DECIDE_EXIT=$?

# proof 는 판정 직후 비우고 새로 쓴다 (지난 라운드의 converged proof 가 살아남지 않게).
rm -f "$STATE/proof.json"
PROOF_EXIT=0
node -e 'const fs=require("fs");const j=JSON.parse(fs.readFileSync(process.argv[1],"utf8"));if(j.review_proof)fs.writeFileSync(process.argv[2],JSON.stringify(j.review_proof,null,2));' \
  "$STATE/decision.json" "$STATE/proof.json" || PROOF_EXIT=$?
if [ "$PROOF_EXIT" != 0 ]; then
  record_stop 5.2e-proof
  echo "HALT_STAGE=5.2e-proof"; echo "proof 추출 실패: 판정을 기록할 수 없어 receipt 를 만들 수 없다."; exit 12
fi

VERDICT="$(jread "$STATE/decision.json" 'j.review_verdict' unavailable)"
SOURCE="$(jread "$STATE/decision.json" 'j.review_source' none)"
FWD="$(jread "$STATE/decision.json" 'j.forwardCodexVerdict?1:0' 0)"
L3_V="$(jread "$L3" 'j.verdict' none)"
REASON="$(jread "$STATE/decision.json" 'j.reason' '')"
echo "DECISION verdict=$VERDICT source=$SOURCE forwardCodexVerdict=$([ "$FWD" = 1 ] && echo true || echo false) L3=$L3_V"
echo "REASON=$(printf '%s' "$REASON" | tr '\n\r' '  ')"

if [ "$DECIDE_EXIT" != 0 ]; then
  record_stop 5.2e
  echo "HALT_STAGE=5.2e"
  echo "판정 정지 (decide exit $DECIDE_EXIT). 위 REASON 이 회복 경로를 말한다. stderr: $MCCP_TMP/decide.err"
  exit 12
fi

# 5.2g 증거 검증 (proof 가 있을 때만)
if [ -f "$STATE/proof.json" ]; then
  VERIFY_EXIT=0
  node "$PLAN_NODE_CLI" verify-proof --proof-file "$STATE/proof.json" >/dev/null 2>&1 || VERIFY_EXIT=$?
  if [ "$VERIFY_EXIT" != 0 ]; then
    record_stop 5.2g; echo "HALT_STAGE=5.2g"; echo "proof 증거 검증 실패 (exit $VERIFY_EXIT)."; exit 12
  fi
fi

# 5.2g2 단일통과 완화 시에만 backlog 로 흡수 (gatekit 은 단일통과를 쓰지 않으므로 보통 해당 없음).
SP_REASON="$(jread "$STATE/decision.json" 'j.single_pass_reason||""' "")"
if [ -n "$SP_REASON" ]; then
  node "$PLAN_NODE_CLI" backlog-append --review-dir "$STATE" --plan "$PLAN_REL" --slug "$SLUG" \
    || { record_stop 5.2g2; echo "HALT_STAGE=5.2g2"; echo "backlog 기록 실패: 단일통과 완화 불가."; exit 12; }
fi

# 5.2h 기록: 통과 경로만 (단계 인자 없음 = pass). 차단 경로는 위에서 자기 단계로 이미 기록했다.
if [ "$VERDICT" = converged ] && [ "$DECIDE_EXIT" = 0 ]; then
  record_pass
  echo "RECORD=.claude/reviews/plan-review-$SLUG.md"
  echo "NEXT=seal-converged.sh $GK_N"
  exit 0
fi
record_stop 5.2e
echo "HALT_STAGE=5.2e"; echo "판정이 converged 가 아니다 (verdict=$VERDICT). 라운드 상한이면 seal-divergent-hybrid.sh $GK_N, 아니면 흡수 후 pre.sh 로 새 라운드."
exit 12
