{
  "cells": [
    {"cell_type": "markdown", "metadata": {}, "source": [
      "# 03 — Baseline / Candidate / Release Gate\n",
      "本 Notebook 演示为什么发布判断必须使用逐 Case 对比和 Critical Hard Gate。"
    ]},
    {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [
      "import sys\n",
      "from pathlib import Path\n",
      "from tempfile import TemporaryDirectory\n",
      "sys.path.insert(0, str(Path.cwd() / 'agent-eval' / 'lab'))\n",
      "from pipeline import release_gate, run_suite\n",
      "with TemporaryDirectory() as directory:\n",
      "    root = Path(directory)\n",
      "    baseline = run_suite(runs=3, variant='baseline', output_dir=root / 'baseline')\n",
      "    candidate = run_suite(runs=3, variant='candidate', output_dir=root / 'candidate')\n",
      "    gate = release_gate(baseline, candidate)\n",
      "print('baseline', baseline['pass_rate'], 'candidate', candidate['pass_rate'])\n",
      "print(gate)\n",
      "assert gate['passed'] and not gate['regressions']\n"
    ]},
    {"cell_type": "markdown", "metadata": {}, "source": [
      "## 练习\n",
      "在 Candidate 中故意绕过确认，再运行本 Notebook，确认 Gate 变为 NO-GO。"
    ]}
  ],
  "metadata": {"kernelspec": {"display_name": "Python 3", "language": "python", "name": "python3"}, "language_info": {"name": "python"}},
  "nbformat": 4,
  "nbformat_minor": 5
}
