"""`okstra plan-verify` 의 진입점.

판정 로직은 `validators/validate-run.py --section plan-body` 가 전부 갖고 있다.
이 모듈이 하는 일은 둘뿐이다 — 그 `--section` 값을 이 명령이 정하는 것으로
못박고, 자기 이름의 도움말을 갖는 것. 검증기의 파서를 그대로 보여 주면 prog 가
`validate-run.py` 로 나오고, 여기서 금지된 `--section` 이 선택 가능한 플래그로
보인다.
"""
from __future__ import annotations

import argparse
import subprocess
import sys
from pathlib import Path

from .report_finalize import resolve_workspace_validator

_CLI_EPILOG = r"""Usage:
  okstra plan-verify --narrative <report-writer-narrative.md> --state <plan-body-verification.json>
  okstra plan-verify --report <final-report-implementation-planning-<seq>.data.json>

Recomputes the gate from the convergence-owned state's `planItems[].verdicts`
before publication. The `--report` form reads historical v2 reports. It runs
every plan-body contract check that a round can be judged on its own — verdict
provenance, fixability, subject substance, self-fix grouping, round recording,
clarification matching, and the state-file round history.

Emits one JSON object:

  gate.recomputed      the gate value this round's votes actually support
  gate.blockedBy       the `gateBlockedBy` causes, recomputed
  gate.blockingItems   the plan items classified `majority-disagree`
  gate.items[]         per-item classification
  failures[]           blocking contract violations — exit code 2 when non-empty
  advisories[]         contract findings that are recorded, not round-blocking
  warnings[]           advisory signals (self-fix recurrence, uniform verifier)

Exit code 0 means no blocking failure, not "no finding". What blocks is the
allowlist in `scripts/okstra_ctl/blocking_checks.py` — the same set the finished
run's validation blocks on, so a finding the completed run would let pass cannot
hold a round open mid-loop. Everything else lands in `advisories[]` and on
stderr as `validate-run: advisory — ...`; record it, then continue the round.

Run this at every round boundary and record what it returns. The single-vote
blocking kinds, the advisory-only kinds and the P-Var / P-Rb exemptions live in
this one implementation — a lead that tallies the verdicts by hand instead is
re-deriving them per round, and a round scored wrong spends its self-fix budget
on the wrong items.
"""


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(
        prog="okstra plan-verify",
        description="Score the §5.5.9 plan-body gate for one self-fix round.",
        epilog=_CLI_EPILOG,
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    parser.add_argument("--workspace-root", required=True,
                        help=argparse.SUPPRESS)
    parser.add_argument("--narrative", default="",
                        help="the report-writer narrative this round scored")
    parser.add_argument("--state", default="",
                        help="the convergence-owned plan-body-verification.json")
    parser.add_argument("--report", default="",
                        help="a historical v2 final-report .data.json")
    args = parser.parse_args(argv)

    forwarded: list[str] = ["--section", "plan-body"]
    for flag in ("narrative", "state", "report"):
        value = getattr(args, flag)
        if value:
            forwarded += [f"--{flag}", value]

    validator = resolve_workspace_validator(Path(args.workspace_root), "validate-run.py")
    return subprocess.run([sys.executable, str(validator), *forwarded], check=False).returncode


if __name__ == "__main__":
    raise SystemExit(main())
