import json
import os
import subprocess
import sys
from pathlib import Path

from flask import Flask
from sqlalchemy import create_engine, text

from database.manager import Base
from services.market_intel import MarketIntelService
from services.market_intel.service import MARKET_INTEL_TABLES
from services.market_intel.adapters import get_adapter, get_adapter_summaries
from services.market_intel.candidate_preview import build_candidate_preview_from_discovery
from services.market_intel.discovery_runner import ManualDiscoveryRunner
from services.market_intel.html_diagnostics import parse_html_diagnostics
from services.market_intel.mcp_activation_runbook import build_mcp_activation_runbook_preview
from services.market_intel.mcp_contract import build_mcp_tool_contract_preview
from services.market_intel.mcp_deploy_preflight import build_mcp_deploy_preflight_plan
from services.market_intel.mcp_fetch_gate import build_mcp_fetch_gate_preview
from services.market_intel.mcp_readiness import build_mcp_readiness_plan
from services.market_intel.live_db_inventory import build_live_db_inventory_preview
from services.market_intel.manual_sample_review import evaluate_manual_sample_result
from services.market_intel.platform_seed_db_diff import build_platform_seed_db_diff_plan
from services.market_intel.schema_db_probe import build_schema_db_probe_plan


TEST_APPROVAL_TOKEN = "test-market-intel-approval-token"


def _market_intel_sample_result(batch_id="sample-batch-receipt"):
    return {
        "batch_id": batch_id,
        "platform_code": "momo",
        "source_key": "homepage",
        "source_url": "https://www.momoshop.com.tw/",
        "status": "fetched",
        "status_code": 200,
        "content_length": 1700,
        "page_hash": "b" * 64,
        "title": "MOMO 活動",
        "diagnostics": {
            "link_count": 1,
            "same_host_link_count": 1,
            "campaign_link_candidates": [
                {
                    "confidence_band": "high",
                    "score": 94,
                    "url": "https://www.momoshop.com.tw/activity/sample",
                    "text": "品牌活動",
                },
            ],
        },
    }


def _build_candidate_queue_writer_receipt_fixture(batch_id="sample-batch-receipt"):
    from services.market_intel.candidate_queue_writer_cli import (
        build_candidate_queue_writer_cli_plan,
    )
    from services.market_intel.candidate_queue_writer_operator_drill import (
        build_candidate_queue_writer_operator_drill,
    )
    from services.market_intel.candidate_queue_writer_postwrite_smoke import (
        build_candidate_queue_writer_postwrite_smoke,
    )
    from services.market_intel.candidate_queue_writer_preflight import (
        build_candidate_queue_writer_preflight,
    )
    from services.market_intel.candidate_queue_writer_run_package import (
        build_candidate_queue_writer_run_package,
    )
    from services.market_intel.candidate_queue_writer_run_readiness import (
        build_candidate_queue_writer_run_readiness,
    )

    service = MarketIntelService()
    sample_result = _market_intel_sample_result(batch_id=batch_id)
    transaction = service.build_manual_sample_candidate_queue_transaction(
        sample_result=sample_result
    )
    preflight = build_candidate_queue_writer_preflight(
        transaction_preview=transaction,
        execute_requested=False,
    )
    writer_status = build_candidate_queue_writer_cli_plan(
        transaction_preview=transaction,
        writer_preflight=preflight,
    )
    postwrite_smoke = build_candidate_queue_writer_postwrite_smoke(
        transaction_preview=transaction,
        execute_requested=False,
    )
    operator_drill = build_candidate_queue_writer_operator_drill(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=postwrite_smoke,
    )
    run_package = build_candidate_queue_writer_run_package(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=postwrite_smoke,
        operator_drill=operator_drill,
    )
    operator_evidence = {
        "reviewed_sample_json_path": "artifacts/market_intel/reviewed.json",
        "backup_artifact_path": "scripts/tools/backups/backup.zip",
        "preflight_artifact_path": "artifacts/market_intel/preflight.json",
        "migration_live_smoke_passed": True,
        "operator_acknowledged_shell_only_token": True,
        "writer_output_json_path": "artifacts/market_intel/writer-output.json",
        "postwrite_smoke_json_path": "artifacts/market_intel/postwrite-smoke.json",
        "operator_confirmed_no_token_in_artifacts": True,
        "receipt_notes": "small-batch queue writer receipt reviewed",
    }
    run_readiness = build_candidate_queue_writer_run_readiness(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=postwrite_smoke,
        operator_drill=operator_drill,
        run_package=run_package,
        operator_evidence=operator_evidence,
    )
    expected_keys = sorted(
        str(statement["lookup"]["dedupe_key"])
        for statement in transaction["statements"]
    )
    writer_output = {
        "mode": "candidate_queue_writer_cli_executed",
        "exit_code": 0,
        "approval_token_present": True,
        "approval_token_valid": True,
        "approval_token_secret_configured": True,
        "approval_env_var": "MARKET_INTEL_QUEUE_WRITE_APPROVAL",
        "writes_executed": True,
        "would_write_database": True,
        "database_connection_opened": True,
        "explicit_transaction_opened": True,
        "database_write_executed": True,
        "database_commit_executed": True,
        "database_rollback_executed": False,
        "external_network_executed": False,
        "scheduler_attached": False,
        "inserted_count": len(expected_keys),
        "skipped_count": 0,
        "affected_dedupe_keys": expected_keys,
        "skipped_dedupe_keys": [],
    }
    postwrite_smoke_result = {
        "mode": "candidate_queue_writer_postwrite_smoke_read_only",
        "postwrite_smoke_passed": True,
        "ready_for_operator_review": True,
        "read_only_query_executed": True,
        "database_connection_opened": True,
        "database_write_executed": False,
        "database_commit_executed": False,
        "external_network_executed": False,
        "scheduler_attached": False,
        "expected_dedupe_key_count": len(expected_keys),
        "found_count": len(expected_keys),
        "missing_count": 0,
        "found_dedupe_keys": expected_keys,
        "missing_dedupe_keys": [],
        "row_summaries": [
            {
                "dedupe_key": key,
                "review_state": "needs_review",
                "priority_lane": "watch",
                "total_score": 82.5,
                "source_batch_id": batch_id,
                "created_at": "2026-05-19T12:00:00",
                "updated_at": "2026-05-19T12:00:00",
            }
            for key in expected_keys
        ],
    }
    return {
        "sample_result": sample_result,
        "transaction": transaction,
        "run_readiness": run_readiness,
        "operator_evidence": operator_evidence,
        "writer_output": writer_output,
        "postwrite_smoke_result": postwrite_smoke_result,
        "expected_keys": expected_keys,
    }


def _build_ready_review_decision_transaction(
    batch_id="sample-batch-review-decision-writer"
):
    from services.market_intel.candidate_queue_review_decision import (
        build_candidate_queue_review_decision,
    )
    from services.market_intel.candidate_queue_review_decision_approval import (
        build_candidate_queue_review_decision_approval,
    )
    from services.market_intel.candidate_queue_review_decision_transaction import (
        build_candidate_queue_review_decision_transaction,
    )

    fixture = _build_candidate_queue_writer_receipt_fixture(batch_id)
    inventory = {
        "mode": "candidate_queue_review_inventory_preview",
        "review_inventory_ready": True,
        "expected_dedupe_keys": fixture["expected_keys"],
        "row_summaries": [
            {
                "dedupe_key": fixture["expected_keys"][0],
                "review_state": "needs_review",
                "priority_lane": "watch",
                "total_score": 82.5,
            }
        ],
    }
    decision_evidence = {
        "reviewer_id": "operator-a",
        "proposed_review_decision": "confirmed",
        "decision_notes": "evidence reviewed manually",
        "operator_confirmed_manual_decision_only": True,
        "operator_confirmed_no_api_db_write": True,
        "operator_confirmed_no_scheduler_attach": True,
    }
    approval_evidence = {
        **decision_evidence,
        "decision_approval_notes": "approved for cli-only transaction preview",
        "operator_confirmed_decision_payload_reviewed": True,
        "operator_confirmed_decision_apply_requires_cli": True,
        "operator_confirmed_review_state_update_is_not_api": True,
    }
    transaction_evidence = {
        **approval_evidence,
        "decision_transaction_notes": "payload reviewed for shell transaction",
        "operator_confirmed_transaction_payload_reviewed": True,
        "operator_confirmed_cli_only_transaction": True,
    }
    decision = build_candidate_queue_review_decision(
        review_inventory=inventory,
        operator_evidence=decision_evidence,
    )
    approval = build_candidate_queue_review_decision_approval(
        review_decision=decision,
        operator_evidence=approval_evidence,
    )
    transaction = build_candidate_queue_review_decision_transaction(
        decision_approval=approval,
        operator_evidence=transaction_evidence,
    )
    return transaction, transaction_evidence


def _build_review_decision_writer_receipt_fixture(
    batch_id="sample-batch-review-decision-writer-closeout"
):
    from services.market_intel.candidate_queue_review_decision_writer_cli import (
        build_candidate_queue_review_decision_writer_cli_plan,
    )
    from services.market_intel.candidate_queue_review_decision_writer_preflight import (
        build_candidate_queue_review_decision_writer_preflight,
    )
    from services.market_intel.candidate_queue_review_decision_writer_postwrite_smoke import (
        build_candidate_queue_review_decision_writer_postwrite_smoke,
    )
    from services.market_intel.candidate_queue_review_decision_writer_operator_drill import (
        build_candidate_queue_review_decision_writer_operator_drill,
    )
    from services.market_intel.candidate_queue_review_decision_writer_run_package import (
        build_candidate_queue_review_decision_writer_run_package,
    )
    from services.market_intel.candidate_queue_review_decision_writer_run_readiness import (
        build_candidate_queue_review_decision_writer_run_readiness,
    )
    from services.market_intel.candidate_queue_review_decision_writer_run_receipt import (
        build_candidate_queue_review_decision_writer_run_receipt,
    )

    transaction, operator_evidence = _build_ready_review_decision_transaction(
        batch_id
    )
    expected_key = transaction["statements"][0]["lookup"]["dedupe_key"]
    operator_evidence = {
        **operator_evidence,
        "operator_confirmed_manual_shell_window": True,
        "operator_confirmed_post_update_inventory_planned": True,
        "operator_drill_notes": "review_state shell drill reviewed",
    }
    writer_status = build_candidate_queue_review_decision_writer_cli_plan(
        transaction_preview=transaction,
        operator_evidence=operator_evidence,
    )
    preflight = build_candidate_queue_review_decision_writer_preflight(
        writer_status=writer_status,
        transaction_preview=transaction,
        operator_evidence=operator_evidence,
    )
    smoke = build_candidate_queue_review_decision_writer_postwrite_smoke(
        transaction_preview=transaction,
        execute_requested=False,
    )
    drill = build_candidate_queue_review_decision_writer_operator_drill(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=smoke,
        operator_evidence=operator_evidence,
    )
    package = build_candidate_queue_review_decision_writer_run_package(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=smoke,
        operator_drill=drill,
    )
    receipt_evidence = {
        **operator_evidence,
        "review_state_transaction_json_path": (
            "artifacts/market_intel/review-state-transaction.json"
        ),
        "backup_artifact_path": "scripts/tools/backups/backup.zip",
        "preflight_artifact_path": (
            "artifacts/market_intel/review-state-preflight.json"
        ),
        "operator_confirmed_review_state_preflight_only": True,
        "operator_acknowledged_shell_only_token": True,
        "review_state_writer_output_json_path": (
            "artifacts/market_intel/review-state-writer-output.json"
        ),
        "review_state_postwrite_smoke_json_path": (
            "artifacts/market_intel/review-state-postwrite-smoke.json"
        ),
        "operator_confirmed_no_token_in_artifacts": True,
        "receipt_notes": "review_state receipt reviewed",
    }
    readiness = build_candidate_queue_review_decision_writer_run_readiness(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=smoke,
        operator_drill=drill,
        run_package=package,
        operator_evidence=receipt_evidence,
    )
    writer_output = {
        "mode": "candidate_queue_review_decision_writer_cli_executed",
        "exit_code": 0,
        "approval_token_present": True,
        "approval_token_valid": True,
        "approval_token_secret_configured": True,
        "approval_env_var": "MARKET_INTEL_QUEUE_WRITE_APPROVAL",
        "writes_executed": True,
        "would_write_database": True,
        "database_connection_opened": True,
        "explicit_transaction_opened": True,
        "database_write_executed": True,
        "database_commit_executed": True,
        "database_rollback_executed": False,
        "external_network_executed": False,
        "scheduler_attached": False,
        "api_updates_review_state": False,
        "review_state_update_executed": True,
        "updated_count": 1,
        "skipped_count": 0,
        "affected_dedupe_keys": [expected_key],
        "skipped_dedupe_keys": [],
    }
    postwrite_smoke_result = {
        "mode": "candidate_queue_review_decision_writer_postwrite_smoke_read_only",
        "postwrite_smoke_passed": True,
        "review_state_update_verified": True,
        "ready_for_operator_review": True,
        "read_only_query_executed": True,
        "database_connection_opened": True,
        "database_write_executed": False,
        "database_commit_executed": False,
        "external_network_executed": False,
        "scheduler_attached": False,
        "expected_dedupe_key_count": 1,
        "found_count": 1,
        "missing_count": 0,
        "state_mismatch_count": 0,
        "found_dedupe_keys": [expected_key],
        "missing_dedupe_keys": [],
        "state_mismatches": [],
        "row_summaries": [
            {
                "dedupe_key": expected_key,
                "review_state": "confirmed",
                "priority_lane": "watch",
                "threshold_level": "medium",
                "total_score": 82.5,
                "evidence_bundle_id": "evidence-1",
                "source_batch_id": batch_id,
                "reviewed_at": "2026-05-19T12:30:00",
                "created_at": "2026-05-19T12:00:00",
                "updated_at": "2026-05-19T12:30:00",
            }
        ],
    }
    receipt = build_candidate_queue_review_decision_writer_run_receipt(
        transaction_preview=transaction,
        run_readiness=readiness,
        writer_output=writer_output,
        postwrite_smoke_result=postwrite_smoke_result,
        operator_evidence=receipt_evidence,
    )
    return {
        "transaction": transaction,
        "operator_evidence": receipt_evidence,
        "writer_output": writer_output,
        "postwrite_smoke_result": postwrite_smoke_result,
        "receipt": receipt,
    }


def test_market_intel_defaults_are_safe():
    service = MarketIntelService()
    status = service.get_runtime_status().to_dict()
    plan = service.build_dry_run_plan("momo")

    assert status["enabled"] is False
    assert status["crawler_enabled"] is False
    assert status["write_enabled"] is False
    assert status["database_write_allowed"] is False
    assert plan["would_discover_campaigns"] is False
    assert plan["would_write_database"] is False


def test_market_intel_adapter_registry_is_read_only():
    summaries = get_adapter_summaries()
    codes = {item["platform_code"] for item in summaries}

    assert {"momo", "pchome", "coupang", "shopee"} <= codes
    for summary in summaries:
        policy = summary["safety_policy"]
        assert policy["allow_login"] is False
        assert policy["allow_database_write"] is False
        assert policy["allow_scheduler_attach"] is False


def test_market_intel_discovery_plan_does_not_allow_network_or_write():
    service = MarketIntelService()
    plan = service.build_discovery_plan("momo")

    assert plan["found"] is True
    assert len(plan["plans"]) == 1
    momo_plan = plan["plans"][0]
    assert momo_plan["network_request_allowed"] is False
    assert momo_plan["database_write_allowed"] is False
    assert momo_plan["scheduler_attach_allowed"] is False
    assert momo_plan["sources"]


def test_unknown_adapter_returns_diagnostic_error():
    assert get_adapter("unknown") is None
    plan = MarketIntelService().build_discovery_plan("unknown")
    assert plan["found"] is False
    assert plan["error"] == "未知平台 adapter"


def test_manual_discovery_default_does_not_call_network():
    called = {"count": 0}

    def fake_get(*args, **kwargs):
        called["count"] += 1
        raise AssertionError("預設 dry-run 不應發 HTTP request")

    result = MarketIntelService().run_manual_discovery("momo", fetch=False, http_get=fake_get)

    assert called["count"] == 0
    assert result["found"] is True
    assert result["runs"][0]["status"] == "planned"
    assert result["runs"][0]["sources_fetched"] == 0
    assert all(item["network_executed"] is False for item in result["runs"][0]["results"])


def test_manual_discovery_fetch_is_blocked_when_flags_are_off():
    called = {"count": 0}

    def fake_get(*args, **kwargs):
        called["count"] += 1
        raise AssertionError("flags 關閉時不應發 HTTP request")

    result = MarketIntelService().run_manual_discovery("momo", fetch=True, http_get=fake_get)

    assert called["count"] == 0
    assert result["runs"][0]["status"] == "blocked"
    assert result["runs"][0]["network_allowed"] is False
    assert result["runs"][0]["database_write_allowed"] is False
    assert result["mcp_fetch_gate"]["network_request_allowed"] is False
    assert result["runs"][0]["network_gate"]["manual_fetch_gate_open"] is False


def test_manual_runner_fetch_can_be_blocked_by_mcp_gate_even_when_flags_allow():
    class RuntimeStatus:
        enabled = True
        crawler_enabled = True

    called = {"count": 0}

    def fake_get(*args, **kwargs):
        called["count"] += 1
        raise AssertionError("MCP gate 關閉時不應發 HTTP request")

    gate = {
        "manual_fetch_gate_open": False,
        "network_request_allowed": False,
        "blocked_reasons": ["mcp_router_enabled"],
        "operator_message": "人工 fetch 仍被 MCP gate 阻擋",
    }
    adapter = get_adapter("momo")
    runner = ManualDiscoveryRunner(
        runtime_status=RuntimeStatus(),
        http_get=fake_get,
        network_allowed_override=False,
        network_gate=gate,
    )
    result = runner.run(adapter, fetch=True).to_dict()

    assert called["count"] == 0
    assert result["status"] == "blocked"
    assert result["network_allowed"] is False
    assert result["network_gate"]["blocked_reasons"] == ["mcp_router_enabled"]
    assert "MCP gate" in result["error_message"]


def test_manual_runner_fetch_uses_injected_http_get_when_allowed():
    class RuntimeStatus:
        enabled = True
        crawler_enabled = True

    class Response:
        status_code = 200
        text = "<html><title>活動頁</title><body>OK</body></html>"

    called = {"count": 0}

    def fake_get(url, **kwargs):
        called["count"] += 1
        return Response()

    adapter = get_adapter("momo")
    runner = ManualDiscoveryRunner(runtime_status=RuntimeStatus(), http_get=fake_get)
    result = runner.run(adapter, fetch=True).to_dict()

    assert called["count"] == len(adapter.campaign_sources())
    assert result["status"] == "success"
    assert result["database_write_allowed"] is False
    assert result["scheduler_attached"] is False
    assert result["sources_fetched"] == len(adapter.campaign_sources())
    assert result["results"][0]["title"] == "活動頁"
    assert result["results"][0]["diagnostics"]["title"] == "活動頁"


def test_html_diagnostics_extracts_campaign_link_candidates():
    html = """
    <html>
      <head><title>五月品牌日</title></head>
      <body>
        <a href="/event/brand-day">品牌日活動</a>
        <a href="https://example.com/help">客服中心</a>
        <a href="https://other.example/promo">外部 promo</a>
      </body>
    </html>
    """

    diagnostics = parse_html_diagnostics(html, base_url="https://shop.example").to_dict()

    assert diagnostics["title"] == "五月品牌日"
    assert diagnostics["link_count"] == 3
    assert diagnostics["same_host_link_count"] == 1
    assert diagnostics["campaign_link_candidates"][0]["href"] == "https://shop.example/event/brand-day"
    assert diagnostics["campaign_link_candidates"][0]["score"] > 0
    assert "generic_score" in diagnostics["campaign_link_candidates"][0]
    assert "platform_score" in diagnostics["campaign_link_candidates"][0]
    assert "confidence_band" in diagnostics["campaign_link_candidates"][0]
    assert "confidence_reason" in diagnostics["campaign_link_candidates"][0]


def test_manual_runner_returns_parser_diagnostics_when_fetch_succeeds():
    class RuntimeStatus:
        enabled = True
        crawler_enabled = True

    class Response:
        status_code = 200
        text = """
        <html>
          <head><title>PChome 優惠活動</title></head>
          <body><a href="/event/sale">限時優惠</a></body>
        </html>
        """

    adapter = get_adapter("pchome")
    runner = ManualDiscoveryRunner(runtime_status=RuntimeStatus(), http_get=lambda *args, **kwargs: Response())
    result = runner.run(adapter, fetch=True).to_dict()
    diagnostics = result["results"][0]["diagnostics"]

    assert diagnostics["title"] == "PChome 優惠活動"
    assert diagnostics["campaign_link_candidates"]
    assert diagnostics["campaign_link_candidates"][0]["is_same_host"] is True


def test_momo_platform_scorer_prioritizes_momo_campaign_links():
    adapter = get_adapter("momo")
    html = """
    <html><title>MOMO 活動</title><body>
      <a href="https://other.example/promo">外部 promo</a>
      <a href="/edm/cmmedm.jsp">MOMO 品牌日活動</a>
    </body></html>
    """

    diagnostics = parse_html_diagnostics(
        html,
        base_url=adapter.base_url,
        score_link=adapter.score_campaign_link,
    ).to_dict()

    first = diagnostics["campaign_link_candidates"][0]
    assert first["href"] == "https://www.momoshop.com.tw/edm/cmmedm.jsp"
    assert first["platform_score"] > 0
    assert first["confidence_band"] == "high"


def test_pchome_platform_scorer_prioritizes_region_campaign_links():
    adapter = get_adapter("pchome")
    html = """
    <html><title>PChome 活動</title><body>
      <a href="https://other.example/event">外部 event</a>
      <a href="/region/DDAB">PChome 24h 美妝優惠</a>
    </body></html>
    """

    diagnostics = parse_html_diagnostics(
        html,
        base_url=adapter.base_url,
        score_link=adapter.score_campaign_link,
    ).to_dict()

    first = diagnostics["campaign_link_candidates"][0]
    assert first["href"] == "https://24h.pchome.com.tw/region/DDAB"
    assert first["platform_score"] > 0
    assert first["confidence_band"] == "high"


def test_coupang_platform_scorer_prioritizes_official_campaign_links():
    adapter = get_adapter("coupang")
    html = """
    <html><title>Coupang 活動</title><body>
      <a href="https://other.example/event">外部 event</a>
      <a href="/np/coupangglobal">酷澎 火箭跨境優惠</a>
    </body></html>
    """

    diagnostics = parse_html_diagnostics(
        html,
        base_url=adapter.base_url,
        score_link=adapter.score_campaign_link,
    ).to_dict()

    first = diagnostics["campaign_link_candidates"][0]
    assert first["href"] == "https://www.tw.coupang.com/np/coupangglobal"
    assert first["platform_score"] > 0
    assert first["confidence_band"] == "high"


def test_shopee_platform_scorer_prioritizes_mall_campaign_links():
    adapter = get_adapter("shopee")
    html = """
    <html><title>Shopee 活動</title><body>
      <a href="https://other.example/event">外部 event</a>
      <a href="/mall">蝦皮商城 品牌限時優惠</a>
    </body></html>
    """

    diagnostics = parse_html_diagnostics(
        html,
        base_url=adapter.base_url,
        score_link=adapter.score_campaign_link,
    ).to_dict()

    first = diagnostics["campaign_link_candidates"][0]
    assert first["href"] == "https://shopee.tw/mall"
    assert first["platform_score"] > 0
    assert first["confidence_band"] == "high"


def test_confidence_bands_cover_high_medium_low():
    adapter = get_adapter("momo")
    html = """
    <html><title>信心帶測試</title><body>
      <a href="/edm/cmmedm.jsp">MOMO 限時品牌日活動優惠</a>
      <a href="https://neutral.example/event-light">活動</a>
      <a href="https://other.example/sale">清單</a>
    </body></html>
    """

    diagnostics = parse_html_diagnostics(
        html,
        base_url=adapter.base_url,
        score_link=adapter.score_campaign_link,
    ).to_dict()
    bands = {item["href"]: item["confidence_band"] for item in diagnostics["campaign_link_candidates"]}

    assert bands["https://www.momoshop.com.tw/edm/cmmedm.jsp"] == "high"
    assert bands["https://neutral.example/event-light"] == "medium"
    assert bands["https://other.example/sale"] == "low"
    for item in diagnostics["campaign_link_candidates"]:
        assert item["confidence_reason"]


def test_candidate_preview_default_is_empty_and_does_not_call_network():
    called = {"count": 0}

    def fake_get(*args, **kwargs):
        called["count"] += 1
        raise AssertionError("candidate preview 預設不應發 HTTP request")

    preview = MarketIntelService().build_candidate_preview("momo", fetch=False, http_get=fake_get)

    assert called["count"] == 0
    assert preview["candidate_count"] == 0
    assert preview["database_write_allowed"] is False
    assert preview["scheduler_attached"] is False
    assert preview["mcp_fetch_gate_open"] is False
    assert preview["mcp_fetch_gate"]["network_request_allowed"] is False
    assert preview["run_statuses"][0]["status"] == "planned"


def test_candidate_preview_fetch_is_blocked_when_flags_are_off():
    called = {"count": 0}

    def fake_get(*args, **kwargs):
        called["count"] += 1
        raise AssertionError("flags 關閉時 candidate preview 不應發 HTTP request")

    preview = MarketIntelService().build_candidate_preview("momo", fetch=True, http_get=fake_get)

    assert called["count"] == 0
    assert preview["candidate_count"] == 0
    assert preview["run_statuses"][0]["status"] == "blocked"
    assert preview["mcp_fetch_gate_open"] is False
    assert "market_intel_enabled" in preview["mcp_fetch_gate"]["blocked_reasons"]


def test_candidate_preview_aggregates_and_filters_by_band():
    discovery = {
        "platform_code": "all",
        "fetch_requested": True,
        "manual_fetch_allowed": True,
        "runs": [
            {
                "platform_code": "momo",
                "status": "success",
                "sources_planned": 1,
                "sources_fetched": 1,
                "errors": 0,
                "results": [
                    {
                        "source_key": "momo_edm",
                        "name": "MOMO EDM",
                        "url": "https://www.momoshop.com.tw/edm/cmmedm.jsp",
                        "status": "fetched",
                        "diagnostics": {
                            "title": "MOMO 活動",
                            "page_hash": "hash-a",
                            "campaign_link_candidates": [
                                {
                                    "href": "https://www.momoshop.com.tw/edm/a",
                                    "text": "品牌日",
                                    "is_same_host": True,
                                    "score": 20,
                                    "generic_score": 6,
                                    "platform_score": 14,
                                    "confidence_band": "high",
                                    "confidence_reason": "same_host",
                                },
                                {
                                    "href": "https://other.example/sale",
                                    "text": "清單",
                                    "is_same_host": False,
                                    "score": 2,
                                    "generic_score": 2,
                                    "platform_score": 0,
                                    "confidence_band": "low",
                                    "confidence_reason": "external_host",
                                },
                            ],
                        },
                    }
                ],
            }
        ],
    }

    preview = build_candidate_preview_from_discovery(discovery, min_band="medium", limit=10)

    assert preview["candidate_count"] == 1
    assert preview["candidates"][0]["confidence_band"] == "high"
    assert preview["candidates"][0]["platform_code"] == "momo"
    assert preview["candidates"][0]["source_key"] == "momo_edm"


def test_market_intel_preview_template_uses_safe_fetch_false_endpoint():
    template = Path("templates/market_intel/disabled.html").read_text(encoding="utf-8")

    assert "data-market-intel-preview" in template
    assert "data-market-intel-writer" in template
    assert "data-market-intel-cli" in template
    assert "data-market-intel-cli-body" in template
    assert "data-market-intel-db-probe" in template
    assert "data-market-intel-db-probe-body" in template
    assert "data-market-intel-seed-diff" in template
    assert "data-market-intel-seed-diff-body" in template
    assert "data-market-intel-mcp-readiness" in template
    assert "data-market-intel-mcp-servers" in template
    assert "data-market-intel-mcp-checks" in template
    assert "data-market-intel-mcp-tools" in template
    assert "market_intel_contract" in template
    assert "data-market-intel-mcp-preflight" in template
    assert "data-market-intel-mcp-preflight-env" in template
    assert "data-market-intel-mcp-preflight-services" in template
    assert "data-market-intel-mcp-preflight-ports" in template
    assert "data-market-intel-mcp-preflight-fallback" in template
    assert "data-market-intel-mcp-activation" in template
    assert "data-market-intel-mcp-activation-stages" in template
    assert "data-market-intel-mcp-activation-safety" in template
    assert "data-market-intel-mcp-activation-fallback" in template
    assert "data-market-intel-mcp-fetch-gate" in template
    assert "data-market-intel-mcp-fetch-gate-checks" in template
    assert "data-market-intel-mcp-fetch-gate-sequence" in template
    assert "data-market-intel-mcp-fetch-gate-readiness" in template
    assert "data-market-intel-scheduler" in template
    assert "data-market-intel-scheduler-checks" in template
    assert "data-market-intel-scheduler-jobs" in template
    assert "data-market-intel-scheduler-sequence" in template
    assert "data-market-intel-scheduler-fallback" in template
    assert "data-market-intel-match-review" in template
    assert "data-market-intel-match-review-checks" in template
    assert "data-market-intel-match-review-signals" in template
    assert "data-market-intel-match-review-actions" in template
    assert "data-market-intel-match-review-sequence" in template
    assert "data-market-intel-opportunity" in template
    assert "data-market-intel-opportunity-checks" in template
    assert "data-market-intel-opportunity-rules" in template
    assert "data-market-intel-opportunity-severity" in template
    assert "data-market-intel-opportunity-sequence" in template
    assert "data-market-intel-opportunity-scoring" in template
    assert "data-market-intel-opportunity-scoring-checks" in template
    assert "data-market-intel-opportunity-scoring-dimensions" in template
    assert "data-market-intel-opportunity-scoring-thresholds" in template
    assert "data-market-intel-opportunity-scoring-evidence" in template
    assert "data-market-intel-opportunity-scoring-sequence" in template
    assert "data-market-intel-opportunity-evidence" in template
    assert "data-market-intel-opportunity-evidence-checks" in template
    assert "data-market-intel-opportunity-evidence-sections" in template
    assert "data-market-intel-opportunity-evidence-escalation" in template
    assert "data-market-intel-opportunity-evidence-tables" in template
    assert "data-market-intel-opportunity-evidence-sequence" in template
    assert "data-market-intel-opportunity-alert" in template
    assert "data-market-intel-opportunity-alert-checks" in template
    assert "data-market-intel-opportunity-alert-channels" in template
    assert "data-market-intel-opportunity-alert-escalation" in template
    assert "data-market-intel-opportunity-alert-payload" in template
    assert "data-market-intel-opportunity-alert-review" in template
    assert "data-market-intel-opportunity-alert-actions" in template
    assert "data-market-intel-opportunity-alert-queue-contract" in template
    assert "data-market-intel-opportunity-alert-priority-lanes" in template
    assert "data-market-intel-opportunity-alert-queue-indexes" in template
    assert "data-market-intel-opportunity-alert-approval" in template
    assert "data-market-intel-opportunity-alert-sequence" in template
    assert "data-market-intel-migration" in template
    assert "data-market-intel-migration-tables" in template
    assert "data-market-intel-migration-drill" in template
    assert "data-market-intel-migration-drill-checks" in template
    assert "data-market-intel-migration-drill-preapply" in template
    assert "data-market-intel-migration-drill-rollback" in template
    assert "data-market-intel-catalog-review" in template
    assert "data-market-intel-catalog-review-checks" in template
    assert "data-market-intel-catalog-review-findings" in template
    assert "data-market-intel-catalog-review-tables" in template
    assert "data-market-intel-live-smoke" in template
    assert "data-market-intel-live-smoke-checks" in template
    assert "data-market-intel-live-smoke-findings" in template
    assert "data-market-intel-live-smoke-targets" in template
    assert "data-market-intel-live-inventory" in template
    assert "data-market-intel-live-inventory-checks" in template
    assert "data-market-intel-live-inventory-tables" in template
    assert "data-market-intel-live-inventory-platforms" in template
    assert "data-market-intel-live-inventory-alerts" in template
    assert "data-market-intel-manual-sample" in template
    assert "data-market-intel-manual-sample-checks" in template
    assert "data-market-intel-manual-sample-platforms" in template
    assert "data-market-intel-manual-sample-sequence" in template
    assert "data-market-intel-sample-acceptance" in template
    assert "data-market-intel-sample-acceptance-checks" in template
    assert "data-market-intel-sample-acceptance-fields" in template
    assert "data-market-intel-sample-acceptance-rules" in template
    assert "data-market-intel-sample-review" in template
    assert "data-market-intel-sample-review-checks" in template
    assert "data-market-intel-sample-review-findings" in template
    assert "data-market-intel-sample-review-actions" in template
    assert "data-market-intel-sample-review-boundaries" in template
    assert "data-market-intel-sample-review-input" in template
    assert "data-market-intel-sample-review-evaluate" in template
    assert "data-market-intel-sample-candidate-handoff" in template
    assert "data-market-intel-sample-review-actions-rail" in template
    assert ".market-intel-control-actions" in template
    assert "grid-template-columns: minmax(0, 1fr) auto auto auto" not in template
    assert "data-market-intel-sample-candidate-queue-draft" in template
    assert "data-market-intel-sample-candidate-queue-approval" in template
    assert "data-market-intel-sample-candidate-queue-transaction" in template
    assert "data-market-intel-sample-candidate-queue-writer" in template
    assert "data-market-intel-sample-candidate-queue-preflight" in template
    assert "data-market-intel-sample-candidate-queue-run-receipt" in template
    assert "data-market-intel-sample-candidate-queue-run-closeout" in template
    assert "data-market-intel-sample-candidate-queue-review-handoff" in template
    assert "data-market-intel-sample-candidate-queue-review-inventory" in template
    assert "data-market-intel-sample-candidate-queue-review-decision" in template
    assert (
        "data-market-intel-sample-candidate-queue-review-decision-approval"
        in template
    )
    assert "data-market-intel-approval" in template
    assert "data-market-intel-approval-gates" in template
    assert "data-market-intel-deploy" in template
    assert "data-market-intel-deploy-steps" in template
    assert "data-market-intel-deploy-fallback" in template
    assert "market_intel.market_intel_candidate_preview" in template
    assert "market_intel.market_intel_platform_seed_writer_plan" in template
    assert "market_intel.market_intel_seed_writer_cli_status" in template
    assert "market_intel.market_intel_schema_db_probe" in template
    assert "market_intel.market_intel_platform_seed_db_diff" in template
    assert "market_intel.market_intel_legacy_source_bridge" in template
    assert "market_intel.market_intel_mcp_readiness" in template
    assert "market_intel.market_intel_mcp_deploy_preflight" in template
    assert "market_intel.market_intel_mcp_activation_runbook" in template
    assert "market_intel.market_intel_mcp_fetch_gate" in template
    assert "market_intel.market_intel_manual_sample_plan" in template
    assert "market_intel.market_intel_manual_sample_acceptance" in template
    assert "market_intel.market_intel_manual_sample_review" in template
    assert "market_intel.market_intel_manual_sample_review_evaluate" in template
    assert "market_intel.market_intel_manual_sample_candidate_handoff" in template
    assert "market_intel.market_intel_manual_sample_candidate_queue_draft" in template
    assert "market_intel.market_intel_manual_sample_candidate_queue_approval" in template
    assert "market_intel.market_intel_manual_sample_candidate_queue_transaction" in template
    assert "market_intel.market_intel_manual_sample_candidate_queue_writer_status" in template
    assert "market_intel.market_intel_manual_sample_candidate_queue_writer_preflight" in template
    assert (
        "market_intel.market_intel_manual_sample_candidate_queue_writer_postwrite_smoke"
        in template
    )
    assert (
        "market_intel.market_intel_manual_sample_candidate_queue_writer_operator_drill"
        in template
    )
    assert (
        "market_intel.market_intel_manual_sample_candidate_queue_writer_run_package"
        in template
    )
    assert (
        "market_intel.market_intel_manual_sample_candidate_queue_writer_run_readiness"
        in template
    )
    assert (
        "market_intel.market_intel_manual_sample_candidate_queue_writer_run_receipt"
        in template
    )
    assert (
        "market_intel.market_intel_manual_sample_candidate_queue_writer_run_closeout"
        in template
    )
    assert (
        "market_intel.market_intel_manual_sample_candidate_queue_review_handoff"
        in template
    )
    assert (
        "market_intel_review.market_intel_manual_sample_candidate_queue_review_inventory"
        in template
    )
    assert (
        "market_intel_review.market_intel_manual_sample_candidate_queue_review_decision"
        in template
    )
    assert (
        "market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_approval"
        in template
    )
    assert (
        "market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_transaction"
        in template
    )
    assert (
        "data-market-intel-sample-candidate-queue-review-decision-transaction"
        in template
    )
    assert (
        "market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_status"
        in template
    )
    assert (
        "market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_preflight"
        in template
    )
    assert (
        "market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_postwrite_smoke"
        in template
    )
    assert (
        "market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_operator_drill"
        in template
    )
    assert (
        "market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_run_package"
        in template
    )
    assert (
        "market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_run_readiness"
        in template
    )
    assert (
        "market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_run_receipt"
        in template
    )
    assert (
        "market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_run_closeout"
        in template
    )
    assert (
        "market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_post_closeout_inventory"
        in template
    )
    assert (
        "market_intel_review.market_intel_manual_sample_candidate_queue_review_completion_archive"
        in template
    )
    assert (
        "market_intel_review.market_intel_manual_sample_candidate_queue_review_archive_summary"
        in template
    )
    assert (
        "market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_preflight"
        in template
    )
    assert (
        "market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_run_package"
        in template
    )
    assert (
        "data-market-intel-sample-candidate-queue-review-decision-writer"
        in template
    )
    assert (
        "data-market-intel-sample-candidate-queue-review-decision-preflight"
        in template
    )
    assert (
        "data-market-intel-sample-candidate-queue-review-decision-postwrite-smoke"
        in template
    )
    assert (
        "data-market-intel-sample-candidate-queue-review-decision-operator-drill"
        in template
    )
    assert (
        "data-market-intel-sample-candidate-queue-review-decision-run-package"
        in template
    )
    assert (
        "data-market-intel-sample-candidate-queue-review-decision-run-readiness"
        in template
    )
    assert (
        "data-market-intel-sample-candidate-queue-review-decision-run-receipt"
        in template
    )
    assert (
        "data-market-intel-sample-candidate-queue-review-decision-run-closeout"
        in template
    )
    assert (
        "data-market-intel-sample-candidate-queue-review-decision-post-closeout-inventory"
        in template
    )
    assert (
        "data-market-intel-sample-candidate-queue-review-completion-archive"
        in template
    )
    assert (
        "data-market-intel-sample-candidate-queue-review-archive-summary"
        in template
    )
    assert (
        "data-market-intel-sample-candidate-queue-review-ai-summary-preflight"
        in template
    )
    assert (
        "data-market-intel-sample-candidate-queue-review-ai-summary-run-package"
        in template
    )
    assert "X-CSRFToken" in template
    assert "market_intel.market_intel_scheduler_plan" in template
    assert "market_intel.market_intel_match_review_plan" in template
    assert "market_intel.market_intel_opportunity_plan" in template
    assert "market_intel.market_intel_opportunity_scoring_plan" in template
    assert "market_intel.market_intel_opportunity_evidence_plan" in template
    assert "market_intel.market_intel_opportunity_alert_plan" in template
    assert "market_intel.market_intel_migration_blueprint" in template
    assert "market_intel.market_intel_migration_apply_drill" in template
    assert "market_intel.market_intel_migration_catalog_review" in template
    assert "market_intel.market_intel_migration_live_smoke" in template
    assert "market_intel.market_intel_live_db_inventory" in template
    assert "market_intel.market_intel_write_approval_runbook" in template
    assert "market_intel.market_intel_deployment_readiness" in template
    assert "required_manual_steps" in template
    assert "fallback_plan" in template
    assert "approval_gates" in template
    assert "備援方案" in template
    assert "fetch=false" in template
    assert "fetch=true" not in template
    assert "execute=false" in template
    assert "execute=true" not in template
    assert "writes=executed" not in template
    assert "API 不執行推版" in template


def test_market_intel_schema_metadata_contains_all_market_tables():
    metadata_tables = set(Base.metadata.tables)

    assert set(MARKET_INTEL_TABLES) <= metadata_tables


def test_legacy_source_bridge_default_is_planned_only():
    bridge = MarketIntelService().build_legacy_source_bridge()

    assert bridge["mode"] == "legacy_source_bridge_planned"
    assert bridge["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert bridge["execute_requested"] is False
    assert bridge["read_only_query_executed"] is False
    assert bridge["database_connection_opened"] is False
    assert bridge["database_session_created"] is False
    assert bridge["database_write_executed"] is False
    assert bridge["database_commit_executed"] is False
    assert bridge["external_network_executed"] is False
    assert bridge["scheduler_attached"] is False
    assert bridge["writes_executed"] is False
    assert bridge["would_write_database"] is False
    assert bridge["source_count"] == 3
    assert bridge["existing_source_count"] == 0
    assert "execute_false_planned_only" in bridge["blocked_reasons"]
    assert {item["table"] for item in bridge["source_summaries"]} == {
        "promo_products",
        "competitor_prices",
        "competitor_price_history",
    }


def test_legacy_source_bridge_read_only_sqlite_counts_sources():
    engine = create_engine("sqlite:///:memory:")
    with engine.begin() as conn:
        conn.execute(
            text(
                """
                CREATE TABLE promo_products (
                    id INTEGER PRIMARY KEY,
                    batch_id TEXT,
                    crawled_at TEXT,
                    time_slot TEXT,
                    activity_time_text TEXT,
                    session_time_text TEXT,
                    i_code TEXT,
                    name TEXT,
                    price INTEGER,
                    discount_text TEXT,
                    url TEXT,
                    image_url TEXT,
                    previous_price INTEGER,
                    remain_qty INTEGER,
                    status_change TEXT,
                    page_type TEXT
                )
                """
            )
        )
        conn.execute(
            text(
                """
                CREATE TABLE competitor_prices (
                    id INTEGER PRIMARY KEY,
                    sku TEXT,
                    source TEXT,
                    price NUMERIC,
                    original_price NUMERIC,
                    discount_pct INTEGER,
                    competitor_product_id TEXT,
                    competitor_product_name TEXT,
                    match_score NUMERIC,
                    crawled_at TEXT
                )
                """
            )
        )
        conn.execute(
            text(
                """
                CREATE TABLE competitor_price_history (
                    id INTEGER PRIMARY KEY,
                    sku TEXT,
                    source TEXT,
                    momo_product_id INTEGER,
                    momo_price NUMERIC,
                    price NUMERIC,
                    original_price NUMERIC,
                    discount_pct INTEGER,
                    competitor_product_id TEXT,
                    competitor_product_name TEXT,
                    match_score NUMERIC,
                    crawled_at TEXT
                )
                """
            )
        )
        conn.execute(
            text(
                """
                INSERT INTO promo_products
                    (batch_id, crawled_at, time_slot, i_code, name, price, discount_text, url, page_type)
                VALUES
                    ('batch-1', '2026-05-18 10:00:00', '10:00', 'A001', 'MOMO 商品 A', 399, '8折', 'https://momo/A001', 'edm'),
                    ('batch-1', '2026-05-18 10:01:00', '10:00', 'A002', 'MOMO 商品 B', 499, '9折', 'https://momo/A002', 'edm')
                """
            )
        )
        conn.execute(
            text(
                """
                INSERT INTO competitor_prices
                    (sku, source, price, original_price, competitor_product_id, competitor_product_name, match_score, crawled_at)
                VALUES
                    ('A001', 'pchome', 379, 459, 'PC-A001', 'PChome 商品 A', 0.82, '2026-05-18 11:00:00')
                """
            )
        )
        conn.execute(
            text(
                """
                INSERT INTO competitor_price_history
                    (sku, source, momo_product_id, momo_price, price, original_price, competitor_product_id, competitor_product_name, match_score, crawled_at)
                VALUES
                    ('A001', 'pchome', 1, 399, 379, 459, 'PC-A001', 'PChome 商品 A', 0.82, '2026-05-18 11:00:00')
                """
            )
        )

    bridge = MarketIntelService().build_legacy_source_bridge(
        execute_requested=True,
        engine=engine,
        database_type="sqlite",
    )

    assert bridge["mode"] == "legacy_source_bridge_read_only"
    assert bridge["execute_requested"] is True
    assert bridge["read_only_query_executed"] is True
    assert bridge["database_connection_opened"] is True
    assert bridge["database_session_created"] is False
    assert bridge["database_write_executed"] is False
    assert bridge["database_commit_executed"] is False
    assert bridge["external_network_executed"] is False
    assert bridge["scheduler_attached"] is False
    assert bridge["writes_executed"] is False
    assert bridge["would_write_database"] is False
    assert bridge["source_tables_ready"] is True
    assert bridge["existing_source_count"] == 3
    assert bridge["total_existing_rows"] == 4
    assert [item["table"] for item in bridge["source_summaries"]] == [
        "promo_products",
        "competitor_prices",
        "competitor_price_history",
    ]
    assert bridge["source_summaries"][0]["row_count"] == 2
    assert bridge["source_summaries"][0]["distinct_entity_count"] == 2
    assert bridge["source_summaries"][1]["row_count"] == 1
    assert bridge["source_summaries"][2]["row_count"] == 1
    assert len(bridge["bridge_operations"]) == 4
    assert all(
        item["write_status"] != "executed"
        for item in bridge["bridge_operations"]
    )


def test_mcp_tool_contract_preview_is_read_only_and_whitelisted():
    contract = MarketIntelService().build_mcp_tool_contract()

    assert contract["mode"] == "mcp_tool_contract_preview"
    assert contract["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert contract["caller"] == "market_intel"
    assert contract["contract_ready"] is True
    assert contract["blocked_reasons"] == []
    assert contract["tool_count"] == 3
    assert contract["database_session_created"] is False
    assert contract["database_write_executed"] is False
    assert contract["database_commit_executed"] is False
    assert contract["external_network_executed"] is False
    assert contract["scheduler_attached"] is False
    assert contract["writes_executed"] is False
    assert contract["would_write_database"] is False
    assert contract["checks"]["market_intel_caller_registered"] is True
    assert contract["checks"]["all_router_tools_whitelisted"] is True
    assert contract["checks"]["all_tools_read_only"] is True
    assert contract["checks"]["no_database_write_allowed"] is True
    assert contract["checks"]["no_scheduler_attach_allowed"] is True
    assert {item["name"] for item in contract["tools"]} == {
        "market_campaign_search",
        "market_campaign_scrape",
        "market_product_match_lookup",
    }
    assert all(item["router_tools_whitelisted"] is True for item in contract["tools"])
    assert all(item["write_risk"] is False for item in contract["tools"])


def test_mcp_tool_contract_detects_missing_router_whitelist():
    contract = build_mcp_tool_contract_preview(tool_registry={})

    assert contract["contract_ready"] is False
    assert "market_intel_caller_registered" in contract["blocked_reasons"]
    assert "all_router_tools_whitelisted" in contract["blocked_reasons"]


def test_mcp_tool_contract_route_is_preview_only():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.get("/api/market_intel/mcp_tool_contract")
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "mcp_tool_contract_preview"
    assert data["contract_ready"] is True
    assert data["database_session_created"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["external_network_executed"] is False
    assert data["scheduler_attached"] is False


def test_mcp_activation_runbook_blocks_until_env_and_health_pass():
    preflight = build_mcp_deploy_preflight_plan(env={})
    runbook = build_mcp_activation_runbook_preview(preflight=preflight)

    assert runbook["mode"] == "mcp_activation_runbook_preview"
    assert runbook["ready_for_operator_activation"] is False
    assert "required_env_ready" in runbook["blocked_reasons"]
    assert "external_health_smoke_not_executed" in runbook["blocked_reasons"]
    assert runbook["deployment_actions_executed"] is False
    assert runbook["docker_command_executed"] is False
    assert runbook["ssh_command_executed"] is False
    assert runbook["database_session_created"] is False
    assert runbook["database_write_executed"] is False
    assert runbook["database_commit_executed"] is False
    assert runbook["external_network_executed"] is False
    assert runbook["scheduler_attached"] is False
    assert runbook["would_write_database"] is False
    assert runbook["safety_contract"]["does_not_execute_docker"] is True
    assert runbook["safety_contract"]["does_not_enable_router"] is True
    assert {item["key"] for item in runbook["stages"]} == {
        "configure_required_env",
        "create_mcp_readonly_role",
        "start_external_mcp_stack",
        "run_mcp_health_smoke",
        "enable_mcp_router_flag",
        "run_market_intel_mcp_smoke",
    }


def test_mcp_activation_runbook_can_be_ready_with_mocked_gates():
    preflight = build_mcp_deploy_preflight_plan(
        env={
            "MCP_POSTGRES_PASSWORD": "secret",
            "TAVILY_API_KEY": "tavily",
            "EXA_API_KEY": "exa",
            "MCP_ROUTER_ENABLED": "false",
        }
    )
    readiness = {
        "readiness_checks": {
            "external_server_health_checked": True,
            "external_servers_all_healthy": True,
            "market_intel_tool_contract_ready": True,
        }
    }

    runbook = build_mcp_activation_runbook_preview(
        preflight=preflight,
        readiness=readiness,
    )

    assert runbook["ready_for_operator_activation"] is True
    assert runbook["blocked_reasons"] == []
    assert runbook["checks"]["required_env_ready"] is True
    assert runbook["checks"]["all_health_passed"] is True
    assert {
        item["key"]: item["status"]
        for item in runbook["stages"]
    }["enable_mcp_router_flag"] == "ready"


def test_mcp_activation_runbook_route_is_preview_only():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.get("/api/market_intel/mcp_activation_runbook")
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "mcp_activation_runbook_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["deployment_actions_executed"] is False
    assert data["docker_command_executed"] is False
    assert data["ssh_command_executed"] is False
    assert data["database_write_executed"] is False
    assert data["external_network_executed"] is False
    assert data["scheduler_attached"] is False


def test_mcp_fetch_gate_default_blocks_external_fetch():
    gate = MarketIntelService().build_mcp_fetch_gate(fetch_requested=True)

    assert gate["mode"] == "mcp_fetch_gate_planned"
    assert gate["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert gate["fetch_requested"] is True
    assert gate["manual_fetch_gate_open"] is False
    assert gate["network_request_allowed"] is False
    assert gate["would_use_external_network"] is False
    assert gate["database_session_created"] is False
    assert gate["database_write_executed"] is False
    assert gate["database_commit_executed"] is False
    assert gate["external_network_executed"] is False
    assert gate["scheduler_attached"] is False
    assert gate["writes_executed"] is False
    assert gate["would_write_database"] is False
    assert "market_intel_enabled" in gate["blocked_reasons"]
    assert "market_intel_crawler_enabled" in gate["blocked_reasons"]
    assert "mcp_readiness_executed" in gate["blocked_reasons"]
    assert "mcp_router_enabled" in gate["blocked_reasons"]


def test_mcp_fetch_gate_can_open_with_mocked_ready_state():
    class RuntimeStatus:
        enabled = True
        crawler_enabled = True
        database_write_allowed = False
        scheduler_attached = False

    readiness = {
        "mode": "mcp_readiness_read_only",
        "execute_requested": True,
        "router_enabled": True,
        "external_mcp_complete": True,
        "internal_mcp_complete": True,
        "market_intel_mcp_integrated": True,
        "blocked_reasons": [],
        "readiness_checks": {
            "market_intel_tool_contract_ready": True,
            "external_servers_all_healthy": True,
        },
    }

    gate = build_mcp_fetch_gate_preview(
        RuntimeStatus(),
        fetch_requested=True,
        execute_readiness=True,
        readiness=readiness,
    )

    assert gate["mode"] == "mcp_fetch_gate_read_only"
    assert gate["manual_fetch_prerequisites_met"] is True
    assert gate["manual_fetch_gate_open"] is True
    assert gate["network_request_allowed"] is True
    assert gate["blocked_reasons"] == []
    assert gate["database_write_executed"] is False
    assert gate["scheduler_attached"] is False


def test_mcp_fetch_gate_route_is_preview_only():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.get("/api/market_intel/mcp_fetch_gate")
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "mcp_fetch_gate_planned"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["fetch_requested"] is False
    assert data["network_request_allowed"] is False
    assert data["external_network_executed"] is False
    assert data["database_write_executed"] is False
    assert data["scheduler_attached"] is False


def test_manual_sample_plan_preview_blocks_fetch_and_write():
    plan = MarketIntelService().build_manual_sample_plan()

    assert plan["mode"] == "manual_sample_fetch_plan_preview"
    assert plan["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert plan["ready_for_manual_sample_fetch"] is False
    assert plan["sample_fetch_executed"] is False
    assert plan["external_network_executed"] is False
    assert plan["database_session_created"] is False
    assert plan["database_write_executed"] is False
    assert plan["database_commit_executed"] is False
    assert plan["scheduler_attached"] is False
    assert plan["writes_executed"] is False
    assert plan["would_write_database"] is False
    assert plan["platform_count"] == 4
    assert plan["sample_source_total"] == 4
    assert plan["sample_policy"]["max_platforms_per_manual_batch"] == 1
    assert plan["sample_policy"]["first_batch_platform"] == "pchome"
    assert [item["platform_code"] for item in plan["sample_platforms"]] == [
        "pchome",
        "momo",
        "coupang",
        "shopee",
    ]
    assert all(
        item["sample_source_count"] == 1
        and item["network_status"] == "not_executed"
        and item["write_status"] == "blocked_preview_only"
        for item in plan["sample_platforms"]
    )
    assert "market_intel_enabled" in plan["blocked_reasons"]
    assert "mcp_fetch_gate_open" in plan["blocked_reasons"]
    assert "sample_fetch_not_executed_by_api" in plan["blocked_reasons"]
    assert "do_not_fetch_from_api_preview" in plan["safe_boundaries"]
    assert "do_not_bypass_anti_bot" in plan["safe_boundaries"]


def test_manual_sample_plan_route_is_preview_only():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.get("/api/market_intel/manual_sample_plan")
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "manual_sample_fetch_plan_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["sample_fetch_executed"] is False
    assert data["external_network_executed"] is False
    assert data["database_write_executed"] is False
    assert data["scheduler_attached"] is False


def test_manual_sample_acceptance_preview_blocks_candidate_import():
    acceptance = MarketIntelService().build_manual_sample_acceptance()

    assert acceptance["mode"] == "manual_sample_acceptance_preview"
    assert acceptance["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert acceptance["contract_ready"] is True
    assert acceptance["sample_result_loaded"] is False
    assert acceptance["sample_result_accepted"] is False
    assert acceptance["candidate_import_allowed"] is False
    assert acceptance["external_network_executed"] is False
    assert acceptance["database_connection_opened"] is False
    assert acceptance["database_session_created"] is False
    assert acceptance["database_write_executed"] is False
    assert acceptance["database_commit_executed"] is False
    assert acceptance["scheduler_attached"] is False
    assert acceptance["writes_executed"] is False
    assert acceptance["would_write_database"] is False
    assert "sample_result_not_loaded" in acceptance["blocked_reasons"]
    assert "manual_review_required_before_import" in acceptance["blocked_reasons"]
    assert "status_code" in acceptance["required_result_fields"]
    assert "campaign_link_candidates" in acceptance["required_diagnostic_fields"]
    assert acceptance["acceptance_thresholds"]["minimum_campaign_candidates"] == 1
    assert acceptance["acceptance_thresholds"]["accepted_candidate_bands"] == ["high", "medium"]
    assert {item["key"] for item in acceptance["reject_conditions"]} >= {
        "anti_bot_or_login_wall",
        "no_campaign_candidates",
    }
    assert "do_not_import_candidates_without_human_review" in acceptance["safe_boundaries"]
    assert "do_not_write_market_tables_from_acceptance_preview" in acceptance["safe_boundaries"]


def test_manual_sample_acceptance_route_is_preview_only():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.get("/api/market_intel/manual_sample_acceptance")
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "manual_sample_acceptance_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["sample_result_loaded"] is False
    assert data["candidate_import_allowed"] is False
    assert data["external_network_executed"] is False
    assert data["database_write_executed"] is False
    assert data["scheduler_attached"] is False


def test_manual_sample_review_preview_is_planned_until_result_loaded():
    review = MarketIntelService().build_manual_sample_review()

    assert review["mode"] == "manual_sample_review_preview"
    assert review["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert review["contract_ready"] is True
    assert review["sample_result_loaded"] is False
    assert review["sample_result_reviewed"] is False
    assert review["sample_result_accepted"] is False
    assert review["ready_for_candidate_preview"] is False
    assert review["candidate_import_allowed"] is False
    assert review["external_network_executed"] is False
    assert review["database_connection_opened"] is False
    assert review["database_session_created"] is False
    assert review["database_write_executed"] is False
    assert review["database_commit_executed"] is False
    assert review["scheduler_attached"] is False
    assert review["writes_executed"] is False
    assert review["would_write_database"] is False
    assert review["review_result"] == "planned_no_sample_result"
    assert "sample_result_not_loaded" in review["blocked_reasons"]
    assert "candidate_import_still_blocked_until_operator_approval" in review["blocked_reasons"]
    assert "do_not_fetch_external_pages_from_review_api" in review["safe_boundaries"]
    assert "do_not_write_market_tables_from_review_preview" in review["safe_boundaries"]


def test_manual_sample_review_evaluator_accepts_good_result_without_import():
    acceptance = MarketIntelService().build_manual_sample_acceptance()
    sample_result = {
        "batch_id": "sample-batch-1",
        "platform_code": "pchome",
        "source_key": "homepage",
        "source_url": "https://24h.pchome.com.tw/",
        "status": "fetched",
        "status_code": 200,
        "content_length": 1200,
        "page_hash": "a" * 64,
        "title": "PChome 活動",
        "diagnostics": {
            "link_count": 3,
            "same_host_link_count": 2,
            "campaign_link_candidates": [
                {
                    "confidence_band": "high",
                    "score": 82,
                    "url": "https://24h.pchome.com.tw/activity/sample",
                    "text": "品牌活動",
                },
            ],
        },
    }

    result = evaluate_manual_sample_result(sample_result, acceptance)

    assert result["sample_result_loaded"] is True
    assert result["sample_result_reviewed"] is True
    assert result["sample_result_accepted"] is True
    assert result["ready_for_candidate_preview"] is True
    assert result["candidate_import_allowed"] is False
    assert result["review_result"] == "accepted_for_candidate_preview"
    assert all(check["passed"] for check in result["review_checks"])
    assert result["review_findings"] == []
    assert result["candidate_summary"]["candidate_count"] == 1
    assert result["candidate_summary"]["accepted_candidate_count"] == 1


def test_manual_sample_review_evaluator_rejects_bad_result():
    acceptance = MarketIntelService().build_manual_sample_acceptance()
    sample_result = {
        "batch_id": "sample-batch-2",
        "platform_code": "shopee",
        "source_key": "mall",
        "source_url": "https://shopee.tw/mall",
        "status": "blocked",
        "status_code": 403,
        "content_length": 120,
        "page_hash": "short",
        "title": "",
        "diagnostics": {
            "link_count": 0,
            "same_host_link_count": 0,
            "campaign_link_candidates": [],
        },
    }

    result = evaluate_manual_sample_result(sample_result, acceptance)

    assert result["sample_result_loaded"] is True
    assert result["sample_result_reviewed"] is True
    assert result["sample_result_accepted"] is False
    assert result["ready_for_candidate_preview"] is False
    assert result["candidate_import_allowed"] is False
    assert result["review_result"] == "rejected_sample_result"
    assert {item["key"] for item in result["review_findings"]} >= {
        "http_status_ok",
        "content_has_body",
        "candidate_quality_reviewed",
    }


def test_manual_sample_review_route_is_preview_only():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.get("/api/market_intel/manual_sample_review")
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "manual_sample_review_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["sample_result_loaded"] is False
    assert data["sample_result_reviewed"] is False
    assert data["candidate_import_allowed"] is False
    assert data["external_network_executed"] is False
    assert data["database_write_executed"] is False
    assert data["scheduler_attached"] is False


def test_manual_sample_review_evaluation_preview_accepts_payload_without_persisting():
    sample_result = {
        "batch_id": "sample-batch-3",
        "platform_code": "momo",
        "source_key": "homepage",
        "source_url": "https://www.momoshop.com.tw/",
        "status": "fetched",
        "status_code": 200,
        "content_length": 1800,
        "page_hash": "b" * 64,
        "title": "MOMO 活動",
        "diagnostics": {
            "link_count": 4,
            "same_host_link_count": 4,
            "campaign_link_candidates": [
                {
                    "confidence_band": "medium",
                    "score": 74,
                    "url": "https://www.momoshop.com.tw/activity/sample",
                    "text": "活動頁",
                },
            ],
        },
    }

    review = MarketIntelService().build_manual_sample_review_evaluation(
        sample_result=sample_result
    )

    assert review["mode"] == "manual_sample_review_evaluation_preview"
    assert review["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert review["review_request_type"] == "operator_posted_json"
    assert review["payload_received"] is True
    assert review["payload_valid_json_object"] is True
    assert review["payload_persisted"] is False
    assert review["sample_result_persisted"] is False
    assert review["sample_result_loaded"] is True
    assert review["sample_result_reviewed"] is True
    assert review["sample_result_accepted"] is True
    assert review["ready_for_candidate_preview"] is True
    assert review["candidate_preview_payload_created"] is True
    assert review["candidate_preview_persisted"] is False
    assert review["candidate_import_allowed"] is False
    assert review["external_network_executed"] is False
    assert review["database_write_executed"] is False
    assert review["database_commit_executed"] is False
    assert review["scheduler_attached"] is False
    assert "do_not_persist_posted_review_payload" in review["safe_boundaries"]


def test_manual_sample_review_evaluate_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.post(
        "/api/market_intel/manual_sample_review/evaluate",
        json={
            "sample_result": {
                "batch_id": "sample-batch-4",
                "platform_code": "pchome",
                "source_key": "homepage",
                "source_url": "https://24h.pchome.com.tw/",
                "status": "fetched",
                "status_code": 200,
                "content_length": 1400,
                "page_hash": "c" * 64,
                "title": "PChome 活動",
                "diagnostics": {
                    "link_count": 2,
                    "same_host_link_count": 2,
                    "campaign_link_candidates": [
                        {
                            "confidence_band": "high",
                            "score": 88,
                            "url": "https://24h.pchome.com.tw/activity/sample",
                            "text": "品牌活動",
                        },
                    ],
                },
            }
        },
    )
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "manual_sample_review_evaluation_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["payload_received"] is True
    assert data["payload_valid_json_object"] is True
    assert data["payload_persisted"] is False
    assert data["sample_result_persisted"] is False
    assert data["sample_result_accepted"] is True
    assert data["ready_for_candidate_preview"] is True
    assert data["candidate_import_allowed"] is False
    assert data["external_network_executed"] is False
    assert data["database_write_executed"] is False
    assert data["scheduler_attached"] is False


def test_manual_sample_review_evaluate_rejects_invalid_json_without_write():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.post(
        "/api/market_intel/manual_sample_review/evaluate",
        data="not-json",
        content_type="text/plain",
    )
    data = response.get_json()

    assert response.status_code == 400
    assert data["mode"] == "manual_sample_review_evaluation_preview"
    assert data["payload_received"] is False
    assert data["payload_valid_json_object"] is False
    assert data["payload_error"] == "invalid_json_object"
    assert data["payload_persisted"] is False
    assert data["sample_result_persisted"] is False
    assert data["candidate_import_allowed"] is False
    assert data["external_network_executed"] is False
    assert data["database_write_executed"] is False
    assert data["scheduler_attached"] is False
    assert "sample_result_payload_invalid" in data["blocked_reasons"]


def test_manual_sample_candidate_handoff_preview_creates_candidates_without_persisting():
    sample_result = {
        "batch_id": "sample-batch-5",
        "platform_code": "pchome",
        "source_key": "homepage",
        "source_url": "https://24h.pchome.com.tw/",
        "status": "fetched",
        "status_code": 200,
        "content_length": 1500,
        "page_hash": "e" * 64,
        "title": "PChome 活動",
        "diagnostics": {
            "link_count": 3,
            "same_host_link_count": 2,
            "campaign_link_candidates": [
                {
                    "confidence_band": "high",
                    "score": 91,
                    "url": "https://24h.pchome.com.tw/activity/sample",
                    "text": "品牌活動",
                },
                {
                    "confidence_band": "low",
                    "score": 22,
                    "url": "https://24h.pchome.com.tw/search/noise",
                    "text": "低信心連結",
                },
            ],
        },
    }

    handoff = MarketIntelService().build_manual_sample_candidate_handoff(
        sample_result=sample_result
    )

    assert handoff["mode"] == "manual_sample_candidate_handoff_preview"
    assert handoff["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert handoff["payload_received"] is True
    assert handoff["payload_valid_json_object"] is True
    assert handoff["payload_persisted"] is False
    assert handoff["sample_result_persisted"] is False
    assert handoff["handoff_ready"] is True
    assert handoff["candidate_handoff_created"] is True
    assert handoff["candidate_handoff_persisted"] is False
    assert handoff["candidate_import_allowed"] is False
    assert handoff["external_network_executed"] is False
    assert handoff["database_connection_opened"] is False
    assert handoff["database_session_created"] is False
    assert handoff["database_write_executed"] is False
    assert handoff["database_commit_executed"] is False
    assert handoff["scheduler_attached"] is False
    assert handoff["handoff_summary"]["candidate_count"] == 1
    assert handoff["candidates"][0]["review_status"] == "needs_operator_review"
    assert handoff["candidates"][0]["write_status"] == "blocked_preview_only"
    assert handoff["candidates"][0]["import_allowed"] is False
    assert "do_not_persist_candidate_handoff_payload" in handoff["safe_boundaries"]


def test_manual_sample_candidate_handoff_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.post(
        "/api/market_intel/manual_sample_review/candidate_handoff",
        json={
            "sample_result": {
                "batch_id": "sample-batch-6",
                "platform_code": "momo",
                "source_key": "homepage",
                "source_url": "https://www.momoshop.com.tw/",
                "status": "fetched",
                "status_code": 200,
                "content_length": 1600,
                "page_hash": "f" * 64,
                "title": "MOMO 活動",
                "diagnostics": {
                    "link_count": 2,
                    "same_host_link_count": 2,
                    "campaign_link_candidates": [
                        {
                            "confidence_band": "medium",
                            "score": 76,
                            "url": "https://www.momoshop.com.tw/activity/sample",
                            "text": "活動頁",
                        },
                    ],
                },
            }
        },
    )
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "manual_sample_candidate_handoff_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["payload_received"] is True
    assert data["handoff_ready"] is True
    assert data["candidate_handoff_created"] is True
    assert data["candidate_handoff_persisted"] is False
    assert data["candidate_import_allowed"] is False
    assert data["external_network_executed"] is False
    assert data["database_write_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["handoff_summary"]["candidate_count"] == 1


def test_manual_sample_candidate_handoff_blocks_invalid_payload():
    handoff = MarketIntelService().build_manual_sample_candidate_handoff(
        sample_result=None,
        payload_error="invalid_json_object",
    )

    assert handoff["mode"] == "manual_sample_candidate_handoff_preview"
    assert handoff["payload_received"] is False
    assert handoff["payload_valid_json_object"] is False
    assert handoff["handoff_ready"] is False
    assert handoff["candidate_handoff_created"] is False
    assert handoff["candidate_handoff_persisted"] is False
    assert handoff["candidate_import_allowed"] is False
    assert handoff["database_write_executed"] is False
    assert "candidate_handoff_not_ready" in handoff["blocked_reasons"]


def test_manual_sample_candidate_queue_draft_preview_builds_review_items_without_persisting():
    sample_result = {
        "batch_id": "sample-batch-7",
        "platform_code": "coupang",
        "source_key": "homepage",
        "source_url": "https://www.tw.coupang.com/",
        "status": "fetched",
        "status_code": 200,
        "content_length": 1800,
        "page_hash": "a" * 64,
        "title": "酷澎活動",
        "diagnostics": {
            "link_count": 3,
            "same_host_link_count": 2,
            "campaign_link_candidates": [
                {
                    "confidence_band": "high",
                    "score": 95,
                    "url": "https://www.tw.coupang.com/promotion/sample",
                    "text": "限時活動",
                }
            ],
        },
    }

    queue_draft = MarketIntelService().build_manual_sample_candidate_queue_draft(
        sample_result=sample_result
    )

    assert queue_draft["mode"] == "manual_sample_candidate_queue_draft_preview"
    assert queue_draft["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert queue_draft["payload_received"] is True
    assert queue_draft["payload_valid_json_object"] is True
    assert queue_draft["payload_persisted"] is False
    assert queue_draft["sample_result_persisted"] is False
    assert queue_draft["handoff_ready"] is True
    assert queue_draft["queue_draft_ready"] is True
    assert queue_draft["review_queue_draft_created"] is True
    assert queue_draft["review_queue_created"] is False
    assert queue_draft["review_queue_persisted"] is False
    assert queue_draft["candidate_import_allowed"] is False
    assert queue_draft["external_network_executed"] is False
    assert queue_draft["database_connection_opened"] is False
    assert queue_draft["database_session_created"] is False
    assert queue_draft["database_write_executed"] is False
    assert queue_draft["database_commit_executed"] is False
    assert queue_draft["scheduler_attached"] is False
    assert queue_draft["queue_summary"]["queue_item_count"] == 1
    assert queue_draft["queue_contract"]["table_name"] == "market_alert_review_queue"
    assert queue_draft["queue_items"][0]["review_state"] == "needs_review"
    assert queue_draft["queue_items"][0]["priority_lane"] == "urgent"
    assert queue_draft["queue_items"][0]["threshold_level"] == "high"
    assert queue_draft["queue_items"][0]["source_batch_id"] == "sample-batch-7"
    assert queue_draft["queue_items"][0]["review_priority"] == 80
    assert queue_draft["queue_items"][0]["write_status"] == "blocked_preview_only"
    assert queue_draft["queue_items"][0]["approval_required"] is True
    assert (
        "do_not_persist_candidate_review_queue_draft"
        in queue_draft["safe_boundaries"]
    )


def test_manual_sample_candidate_queue_draft_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.post(
        "/api/market_intel/manual_sample_review/candidate_queue_draft",
        json={
            "sample_result": {
                "batch_id": "sample-batch-8",
                "platform_code": "shopee",
                "source_key": "homepage",
                "source_url": "https://shopee.tw/",
                "status": "fetched",
                "status_code": 200,
                "content_length": 1900,
                "page_hash": "b" * 64,
                "title": "蝦皮活動",
                "diagnostics": {
                    "link_count": 2,
                    "same_host_link_count": 2,
                    "campaign_link_candidates": [
                        {
                            "confidence_band": "medium",
                            "score": 72,
                            "url": "https://shopee.tw/m/sample-campaign",
                            "text": "商城活動",
                        },
                    ],
                },
            }
        },
    )
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "manual_sample_candidate_queue_draft_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["payload_received"] is True
    assert data["handoff_ready"] is True
    assert data["queue_draft_ready"] is True
    assert data["review_queue_draft_created"] is True
    assert data["review_queue_created"] is False
    assert data["review_queue_persisted"] is False
    assert data["candidate_import_allowed"] is False
    assert data["external_network_executed"] is False
    assert data["database_write_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["queue_summary"]["queue_item_count"] == 1


def test_manual_sample_candidate_queue_draft_blocks_invalid_payload():
    queue_draft = MarketIntelService().build_manual_sample_candidate_queue_draft(
        sample_result=None,
        payload_error="invalid_json_object",
    )

    assert queue_draft["mode"] == "manual_sample_candidate_queue_draft_preview"
    assert queue_draft["payload_received"] is False
    assert queue_draft["payload_valid_json_object"] is False
    assert queue_draft["handoff_ready"] is False
    assert queue_draft["queue_draft_ready"] is False
    assert queue_draft["review_queue_draft_created"] is False
    assert queue_draft["review_queue_created"] is False
    assert queue_draft["review_queue_persisted"] is False
    assert queue_draft["candidate_import_allowed"] is False
    assert queue_draft["database_write_executed"] is False
    assert "review_queue_draft_not_ready" in queue_draft["blocked_reasons"]


def test_manual_sample_candidate_queue_approval_preview_blocks_write_and_maps_rows():
    sample_result = {
        "batch_id": "sample-batch-9",
        "platform_code": "momo",
        "source_key": "homepage",
        "source_url": "https://www.momoshop.com.tw/",
        "status": "fetched",
        "status_code": 200,
        "content_length": 1700,
        "page_hash": "c" * 64,
        "title": "MOMO 活動",
        "diagnostics": {
            "link_count": 2,
            "same_host_link_count": 2,
            "campaign_link_candidates": [
                {
                    "confidence_band": "high",
                    "score": 92,
                    "url": "https://www.momoshop.com.tw/activity/sample",
                    "text": "品牌活動",
                },
            ],
        },
    }

    approval = MarketIntelService().build_manual_sample_candidate_queue_approval(
        sample_result=sample_result
    )

    assert approval["mode"] == "manual_sample_candidate_queue_approval_preview"
    assert approval["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert approval["payload_received"] is True
    assert approval["payload_valid_json_object"] is True
    assert approval["payload_persisted"] is False
    assert approval["approval_preview_created"] is True
    assert approval["approval_request_created"] is False
    assert approval["approval_record_written"] is False
    assert approval["review_queue_write_allowed"] is False
    assert approval["review_queue_created"] is False
    assert approval["review_queue_persisted"] is False
    assert approval["candidate_import_allowed"] is False
    assert approval["external_network_executed"] is False
    assert approval["database_connection_opened"] is False
    assert approval["database_session_created"] is False
    assert approval["database_write_executed"] is False
    assert approval["database_commit_executed"] is False
    assert approval["scheduler_attached"] is False
    assert approval["approval_summary"]["target_table"] == "market_alert_review_queue"
    assert approval["approval_summary"]["row_preview_count"] == 1
    assert approval["approval_summary"]["gates_passed"] == 3
    assert approval["approval_summary"]["manual_approval_required"] is True
    row = approval["queue_write_preview"]["rows"][0]
    assert row["review_state"] == "needs_review"
    assert row["priority_lane"] == "urgent"
    assert row["threshold_level"] == "high"
    assert row["source_batch_id"] == "sample-batch-9"
    assert row["write_status"] == "blocked_approval_preview_only"
    assert "runtime_write_flags_enabled" in approval["blocked_reasons"]
    assert "manual_operator_approval" in approval["blocked_reasons"]
    assert "review_queue_write_still_blocked" in approval["blocked_reasons"]
    assert (
        "do_not_insert_market_alert_review_queue_from_preview"
        in approval["safe_boundaries"]
    )


def test_manual_sample_candidate_queue_approval_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.post(
        "/api/market_intel/manual_sample_review/candidate_queue_approval",
        json={
            "sample_result": {
                "batch_id": "sample-batch-10",
                "platform_code": "pchome",
                "source_key": "homepage",
                "source_url": "https://24h.pchome.com.tw/",
                "status": "fetched",
                "status_code": 200,
                "content_length": 1800,
                "page_hash": "d" * 64,
                "title": "PChome 活動",
                "diagnostics": {
                    "link_count": 2,
                    "same_host_link_count": 2,
                    "campaign_link_candidates": [
                        {
                            "confidence_band": "medium",
                            "score": 73,
                            "url": "https://24h.pchome.com.tw/activity/sample",
                            "text": "活動頁",
                        },
                    ],
                },
            }
        },
    )
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "manual_sample_candidate_queue_approval_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["payload_received"] is True
    assert data["approval_preview_created"] is True
    assert data["approval_request_created"] is False
    assert data["approval_record_written"] is False
    assert data["review_queue_write_allowed"] is False
    assert data["review_queue_created"] is False
    assert data["review_queue_persisted"] is False
    assert data["database_write_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["queue_write_preview"]["target_table"] == "market_alert_review_queue"
    assert data["queue_write_preview"]["row_count"] == 1


def test_manual_sample_candidate_queue_approval_blocks_invalid_payload():
    approval = MarketIntelService().build_manual_sample_candidate_queue_approval(
        sample_result=None,
        payload_error="invalid_json_object",
    )

    assert approval["mode"] == "manual_sample_candidate_queue_approval_preview"
    assert approval["payload_received"] is False
    assert approval["payload_valid_json_object"] is False
    assert approval["approval_preview_created"] is False
    assert approval["approval_request_created"] is False
    assert approval["approval_record_written"] is False
    assert approval["review_queue_write_allowed"] is False
    assert approval["review_queue_created"] is False
    assert approval["review_queue_persisted"] is False
    assert approval["database_write_executed"] is False
    assert "review_queue_draft_not_ready" in approval["blocked_reasons"]


def test_manual_sample_candidate_queue_transaction_preview_blocks_execution():
    sample_result = {
        "batch_id": "sample-batch-11",
        "platform_code": "momo",
        "source_key": "homepage",
        "source_url": "https://www.momoshop.com.tw/",
        "status": "fetched",
        "status_code": 200,
        "content_length": 1700,
        "page_hash": "e" * 64,
        "title": "MOMO 活動",
        "diagnostics": {
            "link_count": 2,
            "same_host_link_count": 2,
            "campaign_link_candidates": [
                {
                    "confidence_band": "high",
                    "score": 94,
                    "url": "https://www.momoshop.com.tw/activity/sample",
                    "text": "品牌活動",
                },
            ],
        },
    }

    transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
        sample_result=sample_result
    )

    assert transaction["mode"] == "manual_sample_candidate_queue_transaction_preview"
    assert transaction["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert transaction["payload_received"] is True
    assert transaction["payload_valid_json_object"] is True
    assert transaction["payload_persisted"] is False
    assert transaction["transaction_preview_created"] is True
    assert transaction["transaction_ready"] is False
    assert transaction["transaction_opened"] is False
    assert transaction["transaction_committed"] is False
    assert transaction["approval_request_created"] is False
    assert transaction["approval_record_written"] is False
    assert transaction["review_queue_write_allowed"] is False
    assert transaction["review_queue_created"] is False
    assert transaction["review_queue_persisted"] is False
    assert transaction["candidate_import_allowed"] is False
    assert transaction["external_network_executed"] is False
    assert transaction["database_connection_opened"] is False
    assert transaction["database_session_created"] is False
    assert transaction["database_write_executed"] is False
    assert transaction["database_commit_executed"] is False
    assert transaction["scheduler_attached"] is False
    assert transaction["transaction_summary"]["target_table"] == "market_alert_review_queue"
    assert transaction["transaction_summary"]["statement_count"] == 1
    assert transaction["transaction_summary"]["conflict_policy"] == "dedupe_key_do_nothing"
    statement = transaction["statements"][0]
    assert statement["operation"] == "insert"
    assert statement["table"] == "market_alert_review_queue"
    assert statement["write_status"] == "blocked_transaction_preview_only"
    assert statement["idempotency_key"].startswith("market_alert_review_queue:")
    assert statement["parameter_preview"]["dedupe_key"].startswith("sample-candidate:")
    assert statement["parameter_preview"]["metadata_json_preview"]["platform_code"] == "momo"
    assert "queue_approval_gates_not_all_passed" in transaction["blocked_reasons"]
    assert "queue_transaction_execution_still_blocked" in transaction["blocked_reasons"]
    assert (
        "do_not_execute_queue_transaction_from_preview"
        in transaction["safe_boundaries"]
    )


def test_manual_sample_candidate_queue_transaction_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.post(
        "/api/market_intel/manual_sample_review/candidate_queue_transaction",
        json={
            "sample_result": {
                "batch_id": "sample-batch-12",
                "platform_code": "pchome",
                "source_key": "homepage",
                "source_url": "https://24h.pchome.com.tw/",
                "status": "fetched",
                "status_code": 200,
                "content_length": 1800,
                "page_hash": "f" * 64,
                "title": "PChome 活動",
                "diagnostics": {
                    "link_count": 2,
                    "same_host_link_count": 2,
                    "campaign_link_candidates": [
                        {
                            "confidence_band": "medium",
                            "score": 74,
                            "url": "https://24h.pchome.com.tw/activity/sample",
                            "text": "活動頁",
                        },
                    ],
                },
            }
        },
    )
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "manual_sample_candidate_queue_transaction_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["payload_received"] is True
    assert data["transaction_preview_created"] is True
    assert data["transaction_ready"] is False
    assert data["transaction_opened"] is False
    assert data["transaction_committed"] is False
    assert data["approval_record_written"] is False
    assert data["review_queue_created"] is False
    assert data["review_queue_persisted"] is False
    assert data["database_write_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["transaction_summary"]["statement_count"] == 1


def test_manual_sample_candidate_queue_transaction_blocks_invalid_payload():
    transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
        sample_result=None,
        payload_error="invalid_json_object",
    )

    assert transaction["mode"] == "manual_sample_candidate_queue_transaction_preview"
    assert transaction["payload_received"] is False
    assert transaction["payload_valid_json_object"] is False
    assert transaction["transaction_preview_created"] is False
    assert transaction["transaction_ready"] is False
    assert transaction["transaction_opened"] is False
    assert transaction["transaction_committed"] is False
    assert transaction["approval_record_written"] is False
    assert transaction["review_queue_created"] is False
    assert transaction["database_write_executed"] is False
    assert "queue_transaction_preview_not_ready" in transaction["blocked_reasons"]


def test_candidate_queue_writer_cli_gate_blocks_until_preflight_backup_and_smoke_pass():
    from services.market_intel.candidate_queue_writer_cli import (
        build_candidate_queue_writer_cli_plan,
    )

    sample_result = {
        "batch_id": "sample-batch-13",
        "platform_code": "momo",
        "source_key": "homepage",
        "source_url": "https://www.momoshop.com.tw/",
        "status": "fetched",
        "status_code": 200,
        "content_length": 1700,
        "page_hash": "a" * 64,
        "title": "MOMO 活動",
        "diagnostics": {
            "link_count": 1,
            "same_host_link_count": 1,
            "campaign_link_candidates": [
                {
                    "confidence_band": "high",
                    "score": 94,
                    "url": "https://www.momoshop.com.tw/activity/sample",
                    "text": "品牌活動",
                },
            ],
        },
    }
    transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
        sample_result=sample_result
    )
    status = build_candidate_queue_writer_cli_plan(
        transaction_preview=transaction,
        execute_requested=True,
        apply_real_write=True,
        approval_token=TEST_APPROVAL_TOKEN,
        approval_token_secret=TEST_APPROVAL_TOKEN,
    )

    assert status["mode"] == "candidate_queue_writer_cli_blocked"
    assert status["execute_requested"] is True
    assert status["apply_real_write_requested"] is True
    assert status["approval_token_present"] is True
    assert status["approval_token_valid"] is True
    assert status["queue_writer_implementation_enabled"] is True
    assert status["ready_for_real_write"] is False
    assert status["writes_executed"] is False
    assert status["would_write_database"] is False
    assert status["database_connection_opened"] is False
    assert status["database_session_created"] is False
    assert status["explicit_transaction_opened"] is False
    assert status["database_write_executed"] is False
    assert status["database_commit_executed"] is False
    assert status["scheduler_attached"] is False
    assert status["exit_code"] == 2
    assert status["transaction_preview_summary"]["statement_count"] == 1
    assert "approval_token_valid" not in status["blocked_reasons"]
    assert "queue_writer_preflight_ready" in status["blocked_reasons"]
    assert "backup_verified" in status["blocked_reasons"]
    assert "migration_live_smoke_passed" in status["blocked_reasons"]
    assert "queue_writer_implementation_enabled" not in status["blocked_reasons"]
    assert status["safety_contract"]["refuses_api_execution"] is True
    assert (
        "do_not_execute_candidate_queue_writer_from_api"
        in status["safe_boundaries"]
    )


def test_candidate_queue_writer_preflight_planned_maps_payload_without_db():
    from services.market_intel.candidate_queue_writer_preflight import (
        build_candidate_queue_writer_preflight,
    )

    sample_result = {
        "batch_id": "sample-batch-16",
        "platform_code": "momo",
        "source_key": "homepage",
        "source_url": "https://www.momoshop.com.tw/",
        "status": "fetched",
        "status_code": 200,
        "content_length": 1700,
        "page_hash": "d" * 64,
        "title": "MOMO 活動",
        "diagnostics": {
            "link_count": 1,
            "same_host_link_count": 1,
            "campaign_link_candidates": [
                {
                    "confidence_band": "high",
                    "score": 94,
                    "url": "https://www.momoshop.com.tw/activity/sample",
                    "text": "品牌活動",
                },
            ],
        },
    }
    transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
        sample_result=sample_result
    )
    preflight = build_candidate_queue_writer_preflight(
        transaction_preview=transaction,
        execute_requested=False,
    )

    assert preflight["mode"] == "candidate_queue_writer_preflight_planned"
    assert preflight["execute_requested"] is False
    assert preflight["read_only_query_executed"] is False
    assert preflight["database_connection_opened"] is False
    assert preflight["database_write_executed"] is False
    assert preflight["database_commit_executed"] is False
    assert preflight["scheduler_attached"] is False
    assert preflight["ready_for_writer_review"] is False
    assert preflight["ready_for_real_write"] is False
    assert preflight["statement_count"] == 1
    assert preflight["payload_column_map"]["metadata_json_preview"] == "metadata_json"
    assert preflight["unmapped_payload_keys"] == []
    assert "metadata_json" in preflight["mapped_insert_columns"]
    assert "queue_writer_preflight_not_loaded" in preflight["blocked_reasons"]


def test_candidate_queue_writer_preflight_sqlite_read_only_validates_columns():
    from services.market_intel.candidate_queue_writer_preflight import (
        build_candidate_queue_writer_preflight,
    )

    sample_result = {
        "batch_id": "sample-batch-17",
        "platform_code": "pchome",
        "source_key": "homepage",
        "source_url": "https://24h.pchome.com.tw/",
        "status": "fetched",
        "status_code": 200,
        "content_length": 1800,
        "page_hash": "e" * 64,
        "title": "PChome 活動",
        "diagnostics": {
            "link_count": 1,
            "same_host_link_count": 1,
            "campaign_link_candidates": [
                {
                    "confidence_band": "medium",
                    "score": 74,
                    "url": "https://24h.pchome.com.tw/activity/sample",
                    "text": "活動頁",
                },
            ],
        },
    }
    transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
        sample_result=sample_result
    )
    engine = create_engine("sqlite:///:memory:")
    with engine.begin() as conn:
        conn.execute(
            text(
                """
                CREATE TABLE market_alert_review_queue (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    alert_candidate_id TEXT NOT NULL UNIQUE,
                    review_state TEXT NOT NULL DEFAULT 'draft',
                    priority_lane TEXT NOT NULL DEFAULT 'watch',
                    threshold_level TEXT NOT NULL,
                    total_score FLOAT NOT NULL DEFAULT 0,
                    evidence_bundle_id TEXT NOT NULL,
                    dedupe_key TEXT NOT NULL,
                    source_batch_id TEXT NOT NULL,
                    metadata_json TEXT,
                    created_at TEXT,
                    updated_at TEXT
                )
                """
            )
        )
        conn.execute(
            text(
                "CREATE UNIQUE INDEX ux_market_alert_review_queue_dedupe "
                "ON market_alert_review_queue (dedupe_key)"
            )
        )

    preflight = build_candidate_queue_writer_preflight(
        transaction_preview=transaction,
        execute_requested=True,
        engine=engine,
        database_type="sqlite",
    )

    assert preflight["mode"] == "candidate_queue_writer_preflight_read_only"
    assert preflight["execute_requested"] is True
    assert preflight["read_only_query_executed"] is True
    assert preflight["database_connection_opened"] is True
    assert preflight["database_session_created"] is False
    assert preflight["explicit_transaction_opened"] is False
    assert preflight["database_write_executed"] is False
    assert preflight["database_commit_executed"] is False
    assert preflight["scheduler_attached"] is False
    assert preflight["table_exists"] is True
    assert preflight["schema_ready"] is True
    assert preflight["ready_for_writer_review"] is True
    assert preflight["ready_for_real_write"] is False
    assert preflight["missing_insert_columns"] == []
    assert preflight["dedupe_unique_index_present"] is True
    assert preflight["unmapped_payload_keys"] == []
    assert preflight["blocked_reasons"] == []


def test_candidate_queue_writer_cli_sqlite_transaction_is_idempotent():
    from services.market_intel.candidate_queue_writer_cli import (
        build_candidate_queue_writer_cli_plan,
    )
    from services.market_intel.candidate_queue_writer_preflight import (
        build_candidate_queue_writer_preflight,
    )

    sample_result = {
        "batch_id": "sample-batch-19",
        "platform_code": "momo",
        "source_key": "homepage",
        "source_url": "https://www.momoshop.com.tw/",
        "status": "fetched",
        "status_code": 200,
        "content_length": 1700,
        "page_hash": "1" * 64,
        "title": "MOMO 活動",
        "diagnostics": {
            "link_count": 1,
            "same_host_link_count": 1,
            "campaign_link_candidates": [
                {
                    "confidence_band": "high",
                    "score": 94,
                    "url": "https://www.momoshop.com.tw/activity/sample",
                    "text": "品牌活動",
                },
            ],
        },
    }
    transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
        sample_result=sample_result
    )
    engine = create_engine("sqlite:///:memory:")
    with engine.begin() as conn:
        conn.execute(
            text(
                """
                CREATE TABLE market_alert_review_queue (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    alert_candidate_id TEXT NOT NULL UNIQUE,
                    review_state TEXT NOT NULL DEFAULT 'draft',
                    priority_lane TEXT NOT NULL DEFAULT 'watch',
                    threshold_level TEXT NOT NULL,
                    total_score FLOAT NOT NULL DEFAULT 0,
                    evidence_bundle_id TEXT NOT NULL,
                    dedupe_key TEXT NOT NULL,
                    source_batch_id TEXT NOT NULL,
                    metadata_json TEXT,
                    created_at TEXT DEFAULT CURRENT_TIMESTAMP,
                    updated_at TEXT DEFAULT CURRENT_TIMESTAMP
                )
                """
            )
        )
        conn.execute(
            text(
                "CREATE UNIQUE INDEX ux_market_alert_review_queue_dedupe "
                "ON market_alert_review_queue (dedupe_key)"
            )
        )

    preflight = build_candidate_queue_writer_preflight(
        transaction_preview=transaction,
        execute_requested=True,
        engine=engine,
        database_type="sqlite",
    )
    first_run = build_candidate_queue_writer_cli_plan(
        transaction_preview=transaction,
        writer_preflight=preflight,
        execute_requested=True,
        apply_real_write=True,
        approval_token=TEST_APPROVAL_TOKEN,
        approval_token_secret=TEST_APPROVAL_TOKEN,
        backup_verified=True,
        migration_live_smoke_passed=True,
        engine=engine,
        database_type="sqlite",
    )
    second_run = build_candidate_queue_writer_cli_plan(
        transaction_preview=transaction,
        writer_preflight=preflight,
        execute_requested=True,
        apply_real_write=True,
        approval_token=TEST_APPROVAL_TOKEN,
        approval_token_secret=TEST_APPROVAL_TOKEN,
        backup_verified=True,
        migration_live_smoke_passed=True,
        engine=engine,
        database_type="sqlite",
    )
    with engine.connect() as conn:
        rows = conn.execute(
            text(
                """
                SELECT alert_candidate_id, review_state, dedupe_key, metadata_json
                FROM market_alert_review_queue
                """
            )
        ).fetchall()

    assert first_run["mode"] == "candidate_queue_writer_cli_executed"
    assert first_run["ready_for_real_write"] is True
    assert first_run["writes_executed"] is True
    assert first_run["would_write_database"] is True
    assert first_run["database_connection_opened"] is True
    assert first_run["database_session_created"] is False
    assert first_run["explicit_transaction_opened"] is True
    assert first_run["database_write_executed"] is True
    assert first_run["database_commit_executed"] is True
    assert first_run["database_rollback_executed"] is False
    assert first_run["scheduler_attached"] is False
    assert first_run["inserted_count"] == 1
    assert first_run["skipped_count"] == 0
    assert first_run["blocked_reasons"] == []
    assert first_run["exit_code"] == 0
    assert len(rows) == 1
    assert rows[0]._mapping["review_state"] == "needs_review"
    assert "platform_code" in rows[0]._mapping["metadata_json"]

    assert second_run["mode"] == "candidate_queue_writer_cli_executed"
    assert second_run["inserted_count"] == 0
    assert second_run["skipped_count"] == 1
    assert second_run["database_commit_executed"] is True


def test_candidate_queue_writer_postwrite_smoke_planned_without_db():
    from services.market_intel.candidate_queue_writer_postwrite_smoke import (
        build_candidate_queue_writer_postwrite_smoke,
    )

    sample_result = {
        "batch_id": "sample-batch-20",
        "platform_code": "momo",
        "source_key": "homepage",
        "source_url": "https://www.momoshop.com.tw/",
        "status": "fetched",
        "status_code": 200,
        "content_length": 1700,
        "page_hash": "2" * 64,
        "title": "MOMO 活動",
        "diagnostics": {
            "link_count": 1,
            "same_host_link_count": 1,
            "campaign_link_candidates": [
                {
                    "confidence_band": "high",
                    "score": 94,
                    "url": "https://www.momoshop.com.tw/activity/sample",
                    "text": "品牌活動",
                },
            ],
        },
    }
    transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
        sample_result=sample_result
    )
    smoke = build_candidate_queue_writer_postwrite_smoke(
        transaction_preview=transaction,
        execute_requested=False,
    )

    assert smoke["mode"] == "candidate_queue_writer_postwrite_smoke_planned"
    assert smoke["execute_requested"] is False
    assert smoke["read_only_query_executed"] is False
    assert smoke["database_connection_opened"] is False
    assert smoke["database_session_created"] is False
    assert smoke["explicit_transaction_opened"] is False
    assert smoke["database_write_executed"] is False
    assert smoke["database_commit_executed"] is False
    assert smoke["scheduler_attached"] is False
    assert smoke["expected_dedupe_key_count"] == 1
    assert smoke["found_count"] == 0
    assert smoke["missing_count"] == 1
    assert smoke["postwrite_smoke_passed"] is False
    assert "candidate_queue_writer_postwrite_smoke_not_loaded" in smoke["blocked_reasons"]


def test_candidate_queue_writer_postwrite_smoke_sqlite_read_only_finds_rows():
    from services.market_intel.candidate_queue_writer_cli import (
        build_candidate_queue_writer_cli_plan,
    )
    from services.market_intel.candidate_queue_writer_postwrite_smoke import (
        build_candidate_queue_writer_postwrite_smoke,
    )
    from services.market_intel.candidate_queue_writer_preflight import (
        build_candidate_queue_writer_preflight,
    )

    sample_result = {
        "batch_id": "sample-batch-21",
        "platform_code": "pchome",
        "source_key": "homepage",
        "source_url": "https://24h.pchome.com.tw/",
        "status": "fetched",
        "status_code": 200,
        "content_length": 1800,
        "page_hash": "3" * 64,
        "title": "PChome 活動",
        "diagnostics": {
            "link_count": 1,
            "same_host_link_count": 1,
            "campaign_link_candidates": [
                {
                    "confidence_band": "medium",
                    "score": 74,
                    "url": "https://24h.pchome.com.tw/activity/sample",
                    "text": "活動頁",
                },
            ],
        },
    }
    transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
        sample_result=sample_result
    )
    engine = create_engine("sqlite:///:memory:")
    with engine.begin() as conn:
        conn.execute(
            text(
                """
                CREATE TABLE market_alert_review_queue (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    alert_candidate_id TEXT NOT NULL UNIQUE,
                    review_state TEXT NOT NULL DEFAULT 'draft',
                    priority_lane TEXT NOT NULL DEFAULT 'watch',
                    threshold_level TEXT NOT NULL,
                    total_score FLOAT NOT NULL DEFAULT 0,
                    evidence_bundle_id TEXT NOT NULL,
                    dedupe_key TEXT NOT NULL,
                    source_batch_id TEXT NOT NULL,
                    metadata_json TEXT,
                    created_at TEXT DEFAULT CURRENT_TIMESTAMP,
                    updated_at TEXT DEFAULT CURRENT_TIMESTAMP
                )
                """
            )
        )
        conn.execute(
            text(
                "CREATE UNIQUE INDEX ux_market_alert_review_queue_dedupe "
                "ON market_alert_review_queue (dedupe_key)"
            )
        )
    preflight = build_candidate_queue_writer_preflight(
        transaction_preview=transaction,
        execute_requested=True,
        engine=engine,
        database_type="sqlite",
    )
    writer = build_candidate_queue_writer_cli_plan(
        transaction_preview=transaction,
        writer_preflight=preflight,
        execute_requested=True,
        apply_real_write=True,
        approval_token=TEST_APPROVAL_TOKEN,
        approval_token_secret=TEST_APPROVAL_TOKEN,
        backup_verified=True,
        migration_live_smoke_passed=True,
        engine=engine,
        database_type="sqlite",
    )
    smoke = build_candidate_queue_writer_postwrite_smoke(
        transaction_preview=transaction,
        execute_requested=True,
        engine=engine,
        database_type="sqlite",
    )

    assert writer["inserted_count"] == 1
    assert smoke["mode"] == "candidate_queue_writer_postwrite_smoke_read_only"
    assert smoke["execute_requested"] is True
    assert smoke["read_only_query_executed"] is True
    assert smoke["database_connection_opened"] is True
    assert smoke["database_session_created"] is False
    assert smoke["explicit_transaction_opened"] is False
    assert smoke["database_write_executed"] is False
    assert smoke["database_commit_executed"] is False
    assert smoke["scheduler_attached"] is False
    assert smoke["expected_dedupe_key_count"] == 1
    assert smoke["found_count"] == 1
    assert smoke["missing_count"] == 0
    assert smoke["missing_dedupe_keys"] == []
    assert smoke["postwrite_smoke_passed"] is True
    assert smoke["ready_for_operator_review"] is True
    assert smoke["blocked_reasons"] == []
    assert smoke["row_summaries"][0]["review_state"] == "needs_review"


def test_candidate_queue_writer_operator_drill_preview_is_safe():
    from services.market_intel.candidate_queue_writer_cli import (
        build_candidate_queue_writer_cli_plan,
    )
    from services.market_intel.candidate_queue_writer_operator_drill import (
        build_candidate_queue_writer_operator_drill,
    )
    from services.market_intel.candidate_queue_writer_postwrite_smoke import (
        build_candidate_queue_writer_postwrite_smoke,
    )
    from services.market_intel.candidate_queue_writer_preflight import (
        build_candidate_queue_writer_preflight,
    )

    sample_result = {
        "batch_id": "sample-batch-23",
        "platform_code": "momo",
        "source_key": "homepage",
        "source_url": "https://www.momoshop.com.tw/",
        "status": "fetched",
        "status_code": 200,
        "content_length": 1700,
        "page_hash": "5" * 64,
        "title": "MOMO 活動",
        "diagnostics": {
            "link_count": 1,
            "same_host_link_count": 1,
            "campaign_link_candidates": [
                {
                    "confidence_band": "high",
                    "score": 94,
                    "url": "https://www.momoshop.com.tw/activity/sample",
                    "text": "品牌活動",
                },
            ],
        },
    }
    transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
        sample_result=sample_result
    )
    preflight = build_candidate_queue_writer_preflight(
        transaction_preview=transaction,
        execute_requested=False,
    )
    writer_status = build_candidate_queue_writer_cli_plan(
        transaction_preview=transaction,
        writer_preflight=preflight,
    )
    postwrite_smoke = build_candidate_queue_writer_postwrite_smoke(
        transaction_preview=transaction,
        execute_requested=False,
    )
    drill = build_candidate_queue_writer_operator_drill(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=postwrite_smoke,
    )

    assert drill["mode"] == "candidate_queue_writer_operator_drill_preview"
    assert drill["operator_drill_ready"] is True
    assert drill["api_executes_cli"] is False
    assert drill["api_reads_approval_token"] is False
    assert drill["api_writes_database"] is False
    assert drill["database_connection_opened"] is False
    assert drill["database_session_created"] is False
    assert drill["explicit_transaction_opened"] is False
    assert drill["database_write_executed"] is False
    assert drill["database_commit_executed"] is False
    assert drill["scheduler_attached"] is False
    assert drill["writes_executed"] is False
    assert drill["statement_summary"]["statement_count"] == 1
    assert len(drill["command_sequence"]) == 5
    assert any(item["executes_database"] for item in drill["command_sequence"])
    assert "backup_verified_by_operator" in drill["blocked_reasons"]
    assert "one_time_token_supplied_in_shell_only" in drill["blocked_reasons"]
    assert "do_not_execute_cli_from_api" in drill["safe_boundaries"]


def test_candidate_queue_writer_run_package_preview_is_safe():
    from services.market_intel.candidate_queue_writer_cli import (
        build_candidate_queue_writer_cli_plan,
    )
    from services.market_intel.candidate_queue_writer_operator_drill import (
        build_candidate_queue_writer_operator_drill,
    )
    from services.market_intel.candidate_queue_writer_postwrite_smoke import (
        build_candidate_queue_writer_postwrite_smoke,
    )
    from services.market_intel.candidate_queue_writer_preflight import (
        build_candidate_queue_writer_preflight,
    )
    from services.market_intel.candidate_queue_writer_run_package import (
        build_candidate_queue_writer_run_package,
    )

    sample_result = {
        "batch_id": "sample-batch-25",
        "platform_code": "momo",
        "source_key": "homepage",
        "source_url": "https://www.momoshop.com.tw/",
        "status": "fetched",
        "status_code": 200,
        "content_length": 1700,
        "page_hash": "7" * 64,
        "title": "MOMO 活動",
        "diagnostics": {
            "link_count": 1,
            "same_host_link_count": 1,
            "campaign_link_candidates": [
                {
                    "confidence_band": "high",
                    "score": 94,
                    "url": "https://www.momoshop.com.tw/activity/sample",
                    "text": "品牌活動",
                },
            ],
        },
    }
    transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
        sample_result=sample_result
    )
    preflight = build_candidate_queue_writer_preflight(
        transaction_preview=transaction,
        execute_requested=False,
    )
    writer_status = build_candidate_queue_writer_cli_plan(
        transaction_preview=transaction,
        writer_preflight=preflight,
    )
    postwrite_smoke = build_candidate_queue_writer_postwrite_smoke(
        transaction_preview=transaction,
        execute_requested=False,
    )
    operator_drill = build_candidate_queue_writer_operator_drill(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=postwrite_smoke,
    )
    run_package = build_candidate_queue_writer_run_package(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=postwrite_smoke,
        operator_drill=operator_drill,
    )

    assert run_package["mode"] == "candidate_queue_writer_run_package_preview"
    assert run_package["package_ready"] is True
    assert run_package["package_artifact_created"] is False
    assert run_package["api_writes_file"] is False
    assert run_package["api_executes_cli"] is False
    assert run_package["api_reads_approval_token"] is False
    assert run_package["api_writes_database"] is False
    assert run_package["database_connection_opened"] is False
    assert run_package["database_session_created"] is False
    assert run_package["explicit_transaction_opened"] is False
    assert run_package["database_write_executed"] is False
    assert run_package["database_commit_executed"] is False
    assert run_package["scheduler_attached"] is False
    assert run_package["writes_executed"] is False
    assert run_package["would_write_database"] is False
    assert run_package["payload_manifest"]["payload_count"] == 1
    assert len(run_package["payload_manifest"]["manifest_hash"]) == 64
    assert len(run_package["required_artifacts"]) == 5
    assert all(
        item["created_by_api"] is False
        for item in run_package["required_artifacts"]
    )
    assert len(run_package["command_bundle"]) == 5
    assert any(item["executes_database"] for item in run_package["command_bundle"])
    assert "real_sample_payload_saved_by_operator" in run_package["blocked_reasons"]
    assert "one_time_token_supplied_in_shell_only" in run_package["blocked_reasons"]
    assert "do_not_create_run_artifacts_from_api" in run_package["safe_boundaries"]


def test_candidate_queue_writer_run_readiness_preview_checks_operator_evidence():
    from services.market_intel.candidate_queue_writer_cli import (
        build_candidate_queue_writer_cli_plan,
    )
    from services.market_intel.candidate_queue_writer_operator_drill import (
        build_candidate_queue_writer_operator_drill,
    )
    from services.market_intel.candidate_queue_writer_postwrite_smoke import (
        build_candidate_queue_writer_postwrite_smoke,
    )
    from services.market_intel.candidate_queue_writer_preflight import (
        build_candidate_queue_writer_preflight,
    )
    from services.market_intel.candidate_queue_writer_run_package import (
        build_candidate_queue_writer_run_package,
    )
    from services.market_intel.candidate_queue_writer_run_readiness import (
        build_candidate_queue_writer_run_readiness,
    )

    sample_result = {
        "batch_id": "sample-batch-27",
        "platform_code": "momo",
        "source_key": "homepage",
        "source_url": "https://www.momoshop.com.tw/",
        "status": "fetched",
        "status_code": 200,
        "content_length": 1700,
        "page_hash": "9" * 64,
        "title": "MOMO 活動",
        "diagnostics": {
            "link_count": 1,
            "same_host_link_count": 1,
            "campaign_link_candidates": [
                {
                    "confidence_band": "high",
                    "score": 94,
                    "url": "https://www.momoshop.com.tw/activity/sample",
                    "text": "品牌活動",
                },
            ],
        },
    }
    transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
        sample_result=sample_result
    )
    preflight = build_candidate_queue_writer_preflight(
        transaction_preview=transaction,
        execute_requested=False,
    )
    writer_status = build_candidate_queue_writer_cli_plan(
        transaction_preview=transaction,
        writer_preflight=preflight,
    )
    postwrite_smoke = build_candidate_queue_writer_postwrite_smoke(
        transaction_preview=transaction,
        execute_requested=False,
    )
    operator_drill = build_candidate_queue_writer_operator_drill(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=postwrite_smoke,
    )
    run_package = build_candidate_queue_writer_run_package(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=postwrite_smoke,
        operator_drill=operator_drill,
    )

    missing = build_candidate_queue_writer_run_readiness(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=postwrite_smoke,
        operator_drill=operator_drill,
        run_package=run_package,
    )
    ready = build_candidate_queue_writer_run_readiness(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=postwrite_smoke,
        operator_drill=operator_drill,
        run_package=run_package,
        operator_evidence={
            "reviewed_sample_json_path": "artifacts/market_intel/reviewed.json",
            "backup_artifact_path": "scripts/tools/backups/backup.zip",
            "preflight_artifact_path": "artifacts/market_intel/preflight.json",
            "migration_live_smoke_passed": True,
            "operator_acknowledged_shell_only_token": True,
        },
    )
    token_leak = build_candidate_queue_writer_run_readiness(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=postwrite_smoke,
        operator_drill=operator_drill,
        run_package=run_package,
        operator_evidence={
            "reviewed_sample_json_path": "artifacts/market_intel/reviewed.json",
            "backup_artifact_path": "scripts/tools/backups/backup.zip",
            "preflight_artifact_path": "artifacts/market_intel/preflight.json",
            "migration_live_smoke_passed": True,
            "operator_acknowledged_shell_only_token": True,
            "approval_token": TEST_APPROVAL_TOKEN,
        },
    )

    assert missing["mode"] == "candidate_queue_writer_run_readiness_preview"
    assert missing["ready_for_cli_operator_run"] is False
    assert missing["ready_for_api_database_write"] is False
    assert missing["api_executes_cli"] is False
    assert missing["api_reads_approval_token"] is False
    assert missing["api_writes_file"] is False
    assert missing["database_connection_opened"] is False
    assert missing["database_write_executed"] is False
    assert missing["database_commit_executed"] is False
    assert missing["scheduler_attached"] is False
    assert "reviewed_sample_json_path_recorded" in missing["blocked_reasons"]
    assert "backup_artifact_path_recorded" in missing["blocked_reasons"]
    assert "operator_acknowledged_shell_only_token" in missing["blocked_reasons"]
    assert ready["ready_for_cli_operator_run"] is True
    assert ready["ready_for_api_database_write"] is False
    assert ready["database_write_executed"] is False
    assert ready["operator_evidence_summary"]["artifact_path_count"] == 3
    assert token_leak["ready_for_cli_operator_run"] is False
    assert token_leak["operator_evidence_summary"]["approval_token_submitted_to_api"] is True
    assert "approval_token_not_submitted_to_api" in token_leak["blocked_reasons"]
    assert TEST_APPROVAL_TOKEN not in json.dumps(
        token_leak,
        ensure_ascii=False,
        sort_keys=True,
    )
    assert "do_not_read_approval_token_from_api" in ready["safe_boundaries"]


def test_candidate_queue_writer_run_receipt_preview_checks_writer_and_smoke_artifacts():
    from services.market_intel.candidate_queue_writer_run_receipt import (
        build_candidate_queue_writer_run_receipt,
    )

    fixture = _build_candidate_queue_writer_receipt_fixture()
    receipt = build_candidate_queue_writer_run_receipt(
        transaction_preview=fixture["transaction"],
        run_readiness=fixture["run_readiness"],
        writer_output=fixture["writer_output"],
        postwrite_smoke_result=fixture["postwrite_smoke_result"],
        operator_evidence=fixture["operator_evidence"],
    )
    token_leak = build_candidate_queue_writer_run_receipt(
        transaction_preview=fixture["transaction"],
        run_readiness=fixture["run_readiness"],
        writer_output={
            **fixture["writer_output"],
            "approval_token": TEST_APPROVAL_TOKEN,
        },
        postwrite_smoke_result=fixture["postwrite_smoke_result"],
        operator_evidence={
            **fixture["operator_evidence"],
            "market_intel_queue_write_approval": TEST_APPROVAL_TOKEN,
        },
    )
    malformed_receipt = build_candidate_queue_writer_run_receipt(
        transaction_preview=fixture["transaction"],
        run_readiness=fixture["run_readiness"],
        writer_output={
            "inserted_count": "not-a-number",
            "affected_dedupe_keys": fixture["expected_keys"][0],
        },
        postwrite_smoke_result={
            "found_count": "not-a-number",
            "found_dedupe_keys": fixture["expected_keys"][0],
        },
        operator_evidence=fixture["operator_evidence"],
    )

    assert receipt["mode"] == "candidate_queue_writer_run_receipt_preview"
    assert receipt["receipt_passed"] is True
    assert receipt["ready_for_next_manual_review"] is True
    assert receipt["ready_for_api_database_write"] is False
    assert receipt["ready_for_scheduler_attach"] is False
    assert receipt["api_executes_cli"] is False
    assert receipt["api_reads_approval_token"] is False
    assert receipt["api_writes_file"] is False
    assert receipt["api_writes_database"] is False
    assert receipt["database_connection_opened"] is False
    assert receipt["database_write_executed"] is False
    assert receipt["database_commit_executed"] is False
    assert receipt["scheduler_attached"] is False
    assert receipt["expected_dedupe_keys"] == fixture["expected_keys"]
    assert receipt["writer_output_summary"]["database_commit_executed"] is True
    assert receipt["writer_output_summary"]["dedupe_keys_match_expected"] is True
    assert receipt["postwrite_smoke_summary"]["read_only_query_executed"] is True
    assert receipt["postwrite_smoke_summary"]["dedupe_keys_match_expected"] is True
    assert receipt["operator_evidence_summary"][
        "writer_output_json_path_recorded"
    ] is True
    assert receipt["operator_evidence_summary"][
        "postwrite_smoke_json_path_recorded"
    ] is True
    assert receipt["operator_evidence_summary"][
        "operator_confirmed_no_token_in_artifacts"
    ] is True
    assert receipt["blocked_reasons"] == []
    assert "do_not_execute_cli_from_receipt_preview" in receipt["safe_boundaries"]
    assert "do_not_read_approval_token_from_api" in receipt["safe_boundaries"]
    assert token_leak["receipt_passed"] is False
    assert token_leak["writer_output_summary"]["approval_token_key_detected"] is True
    assert token_leak["operator_evidence_summary"][
        "approval_token_submitted_to_api"
    ] is True
    assert "writer_output_no_approval_token_key" in token_leak["blocked_reasons"]
    assert "operator_confirmed_no_token_in_artifacts" in token_leak["blocked_reasons"]
    assert TEST_APPROVAL_TOKEN not in json.dumps(
        token_leak,
        ensure_ascii=False,
        sort_keys=True,
    )
    assert malformed_receipt["receipt_passed"] is False
    assert malformed_receipt["writer_output_summary"]["inserted_count"] == 0
    assert malformed_receipt["postwrite_smoke_summary"]["found_count"] == 0
    assert "writer_output_executed_and_committed" in malformed_receipt[
        "blocked_reasons"
    ]


def test_candidate_queue_writer_run_closeout_preview_promotes_only_manual_phase():
    from services.market_intel.candidate_queue_writer_run_closeout import (
        build_candidate_queue_writer_run_closeout,
    )
    from services.market_intel.candidate_queue_writer_run_receipt import (
        build_candidate_queue_writer_run_receipt,
    )

    fixture = _build_candidate_queue_writer_receipt_fixture()
    closeout_evidence = {
        **fixture["operator_evidence"],
        "closeout_artifact_path": "artifacts/market_intel/closeout.json",
        "operator_confirmed_queue_review_next": True,
        "operator_confirmed_no_scheduler_attach": True,
        "operator_confirmed_no_api_db_write": True,
        "closeout_notes": "ready for read-only inventory",
    }
    receipt = build_candidate_queue_writer_run_receipt(
        transaction_preview=fixture["transaction"],
        run_readiness=fixture["run_readiness"],
        writer_output=fixture["writer_output"],
        postwrite_smoke_result=fixture["postwrite_smoke_result"],
        operator_evidence=fixture["operator_evidence"],
    )
    closeout = build_candidate_queue_writer_run_closeout(
        transaction_preview=fixture["transaction"],
        run_receipt=receipt,
        operator_evidence=closeout_evidence,
    )
    missing = build_candidate_queue_writer_run_closeout(
        transaction_preview=fixture["transaction"],
        run_receipt=receipt,
        operator_evidence=fixture["operator_evidence"],
    )
    token_leak = build_candidate_queue_writer_run_closeout(
        transaction_preview=fixture["transaction"],
        run_receipt=receipt,
        operator_evidence={
            **closeout_evidence,
            "approval_token": TEST_APPROVAL_TOKEN,
        },
    )

    assert closeout["mode"] == "candidate_queue_writer_run_closeout_preview"
    assert closeout["closeout_passed"] is True
    assert closeout["ready_for_next_manual_phase"] is True
    assert closeout["ready_for_api_database_write"] is False
    assert closeout["ready_for_scheduler_attach"] is False
    assert closeout["api_executes_cli"] is False
    assert closeout["api_reads_approval_token"] is False
    assert closeout["api_writes_file"] is False
    assert closeout["api_writes_database"] is False
    assert closeout["database_connection_opened"] is False
    assert closeout["database_write_executed"] is False
    assert closeout["database_commit_executed"] is False
    assert closeout["scheduler_attached"] is False
    assert closeout["receipt_summary"]["receipt_passed"] is True
    assert closeout["receipt_summary"]["safe_boundaries_complete"] is True
    assert closeout["operator_closeout_summary"][
        "closeout_artifact_path_recorded"
    ] is True
    assert closeout["promotion_gate"]["allowed"] is True
    assert closeout["promotion_gate"]["requires_real_db_write"] is False
    assert closeout["blocked_reasons"] == []
    assert "do_not_write_queue_from_closeout_preview" in closeout["safe_boundaries"]
    assert missing["closeout_passed"] is False
    assert "closeout_artifact_path_recorded" in missing["blocked_reasons"]
    assert "operator_confirmed_queue_review_next" in missing["blocked_reasons"]
    assert token_leak["closeout_passed"] is False
    assert token_leak["operator_closeout_summary"][
        "approval_token_submitted_to_api"
    ] is True
    assert "closeout_no_approval_token_submitted_to_api" in token_leak[
        "blocked_reasons"
    ]
    assert TEST_APPROVAL_TOKEN not in json.dumps(
        token_leak,
        ensure_ascii=False,
        sort_keys=True,
    )


def test_candidate_queue_review_handoff_preview_is_manual_only():
    from services.market_intel.candidate_queue_review_handoff import (
        build_candidate_queue_review_handoff,
    )
    from services.market_intel.candidate_queue_writer_run_closeout import (
        build_candidate_queue_writer_run_closeout,
    )
    from services.market_intel.candidate_queue_writer_run_receipt import (
        build_candidate_queue_writer_run_receipt,
    )

    fixture = _build_candidate_queue_writer_receipt_fixture()
    operator_evidence = {
        **fixture["operator_evidence"],
        "closeout_artifact_path": "artifacts/market_intel/closeout.json",
        "operator_confirmed_queue_review_next": True,
        "operator_confirmed_no_scheduler_attach": True,
        "operator_confirmed_no_api_db_write": True,
    }
    receipt = build_candidate_queue_writer_run_receipt(
        transaction_preview=fixture["transaction"],
        run_readiness=fixture["run_readiness"],
        writer_output=fixture["writer_output"],
        postwrite_smoke_result=fixture["postwrite_smoke_result"],
        operator_evidence=fixture["operator_evidence"],
    )
    closeout = build_candidate_queue_writer_run_closeout(
        transaction_preview=fixture["transaction"],
        run_receipt=receipt,
        operator_evidence=operator_evidence,
    )
    handoff = build_candidate_queue_review_handoff(
        transaction_preview=fixture["transaction"],
        run_closeout=closeout,
        operator_evidence=operator_evidence,
    )
    token_leak = build_candidate_queue_review_handoff(
        transaction_preview=fixture["transaction"],
        run_closeout=closeout,
        operator_evidence={**operator_evidence, "approval_token": TEST_APPROVAL_TOKEN},
    )

    assert handoff["mode"] == "candidate_queue_review_handoff_preview"
    assert handoff["handoff_ready"] is True
    assert handoff["ready_for_manual_queue_review"] is True
    assert handoff["ready_for_live_inventory_read_only"] is True
    assert handoff["ready_for_api_database_write"] is False
    assert handoff["ready_for_scheduler_attach"] is False
    assert handoff["api_executes_cli"] is False
    assert handoff["api_reads_approval_token"] is False
    assert handoff["api_writes_database"] is False
    assert handoff["api_updates_review_state"] is False
    assert handoff["read_only_query_executed"] is False
    assert handoff["database_connection_opened"] is False
    assert handoff["database_write_executed"] is False
    assert handoff["database_commit_executed"] is False
    assert handoff["scheduler_attached"] is False
    assert handoff["expected_dedupe_keys"] == fixture["expected_keys"]
    assert handoff["review_contract"]["expected_review_state"] == "needs_review"
    assert "update_review_state" in handoff["review_contract"]["forbidden_api_actions"]
    assert "do_not_update_review_state_from_api" in handoff["safe_boundaries"]
    assert handoff["blocked_reasons"] == []
    assert token_leak["handoff_ready"] is False
    assert token_leak["operator_handoff_summary"][
        "approval_token_submitted_to_api"
    ] is True
    assert "handoff_no_approval_token_submitted_to_api" in token_leak[
        "blocked_reasons"
    ]
    assert TEST_APPROVAL_TOKEN not in json.dumps(
        token_leak,
        ensure_ascii=False,
        sort_keys=True,
    )


def test_candidate_queue_review_inventory_preview_is_read_only():
    from services.market_intel.candidate_queue_review_handoff import (
        build_candidate_queue_review_handoff,
    )
    from services.market_intel.candidate_queue_review_inventory import (
        build_candidate_queue_review_inventory,
    )
    from services.market_intel.candidate_queue_writer_run_closeout import (
        build_candidate_queue_writer_run_closeout,
    )
    from services.market_intel.candidate_queue_writer_run_receipt import (
        build_candidate_queue_writer_run_receipt,
    )

    fixture = _build_candidate_queue_writer_receipt_fixture()
    operator_evidence = {
        **fixture["operator_evidence"],
        "closeout_artifact_path": "artifacts/market_intel/closeout.json",
        "operator_confirmed_queue_review_next": True,
        "operator_confirmed_no_scheduler_attach": True,
        "operator_confirmed_no_api_db_write": True,
        "operator_confirmed_inventory_read_only": True,
    }
    receipt = build_candidate_queue_writer_run_receipt(
        transaction_preview=fixture["transaction"],
        run_readiness=fixture["run_readiness"],
        writer_output=fixture["writer_output"],
        postwrite_smoke_result=fixture["postwrite_smoke_result"],
        operator_evidence=fixture["operator_evidence"],
    )
    closeout = build_candidate_queue_writer_run_closeout(
        transaction_preview=fixture["transaction"],
        run_receipt=receipt,
        operator_evidence=operator_evidence,
    )
    handoff = build_candidate_queue_review_handoff(
        transaction_preview=fixture["transaction"],
        run_closeout=closeout,
        operator_evidence=operator_evidence,
    )
    postwrite_smoke = {
        **fixture["postwrite_smoke_result"],
        "database_commit_executed": False,
        "row_summaries": [
            {
                "dedupe_key": fixture["expected_keys"][0],
                "review_state": "needs_review",
                "priority_lane": "review",
                "total_score": 94,
                "source_batch_id": fixture["sample_result"]["batch_id"],
            }
        ],
    }
    live_db_inventory = {
        "mode": "live_db_inventory_read_only",
        "summary_ready": True,
        "read_only_query_executed": True,
        "database_connection_opened": True,
        "database_write_executed": False,
        "database_commit_executed": False,
        "migration_executed": False,
        "external_network_executed": False,
        "scheduler_attached": False,
        "table_statuses": [
            {
                "table": "market_alert_review_queue",
                "exists": True,
                "row_count": 1,
                "status": "loaded",
            }
        ],
        "total_rows": 1,
        "alert_review_state_breakdown": [
            {
                "review_state": "needs_review",
                "priority_lane": "review",
                "alert_count": 1,
            }
        ],
    }
    inventory = build_candidate_queue_review_inventory(
        review_handoff=handoff,
        postwrite_smoke=postwrite_smoke,
        live_db_inventory=live_db_inventory,
        operator_evidence=operator_evidence,
        execute_requested=True,
    )
    token_leak = build_candidate_queue_review_inventory(
        review_handoff=handoff,
        postwrite_smoke=postwrite_smoke,
        live_db_inventory=live_db_inventory,
        operator_evidence={**operator_evidence, "approval_token": TEST_APPROVAL_TOKEN},
        execute_requested=True,
    )

    assert inventory["mode"] == "candidate_queue_review_inventory_preview"
    assert inventory["review_inventory_ready"] is True
    assert inventory["ready_for_human_decision_review"] is True
    assert inventory["ready_for_api_review_state_update"] is False
    assert inventory["ready_for_api_database_write"] is False
    assert inventory["ready_for_scheduler_attach"] is False
    assert inventory["api_executes_cli"] is False
    assert inventory["api_reads_approval_token"] is False
    assert inventory["api_writes_database"] is False
    assert inventory["api_updates_review_state"] is False
    assert inventory["read_only_query_executed"] is True
    assert inventory["database_connection_opened"] is True
    assert inventory["database_write_executed"] is False
    assert inventory["database_commit_executed"] is False
    assert inventory["scheduler_attached"] is False
    assert inventory["expected_dedupe_keys"] == fixture["expected_keys"]
    assert inventory["found_dedupe_keys"] == fixture["expected_keys"]
    assert inventory["missing_dedupe_keys"] == []
    assert inventory["row_summaries"][0]["review_state"] == "needs_review"
    assert inventory["alert_review_queue_table"]["exists"] is True
    assert inventory["blocked_reasons"] == []
    assert "do_not_update_review_state_from_api" in inventory["safe_boundaries"]
    assert token_leak["review_inventory_ready"] is False
    assert token_leak["operator_inventory_summary"][
        "approval_token_submitted_to_api"
    ] is True
    assert "review_inventory_no_approval_token_submitted_to_api" in token_leak[
        "blocked_reasons"
    ]
    assert TEST_APPROVAL_TOKEN not in json.dumps(
        token_leak,
        ensure_ascii=False,
        sort_keys=True,
    )


def test_candidate_queue_review_inventory_preview_is_read_only_manual_gate():
    from services.market_intel.candidate_queue_review_handoff import (
        build_candidate_queue_review_handoff,
    )
    from services.market_intel.candidate_queue_review_inventory import (
        build_candidate_queue_review_inventory,
    )
    from services.market_intel.candidate_queue_writer_run_closeout import (
        build_candidate_queue_writer_run_closeout,
    )
    from services.market_intel.candidate_queue_writer_run_receipt import (
        build_candidate_queue_writer_run_receipt,
    )

    fixture = _build_candidate_queue_writer_receipt_fixture(
        "sample-batch-review-inventory"
    )
    operator_evidence = {
        **fixture["operator_evidence"],
        "closeout_artifact_path": "artifacts/market_intel/closeout.json",
        "operator_confirmed_queue_review_next": True,
        "operator_confirmed_no_scheduler_attach": True,
        "operator_confirmed_no_api_db_write": True,
        "operator_confirmed_inventory_read_only": True,
    }
    receipt = build_candidate_queue_writer_run_receipt(
        transaction_preview=fixture["transaction"],
        run_readiness=fixture["run_readiness"],
        writer_output=fixture["writer_output"],
        postwrite_smoke_result=fixture["postwrite_smoke_result"],
        operator_evidence=fixture["operator_evidence"],
    )
    closeout = build_candidate_queue_writer_run_closeout(
        transaction_preview=fixture["transaction"],
        run_receipt=receipt,
        operator_evidence=operator_evidence,
    )
    handoff = build_candidate_queue_review_handoff(
        transaction_preview=fixture["transaction"],
        run_closeout=closeout,
        operator_evidence=operator_evidence,
    )
    live_inventory = {
        "mode": "live_db_inventory_read_only",
        "summary_ready": True,
        "read_only_query_executed": True,
        "database_connection_opened": True,
        "database_write_executed": False,
        "database_commit_executed": False,
        "migration_executed": False,
        "external_network_executed": False,
        "scheduler_attached": False,
        "total_rows": len(fixture["expected_keys"]),
        "table_statuses": [
            {
                "table": "market_alert_review_queue",
                "exists": True,
                "row_count": len(fixture["expected_keys"]),
                "status": "loaded",
            }
        ],
        "alert_review_state_breakdown": [
            {
                "review_state": "needs_review",
                "priority_lane": "watch",
                "alert_count": len(fixture["expected_keys"]),
            }
        ],
    }

    inventory = build_candidate_queue_review_inventory(
        review_handoff=handoff,
        postwrite_smoke=fixture["postwrite_smoke_result"],
        live_db_inventory=live_inventory,
        operator_evidence=operator_evidence,
        execute_requested=True,
    )
    token_leak = build_candidate_queue_review_inventory(
        review_handoff=handoff,
        postwrite_smoke=fixture["postwrite_smoke_result"],
        live_db_inventory=live_inventory,
        operator_evidence={**operator_evidence, "approval_token": TEST_APPROVAL_TOKEN},
        execute_requested=True,
    )

    assert inventory["mode"] == "candidate_queue_review_inventory_preview"
    assert inventory["review_inventory_ready"] is True
    assert inventory["ready_for_human_decision_review"] is True
    assert inventory["ready_for_api_review_state_update"] is False
    assert inventory["ready_for_api_database_write"] is False
    assert inventory["ready_for_scheduler_attach"] is False
    assert inventory["api_executes_cli"] is False
    assert inventory["api_reads_approval_token"] is False
    assert inventory["api_writes_database"] is False
    assert inventory["api_updates_review_state"] is False
    assert inventory["read_only_query_executed"] is True
    assert inventory["database_write_executed"] is False
    assert inventory["database_commit_executed"] is False
    assert inventory["scheduler_attached"] is False
    assert inventory["expected_dedupe_keys"] == fixture["expected_keys"]
    assert inventory["found_dedupe_keys"] == fixture["expected_keys"]
    assert inventory["missing_dedupe_keys"] == []
    assert inventory["row_summaries"][0]["review_state"] == "needs_review"
    assert inventory["alert_review_queue_table"]["exists"] is True
    assert "do_not_update_review_state_from_api" in inventory["safe_boundaries"]
    assert inventory["blocked_reasons"] == []
    assert token_leak["review_inventory_ready"] is False
    assert "review_inventory_no_approval_token_submitted_to_api" in token_leak[
        "blocked_reasons"
    ]
    assert TEST_APPROVAL_TOKEN not in json.dumps(
        token_leak,
        ensure_ascii=False,
        sort_keys=True,
    )


def test_candidate_queue_review_decision_preview_is_manual_only():
    from services.market_intel.candidate_queue_review_decision import (
        build_candidate_queue_review_decision,
    )

    fixture = _build_candidate_queue_writer_receipt_fixture(
        "sample-batch-review-decision"
    )
    inventory = {
        "mode": "candidate_queue_review_inventory_preview",
        "review_inventory_ready": True,
        "read_only_query_executed": True,
        "database_connection_opened": True,
        "database_write_executed": False,
        "database_commit_executed": False,
        "scheduler_attached": False,
        "expected_dedupe_keys": fixture["expected_keys"],
        "row_summaries": [
            {
                "dedupe_key": fixture["expected_keys"][0],
                "review_state": "needs_review",
                "priority_lane": "watch",
                "total_score": 82.5,
            }
        ],
    }
    operator_evidence = {
        "reviewer_id": "operator-a",
        "proposed_review_decision": "confirmed",
        "decision_notes": "evidence reviewed manually",
        "operator_confirmed_manual_decision_only": True,
        "operator_confirmed_no_api_db_write": True,
        "operator_confirmed_no_scheduler_attach": True,
    }
    decision = build_candidate_queue_review_decision(
        review_inventory=inventory,
        operator_evidence=operator_evidence,
    )
    token_leak = build_candidate_queue_review_decision(
        review_inventory=inventory,
        operator_evidence={**operator_evidence, "approval_token": TEST_APPROVAL_TOKEN},
    )

    assert decision["mode"] == "candidate_queue_review_decision_preview"
    assert decision["decision_ready"] is True
    assert decision["ready_for_human_decision_record"] is True
    assert decision["ready_for_api_review_state_update"] is False
    assert decision["ready_for_api_database_write"] is False
    assert decision["ready_for_scheduler_attach"] is False
    assert decision["api_executes_cli"] is False
    assert decision["api_reads_approval_token"] is False
    assert decision["api_writes_database"] is False
    assert decision["api_updates_review_state"] is False
    assert decision["decision_record_written"] is False
    assert decision["review_state_update_executed"] is False
    assert decision["database_write_executed"] is False
    assert decision["database_commit_executed"] is False
    assert decision["scheduler_attached"] is False
    assert decision["decision_rows"][0]["current_review_state"] == "needs_review"
    assert decision["decision_rows"][0]["proposed_review_state"] == "confirmed"
    assert decision["decision_contract"]["allowed_next_states"] == [
        "confirmed",
        "rejected",
        "deferred",
    ]
    assert "update_review_state" in decision["decision_contract"]["forbidden_api_actions"]
    assert "do_not_write_decision_record_from_api" in decision["safe_boundaries"]
    assert decision["blocked_reasons"] == []
    assert token_leak["decision_ready"] is False
    assert token_leak["operator_decision_summary"][
        "approval_token_submitted_to_api"
    ] is True
    assert "decision_no_approval_token_submitted_to_api" in token_leak[
        "blocked_reasons"
    ]
    assert TEST_APPROVAL_TOKEN not in json.dumps(
        token_leak,
        ensure_ascii=False,
        sort_keys=True,
    )


def test_candidate_queue_review_decision_approval_preview_is_cli_only():
    from services.market_intel.candidate_queue_review_decision import (
        build_candidate_queue_review_decision,
    )
    from services.market_intel.candidate_queue_review_decision_approval import (
        build_candidate_queue_review_decision_approval,
    )

    fixture = _build_candidate_queue_writer_receipt_fixture(
        "sample-batch-review-decision-approval"
    )
    inventory = {
        "mode": "candidate_queue_review_inventory_preview",
        "review_inventory_ready": True,
        "expected_dedupe_keys": fixture["expected_keys"],
        "row_summaries": [
            {
                "dedupe_key": fixture["expected_keys"][0],
                "review_state": "needs_review",
                "priority_lane": "watch",
                "total_score": 82.5,
            }
        ],
    }
    decision_operator_evidence = {
        "reviewer_id": "operator-a",
        "proposed_review_decision": "confirmed",
        "decision_notes": "evidence reviewed manually",
        "operator_confirmed_manual_decision_only": True,
        "operator_confirmed_no_api_db_write": True,
        "operator_confirmed_no_scheduler_attach": True,
    }
    approval_operator_evidence = {
        **decision_operator_evidence,
        "decision_approval_notes": "approved for cli-only transaction preview",
        "operator_confirmed_decision_payload_reviewed": True,
        "operator_confirmed_decision_apply_requires_cli": True,
        "operator_confirmed_review_state_update_is_not_api": True,
    }
    decision = build_candidate_queue_review_decision(
        review_inventory=inventory,
        operator_evidence=decision_operator_evidence,
    )
    approval = build_candidate_queue_review_decision_approval(
        review_decision=decision,
        operator_evidence=approval_operator_evidence,
    )
    token_leak = build_candidate_queue_review_decision_approval(
        review_decision=decision,
        operator_evidence={
            **approval_operator_evidence,
            "approval_token": TEST_APPROVAL_TOKEN,
        },
    )

    assert approval["mode"] == "candidate_queue_review_decision_approval_preview"
    assert approval["approval_ready"] is True
    assert approval["ready_for_review_state_transaction_preview"] is True
    assert approval["ready_for_cli_decision_writer"] is True
    assert approval["ready_for_api_review_state_update"] is False
    assert approval["ready_for_api_database_write"] is False
    assert approval["review_state_update_allowed_from_api"] is False
    assert approval["decision_apply_allowed_from_api"] is False
    assert approval["api_executes_cli"] is False
    assert approval["api_reads_approval_token"] is False
    assert approval["api_writes_database"] is False
    assert approval["api_updates_review_state"] is False
    assert approval["approval_record_written"] is False
    assert approval["decision_record_written"] is False
    assert approval["review_state_update_executed"] is False
    assert approval["database_write_executed"] is False
    assert approval["database_commit_executed"] is False
    assert approval["scheduler_attached"] is False
    assert approval["decision_update_preview"][0][
        "expected_current_review_state"
    ] == "needs_review"
    assert approval["decision_update_preview"][0][
        "approved_next_review_state"
    ] == "confirmed"
    assert approval["approval_contract"]["next_stage"] == (
        "candidate_queue_review_decision_transaction_preview"
    )
    assert "update_review_state" in approval["approval_contract"][
        "forbidden_api_actions"
    ]
    assert "do_not_update_review_state_from_approval_api" in approval[
        "safe_boundaries"
    ]
    assert approval["blocked_reasons"] == []
    assert token_leak["approval_ready"] is False
    assert token_leak["operator_approval_summary"][
        "approval_token_submitted_to_api"
    ] is True
    assert "approval_no_token_submitted_to_api" in token_leak[
        "blocked_reasons"
    ]
    assert TEST_APPROVAL_TOKEN not in json.dumps(
        token_leak,
        ensure_ascii=False,
        sort_keys=True,
    )


def test_candidate_queue_review_decision_transaction_preview_is_shell_only():
    from services.market_intel.candidate_queue_review_decision import (
        build_candidate_queue_review_decision,
    )
    from services.market_intel.candidate_queue_review_decision_approval import (
        build_candidate_queue_review_decision_approval,
    )
    from services.market_intel.candidate_queue_review_decision_transaction import (
        build_candidate_queue_review_decision_transaction,
    )

    fixture = _build_candidate_queue_writer_receipt_fixture(
        "sample-batch-review-decision-transaction"
    )
    inventory = {
        "mode": "candidate_queue_review_inventory_preview",
        "review_inventory_ready": True,
        "expected_dedupe_keys": fixture["expected_keys"],
        "row_summaries": [
            {
                "dedupe_key": fixture["expected_keys"][0],
                "review_state": "needs_review",
                "priority_lane": "watch",
                "total_score": 82.5,
            }
        ],
    }
    decision_operator_evidence = {
        "reviewer_id": "operator-a",
        "proposed_review_decision": "confirmed",
        "decision_notes": "evidence reviewed manually",
        "operator_confirmed_manual_decision_only": True,
        "operator_confirmed_no_api_db_write": True,
        "operator_confirmed_no_scheduler_attach": True,
    }
    approval_operator_evidence = {
        **decision_operator_evidence,
        "decision_approval_notes": "approved for cli-only transaction preview",
        "operator_confirmed_decision_payload_reviewed": True,
        "operator_confirmed_decision_apply_requires_cli": True,
        "operator_confirmed_review_state_update_is_not_api": True,
    }
    transaction_operator_evidence = {
        **approval_operator_evidence,
        "decision_transaction_notes": "payload reviewed for shell transaction",
        "operator_confirmed_transaction_payload_reviewed": True,
        "operator_confirmed_cli_only_transaction": True,
    }
    decision = build_candidate_queue_review_decision(
        review_inventory=inventory,
        operator_evidence=decision_operator_evidence,
    )
    approval = build_candidate_queue_review_decision_approval(
        review_decision=decision,
        operator_evidence=approval_operator_evidence,
    )
    transaction = build_candidate_queue_review_decision_transaction(
        decision_approval=approval,
        operator_evidence=transaction_operator_evidence,
    )
    token_leak = build_candidate_queue_review_decision_transaction(
        decision_approval=approval,
        operator_evidence={
            **transaction_operator_evidence,
            "approval_token": TEST_APPROVAL_TOKEN,
        },
    )

    assert transaction["mode"] == "candidate_queue_review_decision_transaction_preview"
    assert transaction["transaction_preview_created"] is True
    assert transaction["transaction_ready"] is True
    assert transaction["ready_for_manual_shell_update_window"] is True
    assert transaction["ready_for_cli_decision_writer"] is True
    assert transaction["ready_for_api_review_state_update"] is False
    assert transaction["ready_for_api_database_write"] is False
    assert transaction["ready_for_scheduler_attach"] is False
    assert transaction["api_executes_cli"] is False
    assert transaction["api_reads_approval_token"] is False
    assert transaction["api_writes_database"] is False
    assert transaction["api_updates_review_state"] is False
    assert transaction["approval_record_written"] is False
    assert transaction["decision_record_written"] is False
    assert transaction["review_state_update_executed"] is False
    assert transaction["database_connection_opened"] is False
    assert transaction["database_session_created"] is False
    assert transaction["explicit_transaction_opened"] is False
    assert transaction["transaction_opened"] is False
    assert transaction["transaction_committed"] is False
    assert transaction["database_write_executed"] is False
    assert transaction["database_commit_executed"] is False
    assert transaction["database_rollback_executed"] is False
    assert transaction["scheduler_attached"] is False
    assert transaction["statements"][0]["table"] == "market_alert_review_queue"
    assert transaction["statements"][0]["operation"] == "update"
    assert transaction["statements"][0]["statement_type"] == "update_review_state"
    assert transaction["statements"][0]["expected_current_review_state"] == (
        "needs_review"
    )
    assert transaction["statements"][0]["next_review_state"] == "confirmed"
    assert transaction["statements"][0]["parameter_keys"] == [
        "dedupe_key",
        "expected_current_review_state",
        "next_review_state",
    ]
    assert "UPDATE market_alert_review_queue" in transaction["statements"][0][
        "sql_template"
    ]
    assert transaction["transaction_preview_summary"]["api_write_allowed"] is False
    assert transaction["transaction_preview_summary"]["manual_cli_required"] is True
    assert transaction["transaction_contract"]["next_stage"] == (
        "manual_shell_review_state_update_window"
    )
    assert "update_review_state" in transaction["transaction_contract"][
        "forbidden_api_actions"
    ]
    assert "do_not_update_review_state_from_transaction_api" in transaction[
        "safe_boundaries"
    ]
    assert transaction["blocked_reasons"] == []
    assert token_leak["transaction_ready"] is False
    assert token_leak["operator_transaction_summary"][
        "approval_token_submitted_to_api"
    ] is True
    assert "transaction_no_token_submitted_to_api" in token_leak[
        "blocked_reasons"
    ]
    assert TEST_APPROVAL_TOKEN not in json.dumps(
        token_leak,
        ensure_ascii=False,
        sort_keys=True,
    )


def test_candidate_queue_review_decision_writer_cli_gate_is_non_writing():
    from services.market_intel.candidate_queue_review_decision_writer_cli import (
        APPROVAL_ENV_VAR,
        build_candidate_queue_review_decision_writer_cli_plan,
    )

    transaction, _ = _build_ready_review_decision_transaction()
    plan = build_candidate_queue_review_decision_writer_cli_plan(
        transaction_preview=transaction,
        execute_requested=True,
        apply_real_write=True,
        approval_token=TEST_APPROVAL_TOKEN,
        approval_token_secret=TEST_APPROVAL_TOKEN,
        backup_verified=True,
        review_inventory_smoke_passed=True,
    )
    payload = json.dumps(plan, ensure_ascii=False, sort_keys=True)

    assert plan["mode"] == "candidate_queue_review_decision_writer_cli_blocked"
    assert plan["target_table"] == "market_alert_review_queue"
    assert plan["target_operation"] == "update_review_state"
    assert plan["script_path"] == "scripts/market_intel_review_decision_writer.py"
    assert plan["approval_env_var"] == APPROVAL_ENV_VAR
    assert plan["execute_requested"] is True
    assert plan["apply_real_write_requested"] is True
    assert plan["approval_token_present"] is True
    assert plan["approval_token_valid"] is True
    assert plan["writer_implementation_enabled"] is False
    assert plan["ready_for_real_write"] is False
    assert plan["ready_for_api_review_state_update"] is False
    assert plan["ready_for_api_database_write"] is False
    assert plan["api_executes_cli"] is False
    assert plan["api_reads_approval_token"] is False
    assert plan["api_writes_database"] is False
    assert plan["api_updates_review_state"] is False
    assert plan["review_state_update_executed"] is False
    assert plan["database_connection_opened"] is False
    assert plan["database_session_created"] is False
    assert plan["explicit_transaction_opened"] is False
    assert plan["transaction_opened"] is False
    assert plan["transaction_committed"] is False
    assert plan["database_write_executed"] is False
    assert plan["database_commit_executed"] is False
    assert plan["scheduler_attached"] is False
    assert plan["writes_executed"] is False
    assert plan["would_write_database"] is False
    assert plan["statement_summary"]["statement_count"] == 1
    assert plan["statement_summary"]["review_state_updates"][0][
        "next_review_state"
    ] == "confirmed"
    assert "review_decision_writer_implementation_enabled" in plan[
        "blocked_reasons"
    ]
    assert "do_not_update_review_state_from_api_writer_status" in plan[
        "safe_boundaries"
    ]
    assert TEST_APPROVAL_TOKEN not in payload


def test_candidate_queue_review_decision_writer_preflight_is_payload_only():
    from services.market_intel.candidate_queue_review_decision_writer_cli import (
        build_candidate_queue_review_decision_writer_cli_plan,
    )
    from services.market_intel.candidate_queue_review_decision_writer_preflight import (
        build_candidate_queue_review_decision_writer_preflight,
    )

    transaction, operator_evidence = _build_ready_review_decision_transaction()
    writer_status = build_candidate_queue_review_decision_writer_cli_plan(
        transaction_preview=transaction,
        execute_requested=False,
        apply_real_write=False,
    )
    preflight = build_candidate_queue_review_decision_writer_preflight(
        writer_status=writer_status,
        transaction_preview=transaction,
        operator_evidence={
            **operator_evidence,
            "operator_confirmed_review_state_preflight_only": True,
        },
    )
    token_leak = build_candidate_queue_review_decision_writer_preflight(
        writer_status=writer_status,
        transaction_preview=transaction,
        operator_evidence={**operator_evidence, "approval_token": TEST_APPROVAL_TOKEN},
    )
    payload = json.dumps(preflight, ensure_ascii=False, sort_keys=True)

    assert preflight["mode"] == (
        "candidate_queue_review_decision_writer_preflight_preview"
    )
    assert preflight["target_table"] == "market_alert_review_queue"
    assert preflight["target_operation"] == "update_review_state"
    assert preflight["execute_requested"] is False
    assert preflight["apply_real_write_requested"] is False
    assert preflight["preflight_payload_ready"] is True
    assert preflight["writer_status_safe"] is True
    assert preflight["writer_implementation_enabled"] is False
    assert preflight["preflight_ready"] is False
    assert preflight["ready_for_real_write"] is False
    assert preflight["ready_for_api_review_state_update"] is False
    assert preflight["ready_for_api_database_write"] is False
    assert preflight["api_executes_cli"] is False
    assert preflight["api_reads_approval_token"] is False
    assert preflight["api_writes_database"] is False
    assert preflight["api_updates_review_state"] is False
    assert preflight["review_state_update_executed"] is False
    assert preflight["read_only_query_executed"] is False
    assert preflight["database_connection_opened"] is False
    assert preflight["database_session_created"] is False
    assert preflight["transaction_opened"] is False
    assert preflight["transaction_committed"] is False
    assert preflight["database_write_executed"] is False
    assert preflight["database_commit_executed"] is False
    assert preflight["scheduler_attached"] is False
    assert preflight["writes_executed"] is False
    assert preflight["would_write_database"] is False
    assert preflight["statement_summary"]["statement_count"] == 1
    assert preflight["statement_summary"]["invalid_statement_count"] == 0
    assert preflight["statement_summary"]["review_state_updates"][0][
        "next_review_state"
    ] == "confirmed"
    assert preflight["update_contract"]["expected_current_review_state"] == (
        "needs_review"
    )
    assert preflight["catalog_probe_plan"]["read_only_query_executed"] is False
    assert "review_decision_writer_implementation_enabled" in preflight[
        "blocked_reasons"
    ]
    assert "do_not_update_review_state_from_review_state_preflight" in preflight[
        "safe_boundaries"
    ]
    assert "preflight_no_token_submitted_to_api" in token_leak["blocked_reasons"]
    assert TEST_APPROVAL_TOKEN not in payload


def test_candidate_queue_review_decision_writer_postwrite_smoke_is_read_only():
    from services.market_intel.candidate_queue_review_decision_writer_postwrite_smoke import (
        build_candidate_queue_review_decision_writer_postwrite_smoke,
    )

    transaction, _operator_evidence = _build_ready_review_decision_transaction()
    statement = transaction["statements"][0]
    dedupe_key = statement["lookup"]["dedupe_key"]
    expected_state = statement["next_review_state"]
    plan = build_candidate_queue_review_decision_writer_postwrite_smoke(
        transaction_preview=transaction,
        execute_requested=False,
    )
    engine = create_engine("sqlite:///:memory:")
    with engine.begin() as conn:
        conn.execute(
            text(
                """
                CREATE TABLE market_alert_review_queue (
                    id INTEGER PRIMARY KEY,
                    alert_candidate_id INTEGER,
                    review_state TEXT,
                    priority_lane TEXT,
                    threshold_level TEXT,
                    total_score REAL,
                    evidence_bundle_id TEXT,
                    dedupe_key TEXT UNIQUE,
                    source_batch_id TEXT,
                    reviewed_at TEXT,
                    created_at TEXT,
                    updated_at TEXT
                )
                """
            )
        )
        conn.execute(
            text(
                """
                INSERT INTO market_alert_review_queue (
                    alert_candidate_id,
                    review_state,
                    priority_lane,
                    threshold_level,
                    total_score,
                    evidence_bundle_id,
                    dedupe_key,
                    source_batch_id,
                    reviewed_at,
                    created_at,
                    updated_at
                )
                VALUES (
                    101,
                    :review_state,
                    'urgent',
                    'high',
                    91.5,
                    'evidence-1',
                    :dedupe_key,
                    'sample-batch',
                    '2026-05-19T12:00:00',
                    '2026-05-19T11:00:00',
                    '2026-05-19T12:00:00'
                )
                """
            ),
            {"review_state": expected_state, "dedupe_key": dedupe_key},
        )
    smoke = build_candidate_queue_review_decision_writer_postwrite_smoke(
        transaction_preview=transaction,
        execute_requested=True,
        engine=engine,
        database_type="sqlite",
    )
    payload = json.dumps(smoke, ensure_ascii=False, sort_keys=True)

    assert plan["mode"] == (
        "candidate_queue_review_decision_writer_postwrite_smoke_planned"
    )
    assert plan["read_only_query_executed"] is False
    assert plan["database_connection_opened"] is False
    assert plan["review_state_update_executed"] is False
    assert plan["api_updates_review_state"] is False
    assert plan["database_write_executed"] is False
    assert plan["database_commit_executed"] is False
    assert "review_decision_writer_postwrite_smoke_not_loaded" in plan[
        "blocked_reasons"
    ]
    assert smoke["mode"] == (
        "candidate_queue_review_decision_writer_postwrite_smoke_read_only"
    )
    assert smoke["read_only_query_executed"] is True
    assert smoke["database_connection_opened"] is True
    assert smoke["database_session_created"] is False
    assert smoke["explicit_transaction_opened"] is False
    assert smoke["transaction_committed"] is False
    assert smoke["database_write_executed"] is False
    assert smoke["database_commit_executed"] is False
    assert smoke["review_state_update_executed"] is False
    assert smoke["api_updates_review_state"] is False
    assert smoke["scheduler_attached"] is False
    assert smoke["postwrite_smoke_passed"] is True
    assert smoke["review_state_update_verified"] is True
    assert smoke["missing_count"] == 0
    assert smoke["state_mismatch_count"] == 0
    assert smoke["found_dedupe_keys"] == [dedupe_key]
    assert TEST_APPROVAL_TOKEN not in payload


def test_candidate_queue_review_decision_writer_operator_drill_preview_is_safe():
    from services.market_intel.candidate_queue_review_decision_writer_cli import (
        build_candidate_queue_review_decision_writer_cli_plan,
    )
    from services.market_intel.candidate_queue_review_decision_writer_preflight import (
        build_candidate_queue_review_decision_writer_preflight,
    )
    from services.market_intel.candidate_queue_review_decision_writer_postwrite_smoke import (
        build_candidate_queue_review_decision_writer_postwrite_smoke,
    )
    from services.market_intel.candidate_queue_review_decision_writer_operator_drill import (
        build_candidate_queue_review_decision_writer_operator_drill,
    )

    transaction, operator_evidence = _build_ready_review_decision_transaction()
    operator_evidence = {
        **operator_evidence,
        "operator_confirmed_manual_shell_window": True,
        "operator_confirmed_post_update_inventory_planned": True,
        "operator_drill_notes": "review_state shell drill reviewed",
    }
    writer_status = build_candidate_queue_review_decision_writer_cli_plan(
        transaction_preview=transaction,
        operator_evidence=operator_evidence,
    )
    preflight = build_candidate_queue_review_decision_writer_preflight(
        writer_status=writer_status,
        transaction_preview=transaction,
        operator_evidence=operator_evidence,
    )
    smoke = build_candidate_queue_review_decision_writer_postwrite_smoke(
        transaction_preview=transaction,
        execute_requested=False,
    )
    drill = build_candidate_queue_review_decision_writer_operator_drill(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=smoke,
        operator_evidence=operator_evidence,
    )
    token_leak = build_candidate_queue_review_decision_writer_operator_drill(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=smoke,
        operator_evidence={**operator_evidence, "approval_token": TEST_APPROVAL_TOKEN},
    )
    payload = json.dumps(drill, ensure_ascii=False, sort_keys=True)

    assert drill["mode"] == (
        "candidate_queue_review_decision_writer_operator_drill_preview"
    )
    assert drill["target_table"] == "market_alert_review_queue"
    assert drill["target_operation"] == "update_review_state"
    assert drill["operator_drill_ready"] is True
    assert drill["ready_for_api_review_state_update"] is False
    assert drill["ready_for_api_database_write"] is False
    assert drill["ready_for_scheduler_attach"] is False
    assert drill["api_executes_cli"] is False
    assert drill["api_reads_approval_token"] is False
    assert drill["api_writes_file"] is False
    assert drill["api_writes_database"] is False
    assert drill["api_updates_review_state"] is False
    assert drill["review_state_update_executed"] is False
    assert drill["database_connection_opened"] is False
    assert drill["database_session_created"] is False
    assert drill["transaction_opened"] is False
    assert drill["transaction_committed"] is False
    assert drill["database_write_executed"] is False
    assert drill["database_commit_executed"] is False
    assert drill["scheduler_attached"] is False
    assert drill["statement_summary"]["statement_count"] == 1
    assert drill["statement_summary"]["invalid_statement_count"] == 0
    assert drill["input_summaries"]["writer_preflight_mode"] == (
        "candidate_queue_review_decision_writer_preflight_preview"
    )
    assert drill["input_summaries"]["postwrite_smoke_mode"] == (
        "candidate_queue_review_decision_writer_postwrite_smoke_planned"
    )
    assert len(drill["command_sequence"]) == 5
    assert any(item["key"] == "run_cli_review_state_writer" for item in drill["command_sequence"])
    assert "backup_verified_by_operator" in drill["blocked_reasons"]
    assert "do_not_update_review_state_from_review_state_operator_drill" in drill[
        "safe_boundaries"
    ]
    assert token_leak["operator_drill_ready"] is False
    assert "operator_drill_no_token_submitted_to_api" in token_leak[
        "blocked_reasons"
    ]
    assert TEST_APPROVAL_TOKEN not in payload


def test_candidate_queue_review_decision_writer_run_package_preview_is_safe():
    from services.market_intel.candidate_queue_review_decision_writer_cli import (
        build_candidate_queue_review_decision_writer_cli_plan,
    )
    from services.market_intel.candidate_queue_review_decision_writer_preflight import (
        build_candidate_queue_review_decision_writer_preflight,
    )
    from services.market_intel.candidate_queue_review_decision_writer_postwrite_smoke import (
        build_candidate_queue_review_decision_writer_postwrite_smoke,
    )
    from services.market_intel.candidate_queue_review_decision_writer_operator_drill import (
        build_candidate_queue_review_decision_writer_operator_drill,
    )
    from services.market_intel.candidate_queue_review_decision_writer_run_package import (
        build_candidate_queue_review_decision_writer_run_package,
    )

    transaction, operator_evidence = _build_ready_review_decision_transaction()
    operator_evidence = {
        **operator_evidence,
        "operator_confirmed_manual_shell_window": True,
        "operator_confirmed_post_update_inventory_planned": True,
        "operator_drill_notes": "review_state shell drill reviewed",
    }
    writer_status = build_candidate_queue_review_decision_writer_cli_plan(
        transaction_preview=transaction,
        operator_evidence=operator_evidence,
    )
    preflight = build_candidate_queue_review_decision_writer_preflight(
        writer_status=writer_status,
        transaction_preview=transaction,
        operator_evidence=operator_evidence,
    )
    smoke = build_candidate_queue_review_decision_writer_postwrite_smoke(
        transaction_preview=transaction,
        execute_requested=False,
    )
    drill = build_candidate_queue_review_decision_writer_operator_drill(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=smoke,
        operator_evidence=operator_evidence,
    )
    package = build_candidate_queue_review_decision_writer_run_package(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=smoke,
        operator_drill=drill,
    )
    payload = json.dumps(package, ensure_ascii=False, sort_keys=True)

    assert package["mode"] == (
        "candidate_queue_review_decision_writer_run_package_preview"
    )
    assert package["target_table"] == "market_alert_review_queue"
    assert package["target_operation"] == "update_review_state"
    assert package["package_ready"] is False
    assert package["package_artifact_created"] is False
    assert package["ready_for_api_review_state_update"] is False
    assert package["ready_for_api_database_write"] is False
    assert package["ready_for_scheduler_attach"] is False
    assert package["api_writes_file"] is False
    assert package["api_executes_cli"] is False
    assert package["api_reads_approval_token"] is False
    assert package["api_writes_database"] is False
    assert package["api_updates_review_state"] is False
    assert package["review_state_update_executed"] is False
    assert package["database_connection_opened"] is False
    assert package["database_session_created"] is False
    assert package["transaction_opened"] is False
    assert package["transaction_committed"] is False
    assert package["database_write_executed"] is False
    assert package["database_commit_executed"] is False
    assert package["scheduler_attached"] is False
    assert package["payload_manifest"]["payload_count"] == 1
    assert package["payload_manifest"]["payloads"][0]["next_review_state"] == "confirmed"
    assert len(package["required_artifacts"]) == 5
    assert len(package["command_bundle"]) == 5
    assert "backup_artifact_path_recorded" in package["blocked_reasons"]
    assert "one_time_token_supplied_in_shell_only" in package["blocked_reasons"]
    assert "do_not_update_review_state_from_review_state_run_package" in package[
        "safe_boundaries"
    ]
    assert TEST_APPROVAL_TOKEN not in payload


def test_candidate_queue_review_decision_writer_run_readiness_preview_checks_operator_evidence():
    from services.market_intel.candidate_queue_review_decision_writer_cli import (
        build_candidate_queue_review_decision_writer_cli_plan,
    )
    from services.market_intel.candidate_queue_review_decision_writer_preflight import (
        build_candidate_queue_review_decision_writer_preflight,
    )
    from services.market_intel.candidate_queue_review_decision_writer_postwrite_smoke import (
        build_candidate_queue_review_decision_writer_postwrite_smoke,
    )
    from services.market_intel.candidate_queue_review_decision_writer_operator_drill import (
        build_candidate_queue_review_decision_writer_operator_drill,
    )
    from services.market_intel.candidate_queue_review_decision_writer_run_package import (
        build_candidate_queue_review_decision_writer_run_package,
    )
    from services.market_intel.candidate_queue_review_decision_writer_run_readiness import (
        build_candidate_queue_review_decision_writer_run_readiness,
    )

    transaction, operator_evidence = _build_ready_review_decision_transaction()
    operator_evidence = {
        **operator_evidence,
        "operator_confirmed_manual_shell_window": True,
        "operator_confirmed_post_update_inventory_planned": True,
        "operator_drill_notes": "review_state shell drill reviewed",
    }
    writer_status = build_candidate_queue_review_decision_writer_cli_plan(
        transaction_preview=transaction,
        operator_evidence=operator_evidence,
    )
    preflight = build_candidate_queue_review_decision_writer_preflight(
        writer_status=writer_status,
        transaction_preview=transaction,
        operator_evidence=operator_evidence,
    )
    smoke = build_candidate_queue_review_decision_writer_postwrite_smoke(
        transaction_preview=transaction,
        execute_requested=False,
    )
    drill = build_candidate_queue_review_decision_writer_operator_drill(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=smoke,
        operator_evidence=operator_evidence,
    )
    package = build_candidate_queue_review_decision_writer_run_package(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=smoke,
        operator_drill=drill,
    )
    missing = build_candidate_queue_review_decision_writer_run_readiness(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=smoke,
        operator_drill=drill,
        run_package=package,
    )
    ready = build_candidate_queue_review_decision_writer_run_readiness(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=smoke,
        operator_drill=drill,
        run_package=package,
        operator_evidence={
            "review_state_transaction_json_path": (
                "artifacts/market_intel/review-state-transaction.json"
            ),
            "backup_artifact_path": "scripts/tools/backups/backup.zip",
            "preflight_artifact_path": (
                "artifacts/market_intel/review-state-preflight.json"
            ),
            "operator_confirmed_review_state_preflight_only": True,
            "operator_acknowledged_shell_only_token": True,
        },
    )
    token_leak = build_candidate_queue_review_decision_writer_run_readiness(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=smoke,
        operator_drill=drill,
        run_package=package,
        operator_evidence={
            "review_state_transaction_json_path": (
                "artifacts/market_intel/review-state-transaction.json"
            ),
            "backup_artifact_path": "scripts/tools/backups/backup.zip",
            "preflight_artifact_path": (
                "artifacts/market_intel/review-state-preflight.json"
            ),
            "operator_confirmed_review_state_preflight_only": True,
            "operator_acknowledged_shell_only_token": True,
            "approval_token": TEST_APPROVAL_TOKEN,
        },
    )

    assert missing["mode"] == (
        "candidate_queue_review_decision_writer_run_readiness_preview"
    )
    assert missing["target_table"] == "market_alert_review_queue"
    assert missing["target_operation"] == "update_review_state"
    assert missing["ready_for_cli_operator_run"] is False
    assert missing["ready_for_api_review_state_update"] is False
    assert missing["ready_for_api_database_write"] is False
    assert missing["ready_for_scheduler_attach"] is False
    assert missing["api_executes_cli"] is False
    assert missing["api_reads_approval_token"] is False
    assert missing["api_writes_file"] is False
    assert missing["api_updates_review_state"] is False
    assert missing["review_state_update_executed"] is False
    assert missing["database_connection_opened"] is False
    assert missing["database_write_executed"] is False
    assert missing["database_commit_executed"] is False
    assert missing["scheduler_attached"] is False
    assert "review_state_transaction_json_path_recorded" in missing[
        "blocked_reasons"
    ]
    assert "operator_acknowledged_shell_only_token" in missing["blocked_reasons"]
    assert ready["ready_for_cli_operator_run"] is True
    assert ready["ready_for_api_review_state_update"] is False
    assert ready["database_write_executed"] is False
    assert ready["run_package_summary"]["package_ready"] is False
    assert ready["run_package_summary"]["payload_count"] == 1
    assert ready["operator_evidence_summary"]["artifact_path_count"] == 3
    assert token_leak["ready_for_cli_operator_run"] is False
    assert token_leak["operator_evidence_summary"][
        "approval_token_submitted_to_api"
    ] is True
    assert "approval_token_not_submitted_to_api" in token_leak["blocked_reasons"]
    assert "do_not_update_review_state_from_review_state_run_readiness" in ready[
        "safe_boundaries"
    ]
    assert TEST_APPROVAL_TOKEN not in json.dumps(
        token_leak,
        ensure_ascii=False,
        sort_keys=True,
    )


def test_candidate_queue_review_decision_writer_run_receipt_preview_reviews_operator_artifacts():
    from services.market_intel.candidate_queue_review_decision_writer_cli import (
        build_candidate_queue_review_decision_writer_cli_plan,
    )
    from services.market_intel.candidate_queue_review_decision_writer_preflight import (
        build_candidate_queue_review_decision_writer_preflight,
    )
    from services.market_intel.candidate_queue_review_decision_writer_postwrite_smoke import (
        build_candidate_queue_review_decision_writer_postwrite_smoke,
    )
    from services.market_intel.candidate_queue_review_decision_writer_operator_drill import (
        build_candidate_queue_review_decision_writer_operator_drill,
    )
    from services.market_intel.candidate_queue_review_decision_writer_run_package import (
        build_candidate_queue_review_decision_writer_run_package,
    )
    from services.market_intel.candidate_queue_review_decision_writer_run_readiness import (
        build_candidate_queue_review_decision_writer_run_readiness,
    )
    from services.market_intel.candidate_queue_review_decision_writer_run_receipt import (
        build_candidate_queue_review_decision_writer_run_receipt,
    )

    transaction, operator_evidence = _build_ready_review_decision_transaction()
    expected_key = transaction["statements"][0]["lookup"]["dedupe_key"]
    operator_evidence = {
        **operator_evidence,
        "operator_confirmed_manual_shell_window": True,
        "operator_confirmed_post_update_inventory_planned": True,
        "operator_drill_notes": "review_state shell drill reviewed",
    }
    writer_status = build_candidate_queue_review_decision_writer_cli_plan(
        transaction_preview=transaction,
        operator_evidence=operator_evidence,
    )
    preflight = build_candidate_queue_review_decision_writer_preflight(
        writer_status=writer_status,
        transaction_preview=transaction,
        operator_evidence=operator_evidence,
    )
    smoke = build_candidate_queue_review_decision_writer_postwrite_smoke(
        transaction_preview=transaction,
        execute_requested=False,
    )
    drill = build_candidate_queue_review_decision_writer_operator_drill(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=smoke,
        operator_evidence=operator_evidence,
    )
    package = build_candidate_queue_review_decision_writer_run_package(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=smoke,
        operator_drill=drill,
    )
    receipt_evidence = {
        **operator_evidence,
        "review_state_transaction_json_path": (
            "artifacts/market_intel/review-state-transaction.json"
        ),
        "backup_artifact_path": "scripts/tools/backups/backup.zip",
        "preflight_artifact_path": (
            "artifacts/market_intel/review-state-preflight.json"
        ),
        "operator_confirmed_review_state_preflight_only": True,
        "operator_acknowledged_shell_only_token": True,
        "review_state_writer_output_json_path": (
            "artifacts/market_intel/review-state-writer-output.json"
        ),
        "review_state_postwrite_smoke_json_path": (
            "artifacts/market_intel/review-state-postwrite-smoke.json"
        ),
        "operator_confirmed_no_token_in_artifacts": True,
        "receipt_notes": "review_state receipt reviewed",
    }
    readiness = build_candidate_queue_review_decision_writer_run_readiness(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=smoke,
        operator_drill=drill,
        run_package=package,
        operator_evidence=receipt_evidence,
    )
    writer_output = {
        "mode": "candidate_queue_review_decision_writer_cli_executed",
        "exit_code": 0,
        "approval_token_present": True,
        "approval_token_valid": True,
        "approval_token_secret_configured": True,
        "approval_env_var": "MARKET_INTEL_QUEUE_WRITE_APPROVAL",
        "writes_executed": True,
        "would_write_database": True,
        "database_connection_opened": True,
        "explicit_transaction_opened": True,
        "database_write_executed": True,
        "database_commit_executed": True,
        "database_rollback_executed": False,
        "external_network_executed": False,
        "scheduler_attached": False,
        "api_updates_review_state": False,
        "review_state_update_executed": True,
        "updated_count": 1,
        "skipped_count": 0,
        "affected_dedupe_keys": [expected_key],
        "skipped_dedupe_keys": [],
    }
    postwrite_smoke_result = {
        "mode": "candidate_queue_review_decision_writer_postwrite_smoke_read_only",
        "postwrite_smoke_passed": True,
        "review_state_update_verified": True,
        "ready_for_operator_review": True,
        "read_only_query_executed": True,
        "database_connection_opened": True,
        "database_write_executed": False,
        "database_commit_executed": False,
        "external_network_executed": False,
        "scheduler_attached": False,
        "expected_dedupe_key_count": 1,
        "found_count": 1,
        "missing_count": 0,
        "state_mismatch_count": 0,
        "found_dedupe_keys": [expected_key],
        "missing_dedupe_keys": [],
        "state_mismatches": [],
    }
    receipt = build_candidate_queue_review_decision_writer_run_receipt(
        transaction_preview=transaction,
        run_readiness=readiness,
        writer_output=writer_output,
        postwrite_smoke_result=postwrite_smoke_result,
        operator_evidence=receipt_evidence,
    )
    token_leak = build_candidate_queue_review_decision_writer_run_receipt(
        transaction_preview=transaction,
        run_readiness=readiness,
        writer_output={**writer_output, "approval_token": TEST_APPROVAL_TOKEN},
        postwrite_smoke_result=postwrite_smoke_result,
        operator_evidence=receipt_evidence,
    )

    assert receipt["mode"] == (
        "candidate_queue_review_decision_writer_run_receipt_preview"
    )
    assert receipt["target_operation"] == "update_review_state"
    assert receipt["receipt_passed"] is True
    assert receipt["ready_for_next_manual_phase"] is True
    assert receipt["ready_for_api_review_state_update"] is False
    assert receipt["ready_for_api_database_write"] is False
    assert receipt["ready_for_scheduler_attach"] is False
    assert receipt["api_executes_cli"] is False
    assert receipt["api_reads_approval_token"] is False
    assert receipt["api_writes_file"] is False
    assert receipt["api_updates_review_state"] is False
    assert receipt["review_state_update_executed"] is False
    assert receipt["database_connection_opened"] is False
    assert receipt["database_write_executed"] is False
    assert receipt["database_commit_executed"] is False
    assert receipt["scheduler_attached"] is False
    assert receipt["writer_output_summary"]["review_state_update_executed"] is True
    assert receipt["writer_output_summary"]["dedupe_keys_match_expected"] is True
    assert receipt["postwrite_smoke_summary"]["dedupe_keys_match_expected"] is True
    assert receipt["postwrite_smoke_summary"]["review_state_update_verified"] is True
    assert receipt["operator_evidence_summary"][
        "writer_output_json_path_recorded"
    ] is True
    assert receipt["blocked_reasons"] == []
    assert token_leak["receipt_passed"] is False
    assert token_leak["writer_output_summary"]["approval_token_key_detected"] is True
    assert "writer_output_no_approval_token_key" in token_leak["blocked_reasons"]
    assert "do_not_update_review_state_from_review_state_receipt" in receipt[
        "safe_boundaries"
    ]
    assert TEST_APPROVAL_TOKEN not in json.dumps(
        token_leak,
        ensure_ascii=False,
        sort_keys=True,
    )


def test_candidate_queue_review_decision_writer_run_closeout_preview_blocks_api_write_and_tokens():
    from services.market_intel.candidate_queue_review_decision_writer_run_closeout import (
        build_candidate_queue_review_decision_writer_run_closeout,
    )

    fixture = _build_review_decision_writer_receipt_fixture(
        "sample-batch-review-state-closeout"
    )
    closeout_evidence = {
        **fixture["operator_evidence"],
        "review_state_closeout_artifact_path": (
            "artifacts/market_intel/review-state-closeout.json"
        ),
        "operator_confirmed_review_state_closeout_next": True,
        "operator_confirmed_post_closeout_inventory_read_only": True,
        "operator_confirmed_no_scheduler_attach": True,
        "operator_confirmed_no_api_db_write": True,
        "closeout_notes": "review_state closeout reviewed",
    }
    closeout = build_candidate_queue_review_decision_writer_run_closeout(
        transaction_preview=fixture["transaction"],
        run_receipt=fixture["receipt"],
        operator_evidence=closeout_evidence,
    )
    token_leak = build_candidate_queue_review_decision_writer_run_closeout(
        transaction_preview=fixture["transaction"],
        run_receipt=fixture["receipt"],
        operator_evidence={
            **closeout_evidence,
            "approval_token": TEST_APPROVAL_TOKEN,
        },
    )

    assert closeout["mode"] == (
        "candidate_queue_review_decision_writer_run_closeout_preview"
    )
    assert closeout["target_operation"] == "update_review_state"
    assert closeout["closeout_passed"] is True
    assert closeout["ready_for_next_manual_phase"] is True
    assert closeout["ready_for_review_inventory"] is True
    assert closeout["ready_for_api_review_state_update"] is False
    assert closeout["ready_for_api_database_write"] is False
    assert closeout["ready_for_scheduler_attach"] is False
    assert closeout["api_executes_cli"] is False
    assert closeout["api_reads_approval_token"] is False
    assert closeout["api_writes_file"] is False
    assert closeout["api_writes_database"] is False
    assert closeout["api_updates_review_state"] is False
    assert closeout["review_state_update_executed"] is False
    assert closeout["database_connection_opened"] is False
    assert closeout["database_write_executed"] is False
    assert closeout["database_commit_executed"] is False
    assert closeout["scheduler_attached"] is False
    assert closeout["blocked_reasons"] == []
    assert closeout["receipt_summary"]["target_operation"] == "update_review_state"
    assert closeout["receipt_summary"]["receipt_passed"] is True
    assert closeout["receipt_summary"]["safe_boundaries_complete"] is True
    assert closeout["operator_closeout_summary"][
        "closeout_artifact_path_recorded"
    ] is True
    assert closeout["promotion_gate"]["requires_real_db_write"] is False
    assert "do_not_update_review_state_from_review_state_closeout" in closeout[
        "safe_boundaries"
    ]
    assert token_leak["closeout_passed"] is False
    assert token_leak["operator_closeout_summary"][
        "approval_token_submitted_to_api"
    ] is True
    assert "closeout_no_approval_token_submitted_to_api" in token_leak[
        "blocked_reasons"
    ]
    assert TEST_APPROVAL_TOKEN not in json.dumps(
        token_leak,
        ensure_ascii=False,
        sort_keys=True,
    )


def test_candidate_queue_review_decision_post_closeout_inventory_is_read_only():
    from services.market_intel.candidate_queue_review_decision_post_closeout_inventory import (
        build_candidate_queue_review_decision_post_closeout_inventory,
    )
    from services.market_intel.candidate_queue_review_decision_writer_run_closeout import (
        build_candidate_queue_review_decision_writer_run_closeout,
    )

    fixture = _build_review_decision_writer_receipt_fixture(
        "sample-batch-review-state-post-closeout"
    )
    closeout_evidence = {
        **fixture["operator_evidence"],
        "review_state_closeout_artifact_path": (
            "artifacts/market_intel/review-state-closeout.json"
        ),
        "operator_confirmed_review_state_closeout_next": True,
        "operator_confirmed_post_closeout_inventory_read_only": True,
        "operator_confirmed_no_scheduler_attach": True,
        "operator_confirmed_no_api_db_write": True,
        "closeout_notes": "review_state closeout reviewed",
    }
    closeout = build_candidate_queue_review_decision_writer_run_closeout(
        transaction_preview=fixture["transaction"],
        run_receipt=fixture["receipt"],
        operator_evidence=closeout_evidence,
    )
    live_inventory = {
        "mode": "live_db_inventory_loaded",
        "summary_ready": True,
        "read_only_query_executed": True,
        "database_connection_opened": True,
        "database_write_executed": False,
        "database_commit_executed": False,
        "migration_executed": False,
        "external_network_executed": False,
        "scheduler_attached": False,
        "total_rows": 1,
        "table_statuses": [
            {
                "table": "market_alert_review_queue",
                "exists": True,
                "row_count": 1,
                "status": "loaded",
            }
        ],
        "alert_review_state_breakdown": [
            {
                "review_state": "confirmed",
                "priority_lane": "watch",
                "alert_count": 1,
            }
        ],
    }
    inventory = build_candidate_queue_review_decision_post_closeout_inventory(
        transaction_preview=fixture["transaction"],
        run_closeout=closeout,
        postwrite_smoke=fixture["postwrite_smoke_result"],
        live_db_inventory=live_inventory,
        operator_evidence=closeout_evidence,
        execute_requested=True,
    )
    token_leak = build_candidate_queue_review_decision_post_closeout_inventory(
        transaction_preview=fixture["transaction"],
        run_closeout=closeout,
        postwrite_smoke=fixture["postwrite_smoke_result"],
        live_db_inventory=live_inventory,
        operator_evidence={
            **closeout_evidence,
            "approval_token": TEST_APPROVAL_TOKEN,
        },
        execute_requested=True,
    )

    assert inventory["mode"] == (
        "candidate_queue_review_decision_post_closeout_inventory_preview"
    )
    assert inventory["target_operation"] == "verify_review_state_after_closeout"
    assert inventory["post_closeout_inventory_ready"] is True
    assert inventory["ready_for_review_completion_archive"] is True
    assert inventory["ready_for_api_review_state_update"] is False
    assert inventory["ready_for_api_database_write"] is False
    assert inventory["ready_for_scheduler_attach"] is False
    assert inventory["api_executes_cli"] is False
    assert inventory["api_reads_approval_token"] is False
    assert inventory["api_writes_database"] is False
    assert inventory["api_updates_review_state"] is False
    assert inventory["review_state_update_executed"] is False
    assert inventory["database_write_executed"] is False
    assert inventory["database_commit_executed"] is False
    assert inventory["scheduler_attached"] is False
    assert inventory["read_only_query_executed"] is True
    assert inventory["expected_dedupe_keys"] == fixture["receipt"][
        "expected_dedupe_keys"
    ]
    assert inventory["found_dedupe_keys"] == fixture["receipt"][
        "expected_dedupe_keys"
    ]
    assert inventory["state_mismatches"] == []
    assert inventory["alert_review_queue_table"]["exists"] is True
    assert inventory["blocked_reasons"] == []
    assert "post_closeout_inventory_read_only" in inventory["safe_boundaries"]
    assert token_leak["post_closeout_inventory_ready"] is False
    assert token_leak["operator_inventory_summary"][
        "approval_token_submitted_to_api"
    ] is True
    assert "post_closeout_inventory_no_approval_token_submitted_to_api" in token_leak[
        "blocked_reasons"
    ]
    assert TEST_APPROVAL_TOKEN not in json.dumps(
        token_leak,
        ensure_ascii=False,
        sort_keys=True,
    )


def test_candidate_queue_review_completion_archive_is_preview_only():
    from services.market_intel.candidate_queue_review_completion_archive import (
        build_candidate_queue_review_completion_archive,
    )
    from services.market_intel.candidate_queue_review_decision_post_closeout_inventory import (
        build_candidate_queue_review_decision_post_closeout_inventory,
    )
    from services.market_intel.candidate_queue_review_decision_writer_run_closeout import (
        build_candidate_queue_review_decision_writer_run_closeout,
    )

    fixture = _build_review_decision_writer_receipt_fixture(
        "sample-batch-review-completion-archive"
    )
    archive_evidence = {
        **fixture["operator_evidence"],
        "review_state_receipt_artifact_path": (
            "artifacts/market_intel/review-state-receipt.json"
        ),
        "review_state_closeout_artifact_path": (
            "artifacts/market_intel/review-state-closeout.json"
        ),
        "post_closeout_inventory_artifact_path": (
            "artifacts/market_intel/post-closeout-inventory.json"
        ),
        "review_completion_archive_path": (
            "artifacts/market_intel/review-completion-archive.json"
        ),
        "operator_confirmed_review_state_closeout_next": True,
        "operator_confirmed_post_closeout_inventory_read_only": True,
        "operator_confirmed_review_completion_archive": True,
        "operator_confirmed_archive_is_read_only": True,
        "operator_confirmed_no_scheduler_attach": True,
        "operator_confirmed_no_api_db_write": True,
    }
    closeout = build_candidate_queue_review_decision_writer_run_closeout(
        transaction_preview=fixture["transaction"],
        run_receipt=fixture["receipt"],
        operator_evidence=archive_evidence,
    )
    live_inventory = {
        "mode": "live_db_inventory_loaded",
        "summary_ready": True,
        "read_only_query_executed": True,
        "database_connection_opened": True,
        "database_write_executed": False,
        "database_commit_executed": False,
        "migration_executed": False,
        "external_network_executed": False,
        "scheduler_attached": False,
        "total_rows": 1,
        "table_statuses": [
            {
                "table": "market_alert_review_queue",
                "exists": True,
                "row_count": 1,
                "status": "loaded",
            }
        ],
    }
    inventory = build_candidate_queue_review_decision_post_closeout_inventory(
        transaction_preview=fixture["transaction"],
        run_closeout=closeout,
        postwrite_smoke=fixture["postwrite_smoke_result"],
        live_db_inventory=live_inventory,
        operator_evidence=archive_evidence,
        execute_requested=True,
    )
    archive = build_candidate_queue_review_completion_archive(
        transaction_preview=fixture["transaction"],
        run_receipt=fixture["receipt"],
        run_closeout=closeout,
        post_closeout_inventory=inventory,
        operator_evidence=archive_evidence,
        execute_requested=True,
    )
    token_leak = build_candidate_queue_review_completion_archive(
        transaction_preview=fixture["transaction"],
        run_receipt=fixture["receipt"],
        run_closeout=closeout,
        post_closeout_inventory=inventory,
        operator_evidence={
            **archive_evidence,
            "approval_token": TEST_APPROVAL_TOKEN,
        },
        execute_requested=True,
    )

    assert archive["mode"] == "candidate_queue_review_completion_archive_preview"
    assert archive["target_operation"] == "archive_review_completion_evidence"
    assert archive["review_completion_archive_ready"] is True
    assert archive["archive_manifest_ready"] is True
    assert archive["ready_for_api_review_state_update"] is False
    assert archive["ready_for_api_database_write"] is False
    assert archive["ready_for_scheduler_attach"] is False
    assert archive["api_writes_file"] is False
    assert archive["api_executes_cli"] is False
    assert archive["api_reads_approval_token"] is False
    assert archive["api_writes_database"] is False
    assert archive["api_updates_review_state"] is False
    assert archive["archive_file_written"] is False
    assert archive["archive_record_written"] is False
    assert archive["archive_manifest_written"] is False
    assert archive["review_state_update_executed"] is False
    assert archive["database_write_executed"] is False
    assert archive["database_commit_executed"] is False
    assert archive["scheduler_attached"] is False
    assert archive["expected_dedupe_keys"] == fixture["receipt"][
        "expected_dedupe_keys"
    ]
    assert archive["found_dedupe_keys"] == fixture["receipt"][
        "expected_dedupe_keys"
    ]
    assert archive["row_summary_count"] == 1
    assert archive["blocked_reasons"] == []
    assert "review_completion_archive_preview_only" in archive["safe_boundaries"]
    assert token_leak["review_completion_archive_ready"] is False
    assert token_leak["operator_archive_summary"][
        "approval_token_submitted_to_api"
    ] is True
    assert "archive_no_approval_token_submitted_to_api" in token_leak[
        "blocked_reasons"
    ]
    assert TEST_APPROVAL_TOKEN not in json.dumps(
        token_leak,
        ensure_ascii=False,
        sort_keys=True,
    )


def test_candidate_queue_review_archive_summary_blocks_llm_and_writes():
    from services.market_intel.candidate_queue_review_archive_summary import (
        build_candidate_queue_review_archive_summary,
    )
    from services.market_intel.candidate_queue_review_completion_archive import (
        build_candidate_queue_review_completion_archive,
    )
    from services.market_intel.candidate_queue_review_decision_post_closeout_inventory import (
        build_candidate_queue_review_decision_post_closeout_inventory,
    )
    from services.market_intel.candidate_queue_review_decision_writer_run_closeout import (
        build_candidate_queue_review_decision_writer_run_closeout,
    )

    fixture = _build_review_decision_writer_receipt_fixture(
        "sample-batch-review-archive-summary"
    )
    summary_evidence = {
        **fixture["operator_evidence"],
        "review_state_receipt_artifact_path": (
            "artifacts/market_intel/review-state-receipt.json"
        ),
        "review_state_closeout_artifact_path": (
            "artifacts/market_intel/review-state-closeout.json"
        ),
        "post_closeout_inventory_artifact_path": (
            "artifacts/market_intel/post-closeout-inventory.json"
        ),
        "review_completion_archive_path": (
            "artifacts/market_intel/review-completion-archive.json"
        ),
        "archive_summary_artifact_path": (
            "artifacts/market_intel/review-archive-summary.json"
        ),
        "operator_confirmed_review_state_closeout_next": True,
        "operator_confirmed_post_closeout_inventory_read_only": True,
        "operator_confirmed_review_completion_archive": True,
        "operator_confirmed_archive_is_read_only": True,
        "operator_confirmed_ai_summary_review": True,
        "operator_confirmed_summary_is_read_only": True,
        "operator_confirmed_no_llm_call": True,
        "operator_confirmed_no_telegram_dispatch": True,
        "operator_confirmed_no_scheduler_attach": True,
        "operator_confirmed_no_api_db_write": True,
    }
    closeout = build_candidate_queue_review_decision_writer_run_closeout(
        transaction_preview=fixture["transaction"],
        run_receipt=fixture["receipt"],
        operator_evidence=summary_evidence,
    )
    inventory = build_candidate_queue_review_decision_post_closeout_inventory(
        transaction_preview=fixture["transaction"],
        run_closeout=closeout,
        postwrite_smoke=fixture["postwrite_smoke_result"],
        live_db_inventory={
            "mode": "live_db_inventory_loaded",
            "summary_ready": True,
            "read_only_query_executed": True,
            "database_connection_opened": True,
            "database_write_executed": False,
            "database_commit_executed": False,
            "migration_executed": False,
            "external_network_executed": False,
            "scheduler_attached": False,
            "table_statuses": [
                {
                    "table": "market_alert_review_queue",
                    "exists": True,
                    "row_count": 1,
                    "status": "loaded",
                }
            ],
        },
        operator_evidence=summary_evidence,
        execute_requested=True,
    )
    archive = build_candidate_queue_review_completion_archive(
        transaction_preview=fixture["transaction"],
        run_receipt=fixture["receipt"],
        run_closeout=closeout,
        post_closeout_inventory=inventory,
        operator_evidence=summary_evidence,
        execute_requested=True,
    )
    summary = build_candidate_queue_review_archive_summary(
        review_completion_archive=archive,
        operator_evidence=summary_evidence,
        execute_requested=True,
    )
    token_leak = build_candidate_queue_review_archive_summary(
        review_completion_archive=archive,
        operator_evidence={
            **summary_evidence,
            "approval_token": TEST_APPROVAL_TOKEN,
        },
        execute_requested=True,
    )

    assert summary["mode"] == "candidate_queue_review_archive_summary_preview"
    assert summary["target_operation"] == "prepare_archive_summary_input"
    assert summary["archive_summary_ready"] is True
    assert summary["summary_input_ready"] is True
    assert summary["ready_for_ai_summary_review"] is True
    assert summary["ready_for_ai_summary_generation"] is False
    assert summary["ready_for_llm_call"] is False
    assert summary["ready_for_telegram_dispatch"] is False
    assert summary["ai_summary_generated"] is False
    assert summary["llm_call_executed"] is False
    assert summary["ollama_call_executed"] is False
    assert summary["gemini_call_executed"] is False
    assert summary["telegram_dispatched"] is False
    assert summary["summary_file_written"] is False
    assert summary["summary_record_written"] is False
    assert summary["summary_manifest_written"] is False
    assert summary["database_write_executed"] is False
    assert summary["database_commit_executed"] is False
    assert summary["review_state_update_executed"] is False
    assert summary["scheduler_attached"] is False
    assert summary["expected_dedupe_keys"] == fixture["receipt"][
        "expected_dedupe_keys"
    ]
    assert summary["summary_sections"]
    assert summary["blocked_reasons"] == []
    assert "do_not_call_llm_from_archive_summary_gate" in summary[
        "safe_boundaries"
    ]
    assert "ollama_first_only_for_future_llm_summary" in summary[
        "safe_boundaries"
    ]
    assert token_leak["archive_summary_ready"] is False
    assert token_leak["operator_summary_review"][
        "approval_token_submitted_to_api"
    ] is True
    assert "archive_summary_no_approval_token_submitted_to_api" in token_leak[
        "blocked_reasons"
    ]
    assert TEST_APPROVAL_TOKEN not in json.dumps(
        token_leak,
        ensure_ascii=False,
        sort_keys=True,
    )


def test_candidate_queue_review_ai_summary_preflight_is_ollama_first_preview():
    from services.market_intel.candidate_queue_review_ai_summary_preflight import (
        build_candidate_queue_review_ai_summary_preflight,
    )
    from services.market_intel.candidate_queue_review_archive_summary import (
        build_candidate_queue_review_archive_summary,
    )
    from services.market_intel.candidate_queue_review_completion_archive import (
        build_candidate_queue_review_completion_archive,
    )
    from services.market_intel.candidate_queue_review_decision_post_closeout_inventory import (
        build_candidate_queue_review_decision_post_closeout_inventory,
    )
    from services.market_intel.candidate_queue_review_decision_writer_run_closeout import (
        build_candidate_queue_review_decision_writer_run_closeout,
    )

    fixture = _build_review_decision_writer_receipt_fixture(
        "sample-batch-review-ai-summary-preflight"
    )
    preflight_evidence = {
        **fixture["operator_evidence"],
        "review_state_receipt_artifact_path": (
            "artifacts/market_intel/review-state-receipt.json"
        ),
        "review_state_closeout_artifact_path": (
            "artifacts/market_intel/review-state-closeout.json"
        ),
        "post_closeout_inventory_artifact_path": (
            "artifacts/market_intel/post-closeout-inventory.json"
        ),
        "review_completion_archive_path": (
            "artifacts/market_intel/review-completion-archive.json"
        ),
        "archive_summary_artifact_path": (
            "artifacts/market_intel/review-archive-summary.json"
        ),
        "ai_summary_preflight_artifact_path": (
            "artifacts/market_intel/ai-summary-preflight.json"
        ),
        "operator_confirmed_review_state_closeout_next": True,
        "operator_confirmed_post_closeout_inventory_read_only": True,
        "operator_confirmed_review_completion_archive": True,
        "operator_confirmed_archive_is_read_only": True,
        "operator_confirmed_ai_summary_review": True,
        "operator_confirmed_summary_is_read_only": True,
        "operator_confirmed_ai_summary_preflight": True,
        "operator_confirmed_ollama_first": True,
        "operator_confirmed_gemini_backup_only": True,
        "operator_confirmed_no_llm_call": True,
        "operator_confirmed_no_telegram_dispatch": True,
        "operator_confirmed_no_scheduler_attach": True,
        "operator_confirmed_no_api_db_write": True,
    }
    closeout = build_candidate_queue_review_decision_writer_run_closeout(
        transaction_preview=fixture["transaction"],
        run_receipt=fixture["receipt"],
        operator_evidence=preflight_evidence,
    )
    inventory = build_candidate_queue_review_decision_post_closeout_inventory(
        transaction_preview=fixture["transaction"],
        run_closeout=closeout,
        postwrite_smoke=fixture["postwrite_smoke_result"],
        live_db_inventory={
            "mode": "live_db_inventory_loaded",
            "summary_ready": True,
            "read_only_query_executed": True,
            "database_connection_opened": True,
            "database_write_executed": False,
            "database_commit_executed": False,
            "migration_executed": False,
            "external_network_executed": False,
            "scheduler_attached": False,
            "table_statuses": [
                {
                    "table": "market_alert_review_queue",
                    "exists": True,
                    "row_count": 1,
                    "status": "loaded",
                }
            ],
        },
        operator_evidence=preflight_evidence,
        execute_requested=True,
    )
    archive = build_candidate_queue_review_completion_archive(
        transaction_preview=fixture["transaction"],
        run_receipt=fixture["receipt"],
        run_closeout=closeout,
        post_closeout_inventory=inventory,
        operator_evidence=preflight_evidence,
        execute_requested=True,
    )
    archive_summary = build_candidate_queue_review_archive_summary(
        review_completion_archive=archive,
        operator_evidence=preflight_evidence,
        execute_requested=True,
    )
    preflight = build_candidate_queue_review_ai_summary_preflight(
        archive_summary=archive_summary,
        operator_evidence=preflight_evidence,
        execute_requested=True,
    )
    token_leak = build_candidate_queue_review_ai_summary_preflight(
        archive_summary=archive_summary,
        operator_evidence={
            **preflight_evidence,
            "approval_token": TEST_APPROVAL_TOKEN,
        },
        execute_requested=True,
    )

    assert preflight["mode"] == "candidate_queue_review_ai_summary_preflight_preview"
    assert preflight["target_operation"] == "preflight_ollama_first_ai_summary"
    assert preflight["ai_summary_preflight_ready"] is True
    assert preflight["ready_for_manual_ollama_summary_run"] is True
    assert preflight["ready_for_ai_summary_generation"] is False
    assert preflight["ready_for_llm_call"] is False
    assert preflight["ready_for_telegram_dispatch"] is False
    assert preflight["api_reads_approval_token"] is False
    assert preflight["api_writes_file"] is False
    assert preflight["api_writes_database"] is False
    assert preflight["api_updates_review_state"] is False
    assert preflight["summary_file_written"] is False
    assert preflight["summary_record_written"] is False
    assert preflight["summary_manifest_written"] is False
    assert preflight["ai_summary_generated"] is False
    assert preflight["llm_call_executed"] is False
    assert preflight["ollama_call_executed"] is False
    assert preflight["gemini_call_executed"] is False
    assert preflight["telegram_dispatched"] is False
    assert preflight["database_write_executed"] is False
    assert preflight["database_commit_executed"] is False
    assert preflight["scheduler_attached"] is False
    assert preflight["blocked_reasons"] == []
    assert preflight["model_route_policy"]["primary_policy"] == "ollama_first"
    assert len(preflight["model_route_policy"]["primary_cascade"]) == 3
    assert (
        preflight["model_route_policy"]["fallback_policy"]
        == "gemini_backup_only_after_ollama_cascade_failure"
    )
    assert (
        preflight["model_route_policy"]["app_host_forbidden_as_ollama_node"]
        == "192.168.0.188"
    )
    assert "ollama_cascade_must_use_gcp_a_then_gcp_b_then_111" in preflight[
        "safe_boundaries"
    ]
    assert "host_188_forbidden_as_ollama_node" in preflight["safe_boundaries"]
    assert "do_not_call_llm_from_ai_summary_preflight" in preflight[
        "safe_boundaries"
    ]
    assert token_leak["ai_summary_preflight_ready"] is False
    assert token_leak["operator_ai_summary_preflight"][
        "approval_token_submitted_to_api"
    ] is True
    assert "ai_summary_preflight_no_approval_token_submitted_to_api" in token_leak[
        "blocked_reasons"
    ]
    assert TEST_APPROVAL_TOKEN not in json.dumps(
        token_leak,
        ensure_ascii=False,
        sort_keys=True,
    )


def test_candidate_queue_review_ai_summary_run_package_is_manual_only():
    from services.market_intel.candidate_queue_review_ai_summary_preflight import (
        build_candidate_queue_review_ai_summary_preflight,
    )
    from services.market_intel.candidate_queue_review_ai_summary_run_package import (
        build_candidate_queue_review_ai_summary_run_package,
    )
    from services.market_intel.candidate_queue_review_archive_summary import (
        build_candidate_queue_review_archive_summary,
    )
    from services.market_intel.candidate_queue_review_completion_archive import (
        build_candidate_queue_review_completion_archive,
    )
    from services.market_intel.candidate_queue_review_decision_post_closeout_inventory import (
        build_candidate_queue_review_decision_post_closeout_inventory,
    )
    from services.market_intel.candidate_queue_review_decision_writer_run_closeout import (
        build_candidate_queue_review_decision_writer_run_closeout,
    )

    fixture = _build_review_decision_writer_receipt_fixture(
        "sample-batch-review-ai-summary-run-package"
    )
    run_package_evidence = {
        **fixture["operator_evidence"],
        "review_state_receipt_artifact_path": (
            "artifacts/market_intel/review-state-receipt.json"
        ),
        "review_state_closeout_artifact_path": (
            "artifacts/market_intel/review-state-closeout.json"
        ),
        "post_closeout_inventory_artifact_path": (
            "artifacts/market_intel/post-closeout-inventory.json"
        ),
        "review_completion_archive_path": (
            "artifacts/market_intel/review-completion-archive.json"
        ),
        "archive_summary_artifact_path": (
            "artifacts/market_intel/review-archive-summary.json"
        ),
        "ai_summary_preflight_artifact_path": (
            "artifacts/market_intel/ai-summary-preflight.json"
        ),
        "ai_summary_run_package_artifact_path": (
            "artifacts/market_intel/ai-summary-run-package.json"
        ),
        "ai_summary_output_artifact_path": (
            "artifacts/market_intel/ai-summary-output.json"
        ),
        "operator_confirmed_review_state_closeout_next": True,
        "operator_confirmed_post_closeout_inventory_read_only": True,
        "operator_confirmed_review_completion_archive": True,
        "operator_confirmed_archive_is_read_only": True,
        "operator_confirmed_ai_summary_review": True,
        "operator_confirmed_summary_is_read_only": True,
        "operator_confirmed_ai_summary_preflight": True,
        "operator_confirmed_ai_summary_run_package": True,
        "operator_confirmed_ollama_first": True,
        "operator_confirmed_gemini_backup_only": True,
        "operator_confirmed_manual_llm_only": True,
        "operator_confirmed_no_api_llm_call": True,
        "operator_confirmed_no_llm_call": True,
        "operator_confirmed_no_telegram_dispatch": True,
        "operator_confirmed_no_scheduler_attach": True,
        "operator_confirmed_no_api_db_write": True,
    }
    closeout = build_candidate_queue_review_decision_writer_run_closeout(
        transaction_preview=fixture["transaction"],
        run_receipt=fixture["receipt"],
        operator_evidence=run_package_evidence,
    )
    inventory = build_candidate_queue_review_decision_post_closeout_inventory(
        transaction_preview=fixture["transaction"],
        run_closeout=closeout,
        postwrite_smoke=fixture["postwrite_smoke_result"],
        live_db_inventory={
            "mode": "live_db_inventory_loaded",
            "summary_ready": True,
            "read_only_query_executed": True,
            "database_connection_opened": True,
            "database_write_executed": False,
            "database_commit_executed": False,
            "migration_executed": False,
            "external_network_executed": False,
            "scheduler_attached": False,
            "table_statuses": [
                {
                    "table": "market_alert_review_queue",
                    "exists": True,
                    "row_count": 1,
                    "status": "loaded",
                }
            ],
        },
        operator_evidence=run_package_evidence,
        execute_requested=True,
    )
    archive = build_candidate_queue_review_completion_archive(
        transaction_preview=fixture["transaction"],
        run_receipt=fixture["receipt"],
        run_closeout=closeout,
        post_closeout_inventory=inventory,
        operator_evidence=run_package_evidence,
        execute_requested=True,
    )
    archive_summary = build_candidate_queue_review_archive_summary(
        review_completion_archive=archive,
        operator_evidence=run_package_evidence,
        execute_requested=True,
    )
    preflight = build_candidate_queue_review_ai_summary_preflight(
        archive_summary=archive_summary,
        operator_evidence=run_package_evidence,
        execute_requested=True,
    )
    run_package = build_candidate_queue_review_ai_summary_run_package(
        archive_summary=archive_summary,
        ai_summary_preflight=preflight,
        operator_evidence=run_package_evidence,
        execute_requested=True,
    )
    token_leak = build_candidate_queue_review_ai_summary_run_package(
        archive_summary=archive_summary,
        ai_summary_preflight=preflight,
        operator_evidence={
            **run_package_evidence,
            "approval_token": TEST_APPROVAL_TOKEN,
        },
        execute_requested=True,
    )

    assert run_package["mode"] == "candidate_queue_review_ai_summary_run_package_preview"
    assert (
        run_package["target_operation"]
        == "package_ollama_first_ai_summary_manual_run"
    )
    assert run_package["ai_summary_run_package_ready"] is True
    assert run_package["ready_for_manual_ollama_summary_run"] is True
    assert run_package["ready_for_ai_summary_generation"] is False
    assert run_package["ready_for_llm_call"] is False
    assert run_package["ready_for_telegram_dispatch"] is False
    assert run_package["api_executes_llm"] is False
    assert run_package["api_reads_approval_token"] is False
    assert run_package["api_writes_file"] is False
    assert run_package["api_writes_database"] is False
    assert run_package["api_updates_review_state"] is False
    assert run_package["run_package_file_written"] is False
    assert run_package["summary_file_written"] is False
    assert run_package["summary_record_written"] is False
    assert run_package["summary_manifest_written"] is False
    assert run_package["ai_summary_generated"] is False
    assert run_package["llm_call_executed"] is False
    assert run_package["ollama_call_executed"] is False
    assert run_package["gemini_call_executed"] is False
    assert run_package["telegram_dispatched"] is False
    assert run_package["database_write_executed"] is False
    assert run_package["database_commit_executed"] is False
    assert run_package["scheduler_attached"] is False
    assert run_package["blocked_reasons"] == []
    assert run_package["prompt_contract"]["contract_version"] == (
        "market_intel_ai_summary_prompt_v1"
    )
    assert run_package["summary_output_schema"]["schema_version"] == (
        "market_intel_ai_summary_v1"
    )
    assert "evidence_refs" in run_package["summary_output_schema"][
        "required_fields"
    ]
    assert run_package["model_route_policy"]["primary_policy"] == "ollama_first"
    assert "manual_ollama_summary_run_only" in run_package["safe_boundaries"]
    assert "do_not_call_llm_from_ai_summary_run_package" in run_package[
        "safe_boundaries"
    ]
    assert token_leak["ai_summary_run_package_ready"] is False
    assert token_leak["operator_ai_summary_run_package"][
        "approval_token_submitted_to_api"
    ] is True
    assert "ai_summary_run_package_no_approval_token_submitted_to_api" in token_leak[
        "blocked_reasons"
    ]
    assert TEST_APPROVAL_TOKEN not in json.dumps(
        token_leak,
        ensure_ascii=False,
        sort_keys=True,
    )


def test_candidate_queue_writer_preflight_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.post(
        "/api/market_intel/manual_sample_review/candidate_queue_writer_preflight",
        json={
            "sample_result": {
                "batch_id": "sample-batch-18",
                "platform_code": "momo",
                "source_key": "homepage",
                "source_url": "https://www.momoshop.com.tw/",
                "status": "fetched",
                "status_code": 200,
                "content_length": 1700,
                "page_hash": "f" * 64,
                "title": "MOMO 活動",
                "diagnostics": {
                    "link_count": 1,
                    "same_host_link_count": 1,
                    "campaign_link_candidates": [
                        {
                            "confidence_band": "high",
                            "score": 94,
                            "url": "https://www.momoshop.com.tw/activity/sample",
                            "text": "品牌活動",
                        },
                    ],
                },
            }
        },
    )
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "candidate_queue_writer_preflight_planned"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["execute_requested"] is False
    assert data["read_only_query_executed"] is False
    assert data["database_connection_opened"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["statement_count"] == 1
    assert data["payload_column_map"]["metadata_json_preview"] == "metadata_json"


def test_candidate_queue_writer_status_route_never_leaks_approval_token(monkeypatch):
    from routes.market_intel_routes import market_intel_bp

    monkeypatch.setenv("MARKET_INTEL_QUEUE_WRITE_APPROVAL", TEST_APPROVAL_TOKEN)

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.post(
        "/api/market_intel/manual_sample_review/candidate_queue_writer_status"
        "?execute=true&apply_real_write=true",
        json={
            "sample_result": {
                "batch_id": "sample-batch-14",
                "platform_code": "pchome",
                "source_key": "homepage",
                "source_url": "https://24h.pchome.com.tw/",
                "status": "fetched",
                "status_code": 200,
                "content_length": 1800,
                "page_hash": "b" * 64,
                "title": "PChome 活動",
                "diagnostics": {
                    "link_count": 1,
                    "same_host_link_count": 1,
                    "campaign_link_candidates": [
                        {
                            "confidence_band": "medium",
                            "score": 74,
                            "url": "https://24h.pchome.com.tw/activity/sample",
                            "text": "活動頁",
                        },
                    ],
                },
            }
        },
    )
    data = response.get_json()
    payload = json.dumps(data, ensure_ascii=False, sort_keys=True)

    assert response.status_code == 200
    assert data["mode"] == "candidate_queue_writer_cli_blocked"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["execute_requested"] is True
    assert data["apply_real_write_requested"] is True
    assert data["approval_token_present"] is False
    assert data["approval_token_valid"] is False
    assert data["approval_token_secret_configured"] is True
    assert data["ready_for_real_write"] is False
    assert data["writes_executed"] is False
    assert data["would_write_database"] is False
    assert data["database_connection_opened"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["transaction_preview_summary"]["statement_count"] == 1
    assert "approval_token_present" in data["blocked_reasons"]
    assert "approval_token_valid" in data["blocked_reasons"]
    assert "approval_token_hint" not in payload
    assert TEST_APPROVAL_TOKEN not in payload
    assert "APPROVED_MARKET_INTEL_QUEUE_WRITE" not in payload


def test_candidate_queue_writer_status_blocks_invalid_payload():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.post(
        "/api/market_intel/manual_sample_review/candidate_queue_writer_status",
        data="not-json",
        content_type="application/json",
    )
    data = response.get_json()

    assert response.status_code == 400
    assert data["mode"] == "candidate_queue_writer_cli_blocked"
    assert data["ready_for_real_write"] is False
    assert data["writes_executed"] is False
    assert data["transaction_preview_summary"]["statement_count"] == 0
    assert "transaction_preview_created" in data["blocked_reasons"]


def test_candidate_queue_writer_postwrite_smoke_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_writer_postwrite_smoke",
        json={
            "sample_result": {
                "batch_id": "sample-batch-22",
                "platform_code": "momo",
                "source_key": "homepage",
                "source_url": "https://www.momoshop.com.tw/",
                "status": "fetched",
                "status_code": 200,
                "content_length": 1700,
                "page_hash": "4" * 64,
                "title": "MOMO 活動",
                "diagnostics": {
                    "link_count": 1,
                    "same_host_link_count": 1,
                    "campaign_link_candidates": [
                        {
                            "confidence_band": "high",
                            "score": 94,
                            "url": "https://www.momoshop.com.tw/activity/sample",
                            "text": "品牌活動",
                        },
                    ],
                },
            }
        },
    )
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "candidate_queue_writer_postwrite_smoke_planned"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["execute_requested"] is False
    assert data["read_only_query_executed"] is False
    assert data["database_connection_opened"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["expected_dedupe_key_count"] == 1
    assert data["postwrite_smoke_passed"] is False


def test_candidate_queue_writer_operator_drill_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_writer_operator_drill",
        json={
            "sample_result": {
                "batch_id": "sample-batch-24",
                "platform_code": "momo",
                "source_key": "homepage",
                "source_url": "https://www.momoshop.com.tw/",
                "status": "fetched",
                "status_code": 200,
                "content_length": 1700,
                "page_hash": "6" * 64,
                "title": "MOMO 活動",
                "diagnostics": {
                    "link_count": 1,
                    "same_host_link_count": 1,
                    "campaign_link_candidates": [
                        {
                            "confidence_band": "high",
                            "score": 94,
                            "url": "https://www.momoshop.com.tw/activity/sample",
                            "text": "品牌活動",
                        },
                    ],
                },
            }
        },
    )
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "candidate_queue_writer_operator_drill_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["operator_drill_ready"] is True
    assert data["api_executes_cli"] is False
    assert data["api_reads_approval_token"] is False
    assert data["api_writes_database"] is False
    assert data["database_connection_opened"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["statement_summary"]["statement_count"] == 1
    assert "backup_verified_by_operator" in data["blocked_reasons"]


def test_candidate_queue_writer_run_package_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_writer_run_package",
        json={
            "sample_result": {
                "batch_id": "sample-batch-26",
                "platform_code": "momo",
                "source_key": "homepage",
                "source_url": "https://www.momoshop.com.tw/",
                "status": "fetched",
                "status_code": 200,
                "content_length": 1700,
                "page_hash": "8" * 64,
                "title": "MOMO 活動",
                "diagnostics": {
                    "link_count": 1,
                    "same_host_link_count": 1,
                    "campaign_link_candidates": [
                        {
                            "confidence_band": "high",
                            "score": 94,
                            "url": "https://www.momoshop.com.tw/activity/sample",
                            "text": "品牌活動",
                        },
                    ],
                },
            }
        },
    )
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "candidate_queue_writer_run_package_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["package_ready"] is True
    assert data["package_artifact_created"] is False
    assert data["api_writes_file"] is False
    assert data["api_executes_cli"] is False
    assert data["api_reads_approval_token"] is False
    assert data["api_writes_database"] is False
    assert data["database_connection_opened"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["payload_manifest"]["payload_count"] == 1
    assert len(data["command_bundle"]) == 5
    assert "real_sample_payload_saved_by_operator" in data["blocked_reasons"]


def test_candidate_queue_writer_run_readiness_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_writer_run_readiness",
        json={
            "sample_result": {
                "batch_id": "sample-batch-28",
                "platform_code": "momo",
                "source_key": "homepage",
                "source_url": "https://www.momoshop.com.tw/",
                "status": "fetched",
                "status_code": 200,
                "content_length": 1700,
                "page_hash": "a" * 64,
                "title": "MOMO 活動",
                "diagnostics": {
                    "link_count": 1,
                    "same_host_link_count": 1,
                    "campaign_link_candidates": [
                        {
                            "confidence_band": "high",
                            "score": 94,
                            "url": "https://www.momoshop.com.tw/activity/sample",
                            "text": "品牌活動",
                        },
                    ],
                },
            },
            "operator_evidence": {
                "reviewed_sample_json_path": "artifacts/market_intel/reviewed.json",
                "backup_artifact_path": "scripts/tools/backups/backup.zip",
                "preflight_artifact_path": "artifacts/market_intel/preflight.json",
                "migration_live_smoke_passed": True,
                "operator_acknowledged_shell_only_token": True,
            },
        },
    )
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "candidate_queue_writer_run_readiness_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["ready_for_cli_operator_run"] is True
    assert data["ready_for_api_database_write"] is False
    assert data["api_executes_cli"] is False
    assert data["api_reads_approval_token"] is False
    assert data["api_writes_file"] is False
    assert data["api_writes_database"] is False
    assert data["database_connection_opened"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["run_package_summary"]["payload_count"] == 1
    assert data["operator_evidence_summary"]["artifact_path_count"] == 3
    assert data["blocked_reasons"] == []


def test_candidate_queue_writer_run_receipt_preview_reviews_operator_artifacts():
    from services.market_intel.candidate_queue_writer_cli import (
        build_candidate_queue_writer_cli_plan,
    )
    from services.market_intel.candidate_queue_writer_operator_drill import (
        build_candidate_queue_writer_operator_drill,
    )
    from services.market_intel.candidate_queue_writer_postwrite_smoke import (
        build_candidate_queue_writer_postwrite_smoke,
    )
    from services.market_intel.candidate_queue_writer_preflight import (
        build_candidate_queue_writer_preflight,
    )
    from services.market_intel.candidate_queue_writer_run_package import (
        build_candidate_queue_writer_run_package,
    )
    from services.market_intel.candidate_queue_writer_run_readiness import (
        build_candidate_queue_writer_run_readiness,
    )
    from services.market_intel.candidate_queue_writer_run_receipt import (
        build_candidate_queue_writer_run_receipt,
    )

    sample_result = _market_intel_sample_result("sample-batch-29")
    transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
        sample_result=sample_result
    )
    expected_key = transaction["statements"][0]["lookup"]["dedupe_key"]
    preflight = build_candidate_queue_writer_preflight(
        transaction_preview=transaction,
        execute_requested=False,
    )
    writer_status = build_candidate_queue_writer_cli_plan(
        transaction_preview=transaction,
        writer_preflight=preflight,
    )
    postwrite_smoke = build_candidate_queue_writer_postwrite_smoke(
        transaction_preview=transaction,
        execute_requested=False,
    )
    operator_drill = build_candidate_queue_writer_operator_drill(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=postwrite_smoke,
    )
    run_package = build_candidate_queue_writer_run_package(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=postwrite_smoke,
        operator_drill=operator_drill,
    )
    operator_evidence = {
        "reviewed_sample_json_path": "artifacts/market_intel/reviewed.json",
        "backup_artifact_path": "scripts/tools/backups/backup.zip",
        "preflight_artifact_path": "artifacts/market_intel/preflight.json",
        "migration_live_smoke_passed": True,
        "operator_acknowledged_shell_only_token": True,
        "writer_output_json_path": "artifacts/market_intel/writer-output.json",
        "postwrite_smoke_json_path": "artifacts/market_intel/postwrite-smoke.json",
        "operator_confirmed_no_token_in_artifacts": True,
    }
    run_readiness = build_candidate_queue_writer_run_readiness(
        transaction_preview=transaction,
        writer_preflight=preflight,
        writer_status=writer_status,
        postwrite_smoke=postwrite_smoke,
        operator_drill=operator_drill,
        run_package=run_package,
        operator_evidence=operator_evidence,
    )
    writer_output = {
        "mode": "candidate_queue_writer_cli_executed",
        "exit_code": 0,
        "writes_executed": True,
        "would_write_database": True,
        "database_connection_opened": True,
        "explicit_transaction_opened": True,
        "database_write_executed": True,
        "database_commit_executed": True,
        "database_rollback_executed": False,
        "external_network_executed": False,
        "scheduler_attached": False,
        "inserted_count": 1,
        "skipped_count": 0,
        "affected_dedupe_keys": [expected_key],
        "skipped_dedupe_keys": [],
    }
    postwrite_smoke_result = {
        "mode": "candidate_queue_writer_postwrite_smoke_read_only",
        "postwrite_smoke_passed": True,
        "ready_for_operator_review": True,
        "read_only_query_executed": True,
        "database_connection_opened": True,
        "database_write_executed": False,
        "database_commit_executed": False,
        "external_network_executed": False,
        "scheduler_attached": False,
        "expected_dedupe_key_count": 1,
        "found_count": 1,
        "missing_count": 0,
        "found_dedupe_keys": [expected_key],
        "missing_dedupe_keys": [],
    }

    receipt = build_candidate_queue_writer_run_receipt(
        transaction_preview=transaction,
        run_readiness=run_readiness,
        writer_output=writer_output,
        postwrite_smoke_result=postwrite_smoke_result,
        operator_evidence=operator_evidence,
    )
    token_leak = build_candidate_queue_writer_run_receipt(
        transaction_preview=transaction,
        run_readiness=run_readiness,
        writer_output={**writer_output, "approval_token": TEST_APPROVAL_TOKEN},
        postwrite_smoke_result=postwrite_smoke_result,
        operator_evidence=operator_evidence,
    )

    assert receipt["mode"] == "candidate_queue_writer_run_receipt_preview"
    assert receipt["receipt_passed"] is True
    assert receipt["ready_for_next_manual_review"] is True
    assert receipt["ready_for_api_database_write"] is False
    assert receipt["ready_for_scheduler_attach"] is False
    assert receipt["api_executes_cli"] is False
    assert receipt["api_reads_approval_token"] is False
    assert receipt["api_writes_file"] is False
    assert receipt["database_connection_opened"] is False
    assert receipt["database_write_executed"] is False
    assert receipt["database_commit_executed"] is False
    assert receipt["scheduler_attached"] is False
    assert receipt["writer_output_summary"]["dedupe_keys_match_expected"] is True
    assert receipt["postwrite_smoke_summary"]["dedupe_keys_match_expected"] is True
    assert receipt["operator_evidence_summary"]["writer_output_json_path_recorded"] is True
    assert receipt["blocked_reasons"] == []
    assert token_leak["receipt_passed"] is False
    assert token_leak["writer_output_summary"]["approval_token_key_detected"] is True
    assert "writer_output_no_approval_token_key" in token_leak["blocked_reasons"]
    assert TEST_APPROVAL_TOKEN not in json.dumps(
        token_leak,
        ensure_ascii=False,
        sort_keys=True,
    )
    assert "do_not_echo_operator_receipt_payload" in receipt["safe_boundaries"]


def test_candidate_queue_writer_run_closeout_preview_blocks_api_write_and_tokens():
    from services.market_intel.candidate_queue_writer_run_closeout import (
        build_candidate_queue_writer_run_closeout,
    )
    from services.market_intel.candidate_queue_writer_run_receipt import (
        build_candidate_queue_writer_run_receipt,
    )

    fixture = _build_candidate_queue_writer_receipt_fixture(
        "sample-batch-closeout"
    )
    closeout_evidence = {
        **fixture["operator_evidence"],
        "closeout_artifact_path": "artifacts/market_intel/closeout.json",
        "operator_confirmed_queue_review_next": True,
        "operator_confirmed_no_scheduler_attach": True,
        "operator_confirmed_no_api_db_write": True,
        "closeout_notes": "manual closeout reviewed",
    }
    receipt = build_candidate_queue_writer_run_receipt(
        transaction_preview=fixture["transaction"],
        run_readiness=fixture["run_readiness"],
        writer_output=fixture["writer_output"],
        postwrite_smoke_result=fixture["postwrite_smoke_result"],
        operator_evidence=fixture["operator_evidence"],
    )
    closeout = build_candidate_queue_writer_run_closeout(
        transaction_preview=fixture["transaction"],
        run_receipt=receipt,
        operator_evidence=closeout_evidence,
    )
    token_leak = build_candidate_queue_writer_run_closeout(
        transaction_preview=fixture["transaction"],
        run_receipt=receipt,
        operator_evidence={
            **closeout_evidence,
            "approval_token": TEST_APPROVAL_TOKEN,
        },
    )

    assert closeout["mode"] == "candidate_queue_writer_run_closeout_preview"
    assert closeout["closeout_passed"] is True
    assert closeout["ready_for_next_manual_phase"] is True
    assert closeout["ready_for_api_database_write"] is False
    assert closeout["ready_for_scheduler_attach"] is False
    assert closeout["api_executes_cli"] is False
    assert closeout["api_reads_approval_token"] is False
    assert closeout["api_writes_file"] is False
    assert closeout["api_writes_database"] is False
    assert closeout["database_connection_opened"] is False
    assert closeout["database_write_executed"] is False
    assert closeout["database_commit_executed"] is False
    assert closeout["scheduler_attached"] is False
    assert closeout["blocked_reasons"] == []
    assert closeout["promotion_gate"]["requires_operator_approval"] is True
    assert "no_momo_db_lifecycle_change" in closeout["safe_boundaries"]
    assert token_leak["closeout_passed"] is False
    assert token_leak["operator_closeout_summary"][
        "approval_token_submitted_to_api"
    ] is True
    assert "closeout_no_approval_token_submitted_to_api" in token_leak[
        "blocked_reasons"
    ]
    assert TEST_APPROVAL_TOKEN not in json.dumps(
        token_leak,
        ensure_ascii=False,
        sort_keys=True,
    )


def test_candidate_queue_writer_run_receipt_route_accepts_inline_payload_no_write():
    from routes.market_intel_routes import market_intel_bp

    sample_result = _market_intel_sample_result("sample-batch-30")
    transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
        sample_result=sample_result
    )
    expected_key = transaction["statements"][0]["lookup"]["dedupe_key"]
    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_writer_run_receipt",
        json={
            "sample_result": sample_result,
            "operator_evidence": {
                "reviewed_sample_json_path": "artifacts/market_intel/reviewed.json",
                "backup_artifact_path": "scripts/tools/backups/backup.zip",
                "preflight_artifact_path": "artifacts/market_intel/preflight.json",
                "migration_live_smoke_passed": True,
                "operator_acknowledged_shell_only_token": True,
                "writer_output_json_path": "artifacts/market_intel/writer-output.json",
                "postwrite_smoke_json_path": "artifacts/market_intel/smoke.json",
                "operator_confirmed_no_token_in_artifacts": True,
            },
            "writer_output": {
                "mode": "candidate_queue_writer_cli_executed",
                "exit_code": 0,
                "writes_executed": True,
                "would_write_database": True,
                "database_connection_opened": True,
                "explicit_transaction_opened": True,
                "database_write_executed": True,
                "database_commit_executed": True,
                "database_rollback_executed": False,
                "external_network_executed": False,
                "scheduler_attached": False,
                "inserted_count": 1,
                "skipped_count": 0,
                "affected_dedupe_keys": [expected_key],
            },
            "postwrite_smoke_result": {
                "mode": "candidate_queue_writer_postwrite_smoke_read_only",
                "postwrite_smoke_passed": True,
                "ready_for_operator_review": True,
                "read_only_query_executed": True,
                "database_connection_opened": True,
                "database_write_executed": False,
                "database_commit_executed": False,
                "external_network_executed": False,
                "scheduler_attached": False,
                "expected_dedupe_key_count": 1,
                "found_count": 1,
                "missing_count": 0,
                "found_dedupe_keys": [expected_key],
                "missing_dedupe_keys": [],
            },
        },
    )
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "candidate_queue_writer_run_receipt_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["receipt_passed"] is True
    assert data["ready_for_api_database_write"] is False
    assert data["ready_for_scheduler_attach"] is False
    assert data["api_executes_cli"] is False
    assert data["api_reads_approval_token"] is False
    assert data["api_writes_file"] is False
    assert data["database_connection_opened"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["blocked_reasons"] == []


def test_candidate_queue_writer_run_closeout_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp

    fixture = _build_candidate_queue_writer_receipt_fixture(
        "sample-batch-closeout-route"
    )
    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_writer_run_closeout",
        json={
            "sample_result": fixture["sample_result"],
            "operator_evidence": {
                **fixture["operator_evidence"],
                "closeout_artifact_path": "artifacts/market_intel/closeout.json",
                "operator_confirmed_queue_review_next": True,
                "operator_confirmed_no_scheduler_attach": True,
                "operator_confirmed_no_api_db_write": True,
                "closeout_notes": "manual closeout reviewed",
            },
            "writer_output": fixture["writer_output"],
            "postwrite_smoke_result": fixture["postwrite_smoke_result"],
        },
    )
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "candidate_queue_writer_run_closeout_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["closeout_passed"] is True
    assert data["ready_for_next_manual_phase"] is True
    assert data["ready_for_api_database_write"] is False
    assert data["ready_for_scheduler_attach"] is False
    assert data["api_executes_cli"] is False
    assert data["api_reads_approval_token"] is False
    assert data["api_writes_file"] is False
    assert data["api_writes_database"] is False
    assert data["database_connection_opened"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["blocked_reasons"] == []


def test_candidate_queue_review_handoff_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp

    fixture = _build_candidate_queue_writer_receipt_fixture(
        "sample-batch-handoff-route"
    )
    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_handoff",
        json={
            "sample_result": fixture["sample_result"],
            "operator_evidence": {
                **fixture["operator_evidence"],
                "closeout_artifact_path": "artifacts/market_intel/closeout.json",
                "operator_confirmed_queue_review_next": True,
                "operator_confirmed_no_scheduler_attach": True,
                "operator_confirmed_no_api_db_write": True,
            },
            "writer_output": fixture["writer_output"],
            "postwrite_smoke_result": fixture["postwrite_smoke_result"],
        },
    )
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "candidate_queue_review_handoff_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["handoff_ready"] is True
    assert data["ready_for_manual_queue_review"] is True
    assert data["ready_for_api_database_write"] is False
    assert data["ready_for_scheduler_attach"] is False
    assert data["api_executes_cli"] is False
    assert data["api_reads_approval_token"] is False
    assert data["api_writes_database"] is False
    assert data["api_updates_review_state"] is False
    assert data["database_connection_opened"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["review_contract"]["expected_review_state"] == "needs_review"
    assert data["blocked_reasons"] == []


def test_candidate_queue_review_inventory_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp
    from routes.market_intel_review_routes import market_intel_review_bp

    fixture = _build_candidate_queue_writer_receipt_fixture(
        "sample-batch-review-inventory-route"
    )
    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    app.register_blueprint(market_intel_review_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    get_response = client.get(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_inventory"
    )
    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_inventory?execute=false",
        json={
            "sample_result": fixture["sample_result"],
            "operator_evidence": {
                **fixture["operator_evidence"],
                "closeout_artifact_path": "artifacts/market_intel/closeout.json",
                "operator_confirmed_queue_review_next": True,
                "operator_confirmed_no_scheduler_attach": True,
                "operator_confirmed_no_api_db_write": True,
                "operator_confirmed_inventory_read_only": True,
            },
            "writer_output": fixture["writer_output"],
            "postwrite_smoke_result": fixture["postwrite_smoke_result"],
        },
    )
    data = response.get_json()

    assert get_response.status_code == 405
    assert response.status_code == 200
    assert data["mode"] == "candidate_queue_review_inventory_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["execute_requested"] is False
    assert data["review_inventory_ready"] is False
    assert data["ready_for_human_decision_review"] is False
    assert data["ready_for_api_review_state_update"] is False
    assert data["ready_for_api_database_write"] is False
    assert data["ready_for_scheduler_attach"] is False
    assert data["api_executes_cli"] is False
    assert data["api_reads_approval_token"] is False
    assert data["api_writes_database"] is False
    assert data["api_updates_review_state"] is False
    assert data["read_only_query_executed"] is False
    assert data["database_connection_opened"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["expected_dedupe_keys"] == fixture["expected_keys"]
    assert "read_only_inventory_executed" in data["blocked_reasons"]
    assert "do_not_insert_missing_queue_row_from_api" in data["safe_boundaries"]


def test_candidate_queue_review_decision_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp
    from routes.market_intel_review_routes import market_intel_review_bp

    fixture = _build_candidate_queue_writer_receipt_fixture(
        "sample-batch-review-decision-route"
    )
    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    app.register_blueprint(market_intel_review_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    get_response = client.get(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision"
    )
    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision?execute=false",
        json={
            "sample_result": fixture["sample_result"],
            "operator_evidence": {
                **fixture["operator_evidence"],
                "closeout_artifact_path": "artifacts/market_intel/closeout.json",
                "operator_confirmed_queue_review_next": True,
                "operator_confirmed_no_scheduler_attach": True,
                "operator_confirmed_no_api_db_write": True,
                "operator_confirmed_inventory_read_only": True,
                "reviewer_id": "operator-a",
                "proposed_review_decision": "confirmed",
                "decision_notes": "manual review only",
                "operator_confirmed_manual_decision_only": True,
            },
            "writer_output": fixture["writer_output"],
            "postwrite_smoke_result": fixture["postwrite_smoke_result"],
        },
    )
    data = response.get_json()

    assert get_response.status_code == 405
    assert response.status_code == 200
    assert data["mode"] == "candidate_queue_review_decision_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["decision_ready"] is False
    assert data["ready_for_human_decision_record"] is False
    assert data["ready_for_api_review_state_update"] is False
    assert data["ready_for_api_database_write"] is False
    assert data["ready_for_scheduler_attach"] is False
    assert data["api_executes_cli"] is False
    assert data["api_reads_approval_token"] is False
    assert data["api_writes_database"] is False
    assert data["api_updates_review_state"] is False
    assert data["decision_record_written"] is False
    assert data["review_state_update_executed"] is False
    assert data["read_only_query_executed"] is False
    assert data["database_connection_opened"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["expected_dedupe_keys"] == fixture["expected_keys"]
    assert "review_inventory_ready" in data["blocked_reasons"]
    assert "do_not_update_review_state_from_api" in data["safe_boundaries"]


def test_candidate_queue_review_decision_approval_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp
    from routes.market_intel_review_routes import market_intel_review_bp

    fixture = _build_candidate_queue_writer_receipt_fixture(
        "sample-batch-review-decision-approval-route"
    )
    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    app.register_blueprint(market_intel_review_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    get_response = client.get(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_approval"
    )
    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_approval?execute=false",
        json={
            "sample_result": fixture["sample_result"],
            "operator_evidence": {
                **fixture["operator_evidence"],
                "closeout_artifact_path": "artifacts/market_intel/closeout.json",
                "operator_confirmed_queue_review_next": True,
                "operator_confirmed_no_scheduler_attach": True,
                "operator_confirmed_no_api_db_write": True,
                "operator_confirmed_inventory_read_only": True,
                "reviewer_id": "operator-a",
                "proposed_review_decision": "confirmed",
                "decision_notes": "manual review only",
                "operator_confirmed_manual_decision_only": True,
                "decision_approval_notes": "cli-only approval gate",
                "operator_confirmed_decision_payload_reviewed": True,
                "operator_confirmed_decision_apply_requires_cli": True,
                "operator_confirmed_review_state_update_is_not_api": True,
            },
            "writer_output": fixture["writer_output"],
            "postwrite_smoke_result": fixture["postwrite_smoke_result"],
        },
    )
    data = response.get_json()

    assert get_response.status_code == 405
    assert response.status_code == 200
    assert data["mode"] == "candidate_queue_review_decision_approval_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["approval_ready"] is False
    assert data["ready_for_review_state_transaction_preview"] is False
    assert data["ready_for_cli_decision_writer"] is False
    assert data["ready_for_api_review_state_update"] is False
    assert data["ready_for_api_database_write"] is False
    assert data["api_executes_cli"] is False
    assert data["api_reads_approval_token"] is False
    assert data["api_writes_database"] is False
    assert data["api_updates_review_state"] is False
    assert data["approval_record_written"] is False
    assert data["decision_record_written"] is False
    assert data["review_state_update_executed"] is False
    assert data["database_connection_opened"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["decision_update_preview"] == []
    assert "decision_preview_ready" in data["blocked_reasons"]
    assert "do_not_update_review_state_from_approval_api" in data[
        "safe_boundaries"
    ]


def test_candidate_queue_review_decision_transaction_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp
    from routes.market_intel_review_routes import market_intel_review_bp

    fixture = _build_candidate_queue_writer_receipt_fixture(
        "sample-batch-review-decision-transaction-route"
    )
    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    app.register_blueprint(market_intel_review_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    get_response = client.get(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_transaction"
    )
    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_transaction?execute=false",
        json={
            "sample_result": fixture["sample_result"],
            "operator_evidence": {
                **fixture["operator_evidence"],
                "closeout_artifact_path": "artifacts/market_intel/closeout.json",
                "operator_confirmed_queue_review_next": True,
                "operator_confirmed_no_scheduler_attach": True,
                "operator_confirmed_no_api_db_write": True,
                "operator_confirmed_inventory_read_only": True,
                "reviewer_id": "operator-a",
                "proposed_review_decision": "confirmed",
                "decision_notes": "manual review only",
                "operator_confirmed_manual_decision_only": True,
                "decision_approval_notes": "cli-only approval gate",
                "operator_confirmed_decision_payload_reviewed": True,
                "operator_confirmed_decision_apply_requires_cli": True,
                "operator_confirmed_review_state_update_is_not_api": True,
                "decision_transaction_notes": "shell-only transaction preview",
                "operator_confirmed_transaction_payload_reviewed": True,
                "operator_confirmed_cli_only_transaction": True,
            },
            "writer_output": fixture["writer_output"],
            "postwrite_smoke_result": fixture["postwrite_smoke_result"],
        },
    )
    data = response.get_json()

    assert get_response.status_code == 405
    assert response.status_code == 200
    assert data["mode"] == "candidate_queue_review_decision_transaction_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["transaction_preview_created"] is False
    assert data["transaction_ready"] is False
    assert data["ready_for_manual_shell_update_window"] is False
    assert data["ready_for_api_review_state_update"] is False
    assert data["ready_for_api_database_write"] is False
    assert data["ready_for_scheduler_attach"] is False
    assert data["api_executes_cli"] is False
    assert data["api_reads_approval_token"] is False
    assert data["api_writes_database"] is False
    assert data["api_updates_review_state"] is False
    assert data["approval_record_written"] is False
    assert data["decision_record_written"] is False
    assert data["review_state_update_executed"] is False
    assert data["database_connection_opened"] is False
    assert data["explicit_transaction_opened"] is False
    assert data["transaction_opened"] is False
    assert data["transaction_committed"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["statements"] == []
    assert "decision_approval_ready" in data["blocked_reasons"]
    assert "transaction_statements_present" in data["blocked_reasons"]
    assert "do_not_update_review_state_from_transaction_api" in data[
        "safe_boundaries"
    ]


def test_candidate_queue_review_decision_writer_status_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp
    from routes.market_intel_review_routes import market_intel_review_bp

    fixture = _build_candidate_queue_writer_receipt_fixture(
        "sample-batch-review-decision-writer-route"
    )
    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    app.register_blueprint(market_intel_review_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    get_response = client.get(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_status"
    )
    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_status?execute=true"
        "&apply_real_write=true",
        json={
            "sample_result": fixture["sample_result"],
            "operator_evidence": {
                **fixture["operator_evidence"],
                "closeout_artifact_path": "artifacts/market_intel/closeout.json",
                "operator_confirmed_queue_review_next": True,
                "operator_confirmed_no_scheduler_attach": True,
                "operator_confirmed_no_api_db_write": True,
                "operator_confirmed_inventory_read_only": True,
                "reviewer_id": "operator-a",
                "proposed_review_decision": "confirmed",
                "decision_notes": "manual review only",
                "operator_confirmed_manual_decision_only": True,
                "decision_approval_notes": "cli-only approval gate",
                "operator_confirmed_decision_payload_reviewed": True,
                "operator_confirmed_decision_apply_requires_cli": True,
                "operator_confirmed_review_state_update_is_not_api": True,
                "decision_transaction_notes": "shell-only transaction preview",
                "operator_confirmed_transaction_payload_reviewed": True,
                "operator_confirmed_cli_only_transaction": True,
            },
            "writer_output": fixture["writer_output"],
            "postwrite_smoke_result": fixture["postwrite_smoke_result"],
        },
    )
    data = response.get_json()

    assert get_response.status_code == 405
    assert response.status_code == 200
    assert data["mode"] == "candidate_queue_review_decision_writer_cli_blocked"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["execute_requested"] is True
    assert data["apply_real_write_requested"] is True
    assert data["approval_token_present"] is False
    assert data["approval_token_valid"] is False
    assert data["writer_implementation_enabled"] is False
    assert data["ready_for_real_write"] is False
    assert data["ready_for_api_review_state_update"] is False
    assert data["api_executes_cli"] is False
    assert data["api_reads_approval_token"] is False
    assert data["api_writes_database"] is False
    assert data["api_updates_review_state"] is False
    assert data["review_state_update_executed"] is False
    assert data["database_connection_opened"] is False
    assert data["database_session_created"] is False
    assert data["transaction_opened"] is False
    assert data["transaction_committed"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["writes_executed"] is False
    assert data["would_write_database"] is False
    assert "approval_token_present" in data["blocked_reasons"]
    assert "review_decision_writer_implementation_enabled" in data[
        "blocked_reasons"
    ]
    assert "do_not_execute_review_decision_writer_from_api" in data[
        "safe_boundaries"
    ]


def test_candidate_queue_review_decision_writer_preflight_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp
    from routes.market_intel_review_routes import market_intel_review_bp

    fixture = _build_candidate_queue_writer_receipt_fixture(
        "sample-batch-review-decision-preflight-route"
    )
    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    app.register_blueprint(market_intel_review_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    get_response = client.get(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_preflight"
    )
    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_preflight?execute=true"
        "&apply_real_write=true",
        json={
            "sample_result": fixture["sample_result"],
            "operator_evidence": {
                **fixture["operator_evidence"],
                "closeout_artifact_path": "artifacts/market_intel/closeout.json",
                "operator_confirmed_queue_review_next": True,
                "operator_confirmed_no_scheduler_attach": True,
                "operator_confirmed_no_api_db_write": True,
                "operator_confirmed_inventory_read_only": True,
                "reviewer_id": "operator-a",
                "proposed_review_decision": "confirmed",
                "decision_notes": "manual review only",
                "operator_confirmed_manual_decision_only": True,
                "decision_approval_notes": "cli-only approval gate",
                "operator_confirmed_decision_payload_reviewed": True,
                "operator_confirmed_decision_apply_requires_cli": True,
                "operator_confirmed_review_state_update_is_not_api": True,
                "decision_transaction_notes": "shell-only transaction preview",
                "operator_confirmed_transaction_payload_reviewed": True,
                "operator_confirmed_cli_only_transaction": True,
            },
            "writer_output": fixture["writer_output"],
            "postwrite_smoke_result": fixture["postwrite_smoke_result"],
        },
    )
    data = response.get_json()

    assert get_response.status_code == 405
    assert response.status_code == 200
    assert data["mode"] == (
        "candidate_queue_review_decision_writer_preflight_preview"
    )
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["execute_requested"] is True
    assert data["apply_real_write_requested"] is True
    assert data["read_only_query_executed"] is False
    assert data["database_connection_opened"] is False
    assert data["database_session_created"] is False
    assert data["explicit_transaction_opened"] is False
    assert data["transaction_opened"] is False
    assert data["transaction_committed"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["review_state_update_executed"] is False
    assert data["api_updates_review_state"] is False
    assert data["scheduler_attached"] is False
    assert data["writes_executed"] is False
    assert data["would_write_database"] is False
    assert data["preflight_payload_ready"] is False
    assert data["statement_summary"]["statement_count"] == 0
    assert "statement_payloads_present" in data["blocked_reasons"]
    assert "preflight_execute_not_requested_from_api" in data["blocked_reasons"]
    assert "preflight_apply_real_write_not_requested_from_api" in data[
        "blocked_reasons"
    ]
    assert "review_decision_writer_implementation_enabled" in data["blocked_reasons"]
    assert "do_not_update_review_state_from_review_state_preflight" in data[
        "safe_boundaries"
    ]


def test_candidate_queue_review_decision_writer_postwrite_smoke_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp
    from routes.market_intel_review_routes import market_intel_review_bp

    fixture = _build_candidate_queue_writer_receipt_fixture(
        "sample-batch-review-decision-postwrite-smoke-route"
    )
    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    app.register_blueprint(market_intel_review_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    get_response = client.get(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_postwrite_smoke"
    )
    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_postwrite_smoke",
        json={
            "sample_result": fixture["sample_result"],
            "operator_evidence": {
                **fixture["operator_evidence"],
                "closeout_artifact_path": "artifacts/market_intel/closeout.json",
                "operator_confirmed_queue_review_next": True,
                "operator_confirmed_no_scheduler_attach": True,
                "operator_confirmed_no_api_db_write": True,
                "operator_confirmed_inventory_read_only": True,
                "reviewer_id": "operator-a",
                "proposed_review_decision": "confirmed",
                "decision_notes": "manual review only",
                "operator_confirmed_manual_decision_only": True,
                "decision_approval_notes": "cli-only approval gate",
                "operator_confirmed_decision_payload_reviewed": True,
                "operator_confirmed_decision_apply_requires_cli": True,
                "operator_confirmed_review_state_update_is_not_api": True,
                "decision_transaction_notes": "shell-only transaction preview",
                "operator_confirmed_transaction_payload_reviewed": True,
                "operator_confirmed_cli_only_transaction": True,
            },
            "writer_output": fixture["writer_output"],
            "postwrite_smoke_result": fixture["postwrite_smoke_result"],
        },
    )
    data = response.get_json()

    assert get_response.status_code == 405
    assert response.status_code == 200
    assert data["mode"] == (
        "candidate_queue_review_decision_writer_postwrite_smoke_planned"
    )
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["execute_requested"] is False
    assert data["read_only_query_executed"] is False
    assert data["database_connection_opened"] is False
    assert data["database_session_created"] is False
    assert data["explicit_transaction_opened"] is False
    assert data["transaction_opened"] is False
    assert data["transaction_committed"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["review_state_update_executed"] is False
    assert data["api_updates_review_state"] is False
    assert data["scheduler_attached"] is False
    assert data["writes_executed"] is False
    assert data["would_write_database"] is False
    assert data["postwrite_smoke_passed"] is False
    assert data["review_state_update_verified"] is False
    assert "review_decision_writer_postwrite_smoke_not_loaded" in data[
        "blocked_reasons"
    ]
    assert "do_not_update_review_state_from_postwrite_smoke" in data[
        "safe_boundaries"
    ]


def test_candidate_queue_review_decision_writer_operator_drill_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp
    from routes.market_intel_review_routes import market_intel_review_bp

    fixture = _build_candidate_queue_writer_receipt_fixture(
        "sample-batch-review-decision-operator-drill-route"
    )
    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    app.register_blueprint(market_intel_review_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    get_response = client.get(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_operator_drill"
    )
    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_operator_drill",
        json={
            "sample_result": fixture["sample_result"],
            "operator_evidence": {
                **fixture["operator_evidence"],
                "closeout_artifact_path": "artifacts/market_intel/closeout.json",
                "operator_confirmed_queue_review_next": True,
                "operator_confirmed_no_scheduler_attach": True,
                "operator_confirmed_no_api_db_write": True,
                "operator_confirmed_inventory_read_only": True,
                "reviewer_id": "operator-a",
                "proposed_review_decision": "confirmed",
                "decision_notes": "manual review only",
                "operator_confirmed_manual_decision_only": True,
                "decision_approval_notes": "cli-only approval gate",
                "operator_confirmed_decision_payload_reviewed": True,
                "operator_confirmed_decision_apply_requires_cli": True,
                "operator_confirmed_review_state_update_is_not_api": True,
                "decision_transaction_notes": "shell-only transaction preview",
                "operator_confirmed_transaction_payload_reviewed": True,
                "operator_confirmed_cli_only_transaction": True,
                "operator_confirmed_manual_shell_window": True,
                "operator_confirmed_post_update_inventory_planned": True,
                "operator_drill_notes": "manual shell drill reviewed",
            },
            "writer_output": fixture["writer_output"],
            "postwrite_smoke_result": fixture["postwrite_smoke_result"],
        },
    )
    data = response.get_json()
    payload = json.dumps(data, ensure_ascii=False, sort_keys=True)

    assert get_response.status_code == 405
    assert response.status_code == 200
    assert data["mode"] == (
        "candidate_queue_review_decision_writer_operator_drill_preview"
    )
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["operator_drill_ready"] is False
    assert data["ready_for_api_review_state_update"] is False
    assert data["ready_for_api_database_write"] is False
    assert data["ready_for_scheduler_attach"] is False
    assert data["api_executes_cli"] is False
    assert data["api_reads_approval_token"] is False
    assert data["api_writes_file"] is False
    assert data["api_writes_database"] is False
    assert data["api_updates_review_state"] is False
    assert data["database_connection_opened"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["review_state_update_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["statement_summary"]["statement_count"] == 0
    assert data["input_summaries"]["writer_status_mode"] == (
        "candidate_queue_review_decision_writer_cli_blocked"
    )
    assert "transaction_preview_created" in data["blocked_reasons"]
    assert "transaction_has_update_statements" in data["blocked_reasons"]
    assert "backup_verified_by_operator" in data["blocked_reasons"]
    assert "do_not_execute_review_state_writer_from_operator_drill_api" in data[
        "safe_boundaries"
    ]
    assert TEST_APPROVAL_TOKEN not in payload


def test_candidate_queue_review_decision_writer_run_package_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp
    from routes.market_intel_review_routes import market_intel_review_bp

    fixture = _build_candidate_queue_writer_receipt_fixture(
        "sample-batch-review-decision-run-package-route"
    )
    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    app.register_blueprint(market_intel_review_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    get_response = client.get(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_run_package"
    )
    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_run_package",
        json={
            "sample_result": fixture["sample_result"],
            "operator_evidence": {
                **fixture["operator_evidence"],
                "closeout_artifact_path": "artifacts/market_intel/closeout.json",
                "operator_confirmed_queue_review_next": True,
                "operator_confirmed_no_scheduler_attach": True,
                "operator_confirmed_no_api_db_write": True,
                "operator_confirmed_inventory_read_only": True,
                "reviewer_id": "operator-a",
                "proposed_review_decision": "confirmed",
                "decision_notes": "manual review only",
                "operator_confirmed_manual_decision_only": True,
                "decision_approval_notes": "cli-only approval gate",
                "operator_confirmed_decision_payload_reviewed": True,
                "operator_confirmed_decision_apply_requires_cli": True,
                "operator_confirmed_review_state_update_is_not_api": True,
                "decision_transaction_notes": "shell-only transaction preview",
                "operator_confirmed_transaction_payload_reviewed": True,
                "operator_confirmed_cli_only_transaction": True,
                "operator_confirmed_manual_shell_window": True,
                "operator_confirmed_post_update_inventory_planned": True,
                "operator_drill_notes": "manual shell drill reviewed",
            },
            "writer_output": fixture["writer_output"],
            "postwrite_smoke_result": fixture["postwrite_smoke_result"],
        },
    )
    data = response.get_json()
    payload = json.dumps(data, ensure_ascii=False, sort_keys=True)

    assert get_response.status_code == 405
    assert response.status_code == 200
    assert data["mode"] == (
        "candidate_queue_review_decision_writer_run_package_preview"
    )
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["package_ready"] is False
    assert data["package_artifact_created"] is False
    assert data["ready_for_api_review_state_update"] is False
    assert data["ready_for_api_database_write"] is False
    assert data["ready_for_scheduler_attach"] is False
    assert data["api_writes_file"] is False
    assert data["api_executes_cli"] is False
    assert data["api_reads_approval_token"] is False
    assert data["api_writes_database"] is False
    assert data["api_updates_review_state"] is False
    assert data["database_connection_opened"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["review_state_update_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["payload_manifest"]["payload_count"] == 0
    assert "transaction_preview_created" in data["blocked_reasons"]
    assert "transaction_has_update_statements" in data["blocked_reasons"]
    assert "backup_artifact_path_recorded" in data["blocked_reasons"]
    assert "do_not_execute_review_state_writer_from_run_package_api" in data[
        "safe_boundaries"
    ]
    assert TEST_APPROVAL_TOKEN not in payload


def test_candidate_queue_review_decision_writer_run_readiness_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp
    from routes.market_intel_review_routes import market_intel_review_bp

    fixture = _build_candidate_queue_writer_receipt_fixture(
        "sample-batch-review-decision-run-readiness-route"
    )
    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    app.register_blueprint(market_intel_review_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    get_response = client.get(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_run_readiness"
    )
    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_run_readiness"
        "?execute=true&apply_real_write=true",
        json={
            "sample_result": fixture["sample_result"],
            "operator_evidence": {
                **fixture["operator_evidence"],
                "review_state_transaction_json_path": (
                    "artifacts/market_intel/review-state-transaction.json"
                ),
                "operator_confirmed_review_state_preflight_only": True,
                "operator_acknowledged_shell_only_token": True,
                "closeout_artifact_path": "artifacts/market_intel/closeout.json",
                "operator_confirmed_queue_review_next": True,
                "operator_confirmed_no_scheduler_attach": True,
                "operator_confirmed_no_api_db_write": True,
                "operator_confirmed_inventory_read_only": True,
                "reviewer_id": "operator-a",
                "proposed_review_decision": "confirmed",
                "decision_notes": "manual review only",
                "operator_confirmed_manual_decision_only": True,
                "decision_approval_notes": "cli-only approval gate",
                "operator_confirmed_decision_payload_reviewed": True,
                "operator_confirmed_decision_apply_requires_cli": True,
                "operator_confirmed_review_state_update_is_not_api": True,
                "decision_transaction_notes": "shell-only transaction preview",
                "operator_confirmed_transaction_payload_reviewed": True,
                "operator_confirmed_cli_only_transaction": True,
                "operator_confirmed_manual_shell_window": True,
                "operator_confirmed_post_update_inventory_planned": True,
                "operator_drill_notes": "manual shell drill reviewed",
            },
            "writer_output": fixture["writer_output"],
            "postwrite_smoke_result": fixture["postwrite_smoke_result"],
        },
    )
    data = response.get_json()
    payload = json.dumps(data, ensure_ascii=False, sort_keys=True)

    assert get_response.status_code == 405
    assert response.status_code == 200
    assert data["mode"] == (
        "candidate_queue_review_decision_writer_run_readiness_preview"
    )
    assert data["phase"] == (
        "phase_81_candidate_queue_review_ai_summary_run_package"
    )
    assert data["ready_for_cli_operator_run"] is False
    assert data["ready_for_api_review_state_update"] is False
    assert data["ready_for_api_database_write"] is False
    assert data["ready_for_scheduler_attach"] is False
    assert data["api_writes_file"] is False
    assert data["api_executes_cli"] is False
    assert data["api_reads_approval_token"] is False
    assert data["api_writes_database"] is False
    assert data["api_updates_review_state"] is False
    assert data["database_connection_opened"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["review_state_update_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["run_package_summary"]["payload_count"] == 0
    assert "payload_count_within_small_batch_limit" in data["blocked_reasons"]
    assert "do_not_execute_review_state_writer_from_run_readiness_api" in data[
        "safe_boundaries"
    ]
    assert TEST_APPROVAL_TOKEN not in payload


def test_candidate_queue_review_decision_writer_run_receipt_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp
    from routes.market_intel_review_routes import market_intel_review_bp

    fixture = _build_candidate_queue_writer_receipt_fixture(
        "sample-batch-review-decision-run-receipt-route"
    )
    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    app.register_blueprint(market_intel_review_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    get_response = client.get(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_run_receipt"
    )
    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_run_receipt"
        "?execute=true&apply_real_write=true",
        json={
            "sample_result": fixture["sample_result"],
            "operator_evidence": {
                **fixture["operator_evidence"],
                "review_state_transaction_json_path": (
                    "artifacts/market_intel/review-state-transaction.json"
                ),
                "operator_confirmed_review_state_preflight_only": True,
                "operator_acknowledged_shell_only_token": True,
                "review_state_writer_output_json_path": (
                    "artifacts/market_intel/review-state-writer-output.json"
                ),
                "review_state_postwrite_smoke_json_path": (
                    "artifacts/market_intel/review-state-postwrite-smoke.json"
                ),
                "operator_confirmed_no_token_in_artifacts": True,
                "receipt_notes": "review_state receipt reviewed",
                "closeout_artifact_path": "artifacts/market_intel/closeout.json",
                "operator_confirmed_queue_review_next": True,
                "operator_confirmed_no_scheduler_attach": True,
                "operator_confirmed_no_api_db_write": True,
                "operator_confirmed_inventory_read_only": True,
                "reviewer_id": "operator-a",
                "proposed_review_decision": "confirmed",
                "decision_notes": "manual review only",
                "operator_confirmed_manual_decision_only": True,
                "decision_approval_notes": "cli-only approval gate",
                "operator_confirmed_decision_payload_reviewed": True,
                "operator_confirmed_decision_apply_requires_cli": True,
                "operator_confirmed_review_state_update_is_not_api": True,
                "decision_transaction_notes": "shell-only transaction preview",
                "operator_confirmed_transaction_payload_reviewed": True,
                "operator_confirmed_cli_only_transaction": True,
                "operator_confirmed_manual_shell_window": True,
                "operator_confirmed_post_update_inventory_planned": True,
                "operator_drill_notes": "manual shell drill reviewed",
            },
            "writer_output": {
                **fixture["writer_output"],
                "mode": "candidate_queue_review_decision_writer_cli_executed",
                "review_state_update_executed": True,
                "api_updates_review_state": False,
            },
            "postwrite_smoke_result": {
                **fixture["postwrite_smoke_result"],
                "mode": (
                    "candidate_queue_review_decision_writer_postwrite_smoke_read_only"
                ),
                "review_state_update_verified": True,
                "state_mismatch_count": 0,
                "state_mismatches": [],
            },
        },
    )
    data = response.get_json()
    payload = json.dumps(data, ensure_ascii=False, sort_keys=True)

    assert get_response.status_code == 405
    assert response.status_code == 200
    assert data["mode"] == (
        "candidate_queue_review_decision_writer_run_receipt_preview"
    )
    assert data["phase"] == (
        "phase_81_candidate_queue_review_ai_summary_run_package"
    )
    assert data["receipt_passed"] is False
    assert data["ready_for_api_review_state_update"] is False
    assert data["ready_for_api_database_write"] is False
    assert data["ready_for_scheduler_attach"] is False
    assert data["api_writes_file"] is False
    assert data["api_executes_cli"] is False
    assert data["api_reads_approval_token"] is False
    assert data["api_writes_database"] is False
    assert data["api_updates_review_state"] is False
    assert data["database_connection_opened"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["review_state_update_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["expected_dedupe_keys"] == []
    assert "expected_dedupe_keys_present" in data["blocked_reasons"]
    assert "do_not_execute_review_state_writer_from_receipt_api" in data[
        "safe_boundaries"
    ]
    assert TEST_APPROVAL_TOKEN not in payload


def test_candidate_queue_review_decision_writer_run_closeout_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp
    from routes.market_intel_review_routes import market_intel_review_bp

    fixture = _build_candidate_queue_writer_receipt_fixture(
        "sample-batch-review-decision-run-closeout-route"
    )
    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    app.register_blueprint(market_intel_review_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    get_response = client.get(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_run_closeout"
    )
    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_run_closeout"
        "?execute=true&apply_real_write=true",
        json={
            "sample_result": fixture["sample_result"],
            "operator_evidence": {
                **fixture["operator_evidence"],
                "review_state_closeout_artifact_path": (
                    "artifacts/market_intel/review-state-closeout.json"
                ),
                "operator_confirmed_review_state_closeout_next": True,
                "operator_confirmed_post_closeout_inventory_read_only": True,
                "operator_confirmed_no_scheduler_attach": True,
                "operator_confirmed_no_api_db_write": True,
                "closeout_notes": "review_state closeout reviewed",
            },
            "writer_output": {
                **fixture["writer_output"],
                "mode": "candidate_queue_review_decision_writer_cli_executed",
                "review_state_update_executed": True,
                "api_updates_review_state": False,
            },
            "postwrite_smoke_result": {
                **fixture["postwrite_smoke_result"],
                "mode": (
                    "candidate_queue_review_decision_writer_postwrite_smoke_read_only"
                ),
                "review_state_update_verified": True,
                "state_mismatch_count": 0,
                "state_mismatches": [],
            },
        },
    )
    data = response.get_json()
    payload = json.dumps(data, ensure_ascii=False, sort_keys=True)

    assert get_response.status_code == 405
    assert response.status_code == 200
    assert data["mode"] == (
        "candidate_queue_review_decision_writer_run_closeout_preview"
    )
    assert data["phase"] == (
        "phase_81_candidate_queue_review_ai_summary_run_package"
    )
    assert data["closeout_passed"] is False
    assert data["ready_for_api_review_state_update"] is False
    assert data["ready_for_api_database_write"] is False
    assert data["ready_for_scheduler_attach"] is False
    assert data["api_writes_file"] is False
    assert data["api_executes_cli"] is False
    assert data["api_reads_approval_token"] is False
    assert data["api_writes_database"] is False
    assert data["api_updates_review_state"] is False
    assert data["database_connection_opened"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["review_state_update_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["receipt_summary"]["expected_dedupe_key_count"] == 0
    assert "receipt_expected_review_state_updates_present" in data[
        "blocked_reasons"
    ]
    assert "do_not_update_review_state_from_review_state_closeout" in data[
        "safe_boundaries"
    ]
    assert TEST_APPROVAL_TOKEN not in payload


def test_candidate_queue_review_decision_post_closeout_inventory_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp
    from routes.market_intel_review_routes import market_intel_review_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    app.register_blueprint(market_intel_review_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    get_response = client.get(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_post_closeout_inventory"
    )
    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_post_closeout_inventory"
        "?execute=true&apply_real_write=true",
        json={"sample_result": {}},
    )
    data = response.get_json()
    payload = json.dumps(data, ensure_ascii=False, sort_keys=True)

    assert get_response.status_code == 405
    assert response.status_code == 200
    assert data["mode"] == (
        "candidate_queue_review_decision_post_closeout_inventory_preview"
    )
    assert data["phase"] == (
        "phase_81_candidate_queue_review_ai_summary_run_package"
    )
    assert data["post_closeout_inventory_ready"] is False
    assert data["ready_for_api_review_state_update"] is False
    assert data["ready_for_api_database_write"] is False
    assert data["ready_for_scheduler_attach"] is False
    assert data["api_writes_file"] is False
    assert data["api_executes_cli"] is False
    assert data["api_reads_approval_token"] is False
    assert data["api_writes_database"] is False
    assert data["api_updates_review_state"] is False
    assert data["database_connection_opened"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["review_state_update_executed"] is False
    assert data["read_only_query_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["expected_dedupe_keys"] == []
    assert "expected_review_state_updates_present" in data["blocked_reasons"]
    assert "do_not_update_review_state_from_post_closeout_inventory" in data[
        "safe_boundaries"
    ]
    assert TEST_APPROVAL_TOKEN not in payload


def test_candidate_queue_review_completion_archive_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp
    from routes.market_intel_review_routes import market_intel_review_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    app.register_blueprint(market_intel_review_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    get_response = client.get(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_completion_archive"
    )
    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_completion_archive"
        "?execute=true&apply_real_write=true",
        json={"sample_result": {}},
    )
    data = response.get_json()
    payload = json.dumps(data, ensure_ascii=False, sort_keys=True)

    assert get_response.status_code == 405
    assert response.status_code == 200
    assert data["mode"] == "candidate_queue_review_completion_archive_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["review_completion_archive_ready"] is False
    assert data["archive_manifest_ready"] is False
    assert data["ready_for_api_review_state_update"] is False
    assert data["ready_for_api_database_write"] is False
    assert data["ready_for_scheduler_attach"] is False
    assert data["api_writes_file"] is False
    assert data["api_executes_cli"] is False
    assert data["api_reads_approval_token"] is False
    assert data["api_writes_database"] is False
    assert data["api_updates_review_state"] is False
    assert data["archive_file_written"] is False
    assert data["archive_record_written"] is False
    assert data["archive_manifest_written"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["review_state_update_executed"] is False
    assert data["read_only_query_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["expected_dedupe_keys"] == []
    assert "post_closeout_inventory_ready" in data["blocked_reasons"]
    assert "do_not_write_archive_file_from_api" in data["safe_boundaries"]
    assert TEST_APPROVAL_TOKEN not in payload


def test_candidate_queue_review_archive_summary_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp
    from routes.market_intel_review_routes import market_intel_review_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    app.register_blueprint(market_intel_review_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    get_response = client.get(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_archive_summary"
    )
    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_archive_summary"
        "?execute=true&apply_real_write=true",
        json={"sample_result": {}},
    )
    data = response.get_json()
    payload = json.dumps(data, ensure_ascii=False, sort_keys=True)

    assert get_response.status_code == 405
    assert response.status_code == 200
    assert data["mode"] == "candidate_queue_review_archive_summary_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["archive_summary_ready"] is False
    assert data["summary_input_ready"] is False
    assert data["ready_for_ai_summary_generation"] is False
    assert data["ready_for_llm_call"] is False
    assert data["ready_for_telegram_dispatch"] is False
    assert data["ready_for_api_review_state_update"] is False
    assert data["ready_for_api_database_write"] is False
    assert data["ready_for_scheduler_attach"] is False
    assert data["api_writes_file"] is False
    assert data["api_executes_cli"] is False
    assert data["api_reads_approval_token"] is False
    assert data["api_writes_database"] is False
    assert data["api_updates_review_state"] is False
    assert data["summary_file_written"] is False
    assert data["summary_record_written"] is False
    assert data["summary_manifest_written"] is False
    assert data["ai_summary_generated"] is False
    assert data["llm_call_executed"] is False
    assert data["ollama_call_executed"] is False
    assert data["gemini_call_executed"] is False
    assert data["telegram_dispatched"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["review_state_update_executed"] is False
    assert data["read_only_query_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["expected_dedupe_keys"] == []
    assert "review_completion_archive_ready" in data["blocked_reasons"]
    assert "do_not_call_llm_from_archive_summary_gate" in data["safe_boundaries"]
    assert TEST_APPROVAL_TOKEN not in payload


def test_candidate_queue_review_ai_summary_preflight_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp
    from routes.market_intel_review_routes import market_intel_review_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    app.register_blueprint(market_intel_review_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    get_response = client.get(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_ai_summary_preflight"
    )
    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_ai_summary_preflight"
        "?execute=true&apply_real_write=true",
        json={"sample_result": {}},
    )
    data = response.get_json()
    payload = json.dumps(data, ensure_ascii=False, sort_keys=True)

    assert get_response.status_code == 405
    assert response.status_code == 200
    assert data["mode"] == "candidate_queue_review_ai_summary_preflight_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["ai_summary_preflight_ready"] is False
    assert data["ready_for_manual_ollama_summary_run"] is False
    assert data["ready_for_ai_summary_generation"] is False
    assert data["ready_for_llm_call"] is False
    assert data["ready_for_telegram_dispatch"] is False
    assert data["ready_for_api_review_state_update"] is False
    assert data["ready_for_api_database_write"] is False
    assert data["ready_for_scheduler_attach"] is False
    assert data["api_writes_file"] is False
    assert data["api_executes_cli"] is False
    assert data["api_reads_approval_token"] is False
    assert data["api_writes_database"] is False
    assert data["api_updates_review_state"] is False
    assert data["summary_file_written"] is False
    assert data["summary_record_written"] is False
    assert data["summary_manifest_written"] is False
    assert data["ai_summary_generated"] is False
    assert data["llm_call_executed"] is False
    assert data["ollama_call_executed"] is False
    assert data["gemini_call_executed"] is False
    assert data["telegram_dispatched"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["review_state_update_executed"] is False
    assert data["read_only_query_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["expected_dedupe_keys"] == []
    assert "archive_summary_ready" in data["blocked_reasons"]
    assert "do_not_call_llm_from_ai_summary_preflight" in data["safe_boundaries"]
    assert (
        data["model_route_policy"]["primary_policy"]
        == "ollama_first"
    )
    assert (
        data["model_route_policy"]["fallback_policy"]
        == "gemini_backup_only_after_ollama_cascade_failure"
    )
    assert TEST_APPROVAL_TOKEN not in payload


def test_candidate_queue_review_ai_summary_run_package_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp
    from routes.market_intel_review_routes import market_intel_review_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    app.register_blueprint(market_intel_review_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    get_response = client.get(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_ai_summary_run_package"
    )
    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_ai_summary_run_package"
        "?execute=true&apply_real_write=true",
        json={"sample_result": {}},
    )
    data = response.get_json()
    payload = json.dumps(data, ensure_ascii=False, sort_keys=True)

    assert get_response.status_code == 405
    assert response.status_code == 200
    assert data["mode"] == "candidate_queue_review_ai_summary_run_package_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["ai_summary_run_package_ready"] is False
    assert data["ready_for_manual_ollama_summary_run"] is False
    assert data["ready_for_ai_summary_generation"] is False
    assert data["ready_for_llm_call"] is False
    assert data["ready_for_telegram_dispatch"] is False
    assert data["ready_for_api_review_state_update"] is False
    assert data["ready_for_api_database_write"] is False
    assert data["ready_for_scheduler_attach"] is False
    assert data["api_executes_llm"] is False
    assert data["api_writes_file"] is False
    assert data["api_executes_cli"] is False
    assert data["api_reads_approval_token"] is False
    assert data["api_writes_database"] is False
    assert data["api_updates_review_state"] is False
    assert data["run_package_file_written"] is False
    assert data["summary_file_written"] is False
    assert data["summary_record_written"] is False
    assert data["summary_manifest_written"] is False
    assert data["ai_summary_generated"] is False
    assert data["llm_call_executed"] is False
    assert data["ollama_call_executed"] is False
    assert data["gemini_call_executed"] is False
    assert data["telegram_dispatched"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["review_state_update_executed"] is False
    assert data["read_only_query_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["expected_dedupe_keys"] == []
    assert "archive_summary_ready" in data["blocked_reasons"]
    assert "ai_summary_preflight_ready" in data["blocked_reasons"]
    assert "do_not_call_llm_from_ai_summary_run_package" in data[
        "safe_boundaries"
    ]
    assert data["prompt_contract"]["contract_version"] == (
        "market_intel_ai_summary_prompt_v1"
    )
    assert data["summary_output_schema"]["schema_version"] == (
        "market_intel_ai_summary_v1"
    )
    assert TEST_APPROVAL_TOKEN not in payload


def test_candidate_queue_writer_run_receipt_route_is_post_only_and_no_write():
    from routes.market_intel_routes import market_intel_bp

    fixture = _build_candidate_queue_writer_receipt_fixture(
        batch_id="sample-batch-route-receipt"
    )
    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.post(
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_writer_run_receipt",
        json={
            "sample_result": fixture["sample_result"],
            "operator_evidence": fixture["operator_evidence"],
            "writer_output": fixture["writer_output"],
            "postwrite_smoke_result": fixture["postwrite_smoke_result"],
        },
    )
    data = response.get_json()
    payload = json.dumps(data, ensure_ascii=False, sort_keys=True)

    assert response.status_code == 200
    assert data["mode"] == "candidate_queue_writer_run_receipt_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["receipt_passed"] is True
    assert data["ready_for_next_manual_review"] is True
    assert data["ready_for_api_database_write"] is False
    assert data["ready_for_scheduler_attach"] is False
    assert data["api_executes_cli"] is False
    assert data["api_reads_approval_token"] is False
    assert data["api_writes_file"] is False
    assert data["api_writes_database"] is False
    assert data["database_connection_opened"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["writer_output_summary"]["database_commit_executed"] is True
    assert data["writer_output_summary"]["dedupe_keys_match_expected"] is True
    assert data["postwrite_smoke_summary"]["postwrite_smoke_passed"] is True
    assert data["postwrite_smoke_summary"]["dedupe_keys_match_expected"] is True
    assert data["blocked_reasons"] == []
    assert TEST_APPROVAL_TOKEN not in payload


def test_scheduler_plan_preview_blocks_job_attachment():
    plan = MarketIntelService().build_scheduler_plan()

    assert plan["mode"] == "scheduler_attach_plan_preview"
    assert plan["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert plan["ready_to_attach_scheduler"] is False
    assert plan["scheduler_attached"] is False
    assert plan["scheduler_registration_executed"] is False
    assert plan["crawler_job_started"] is False
    assert plan["external_network_executed"] is False
    assert plan["database_session_created"] is False
    assert plan["database_write_executed"] is False
    assert plan["database_commit_executed"] is False
    assert plan["writes_executed"] is False
    assert plan["would_write_database"] is False
    assert plan["job_count"] == 3
    assert {item["key"] for item in plan["jobs"]} == {
        "campaign_discovery_daily",
        "campaign_product_probe",
        "product_match_review_seed",
    }
    assert "market_intel_enabled" in plan["blocked_reasons"]
    assert "mcp_fetch_gate_open" in plan["blocked_reasons"]
    assert "manual_operator_approval" in plan["blocked_reasons"]
    assert "do_not_attach_scheduler_from_api" in plan["safe_boundaries"]


def test_scheduler_plan_route_is_preview_only():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.get("/api/market_intel/scheduler_plan")
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "scheduler_attach_plan_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["scheduler_registration_executed"] is False
    assert data["crawler_job_started"] is False
    assert data["external_network_executed"] is False
    assert data["database_write_executed"] is False


def test_match_review_plan_preview_blocks_auto_confirm():
    plan = MarketIntelService().build_match_review_plan()

    assert plan["mode"] == "match_review_plan_preview"
    assert plan["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert plan["ready_for_review_queue"] is False
    assert plan["review_queue_created"] is False
    assert plan["auto_match_executed"] is False
    assert plan["auto_confirm_executed"] is False
    assert plan["database_session_created"] is False
    assert plan["database_write_executed"] is False
    assert plan["database_commit_executed"] is False
    assert plan["external_network_executed"] is False
    assert plan["scheduler_attached"] is False
    assert plan["writes_executed"] is False
    assert plan["would_write_database"] is False
    assert plan["thresholds"]["auto_confirm_enabled"] is False
    assert len(plan["scoring_signals"]) >= 5
    assert "needs_review" in plan["planned_status_flow"]
    assert "confirmed" in plan["planned_status_flow"]
    assert "manual_operator_approval" in plan["blocked_reasons"]
    assert "do_not_auto_confirm_matches" in plan["safe_boundaries"]
    assert all(item["requires_operator"] for item in plan["review_actions"])


def test_match_review_plan_route_is_preview_only():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.get("/api/market_intel/match_review_plan")
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "match_review_plan_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["review_queue_created"] is False
    assert data["auto_confirm_executed"] is False
    assert data["external_network_executed"] is False
    assert data["database_write_executed"] is False


def test_opportunity_plan_preview_blocks_alerts_and_ai_summary():
    plan = MarketIntelService().build_opportunity_plan()

    assert plan["mode"] == "opportunity_plan_preview"
    assert plan["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert plan["ready_for_opportunity_queue"] is False
    assert plan["opportunity_queue_created"] is False
    assert plan["threat_alert_dispatched"] is False
    assert plan["telegram_dispatched"] is False
    assert plan["ai_summary_generated"] is False
    assert plan["database_session_created"] is False
    assert plan["database_write_executed"] is False
    assert plan["database_commit_executed"] is False
    assert plan["external_network_executed"] is False
    assert plan["scheduler_attached"] is False
    assert plan["writes_executed"] is False
    assert plan["would_write_database"] is False
    assert plan["rule_count"] == 4
    assert {item["key"] for item in plan["rules"]} == {
        "competitor_price_threat",
        "promotion_gap",
        "deep_discount_overlap",
        "campaign_ending_watch",
    }
    assert "match_review_candidates_available" in plan["blocked_reasons"]
    assert "manual_operator_approval" in plan["blocked_reasons"]
    assert "do_not_dispatch_alerts_from_preview" in plan["safe_boundaries"]
    assert "do_not_auto_adjust_price" in plan["safe_boundaries"]


def test_opportunity_plan_route_is_preview_only():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.get("/api/market_intel/opportunity_plan")
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "opportunity_plan_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["opportunity_queue_created"] is False
    assert data["threat_alert_dispatched"] is False
    assert data["ai_summary_generated"] is False
    assert data["database_write_executed"] is False


def test_opportunity_scoring_plan_preview_blocks_scoring_and_alerts():
    plan = MarketIntelService().build_opportunity_scoring_plan()

    assert plan["mode"] == "opportunity_scoring_plan_preview"
    assert plan["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert plan["ready_for_scoring_job"] is False
    assert plan["scoring_job_created"] is False
    assert plan["score_calculation_executed"] is False
    assert plan["sample_scores_generated"] is False
    assert plan["opportunity_queue_created"] is False
    assert plan["review_queue_created"] is False
    assert plan["threat_alert_dispatched"] is False
    assert plan["telegram_dispatched"] is False
    assert plan["ai_summary_generated"] is False
    assert plan["database_session_created"] is False
    assert plan["database_write_executed"] is False
    assert plan["database_commit_executed"] is False
    assert plan["external_network_executed"] is False
    assert plan["scheduler_attached"] is False
    assert plan["writes_executed"] is False
    assert plan["would_write_database"] is False
    assert plan["dimension_count"] == 5
    assert plan["total_weight"] == 100
    assert {item["key"] for item in plan["dimensions"]} == {
        "price_gap_pct",
        "discount_depth",
        "match_confidence",
        "campaign_urgency",
        "data_freshness",
    }
    assert "opportunity_queue_ready" in plan["blocked_reasons"]
    assert "confirmed_match_source_ready" in plan["blocked_reasons"]
    assert "manual_operator_approval" in plan["blocked_reasons"]
    assert "do_not_write_scoring_results_from_preview" in plan["safe_boundaries"]
    assert "do_not_auto_adjust_price" in plan["safe_boundaries"]


def test_opportunity_scoring_plan_route_is_preview_only():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.get("/api/market_intel/opportunity_scoring_plan")
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "opportunity_scoring_plan_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["scoring_job_created"] is False
    assert data["score_calculation_executed"] is False
    assert data["sample_scores_generated"] is False
    assert data["database_write_executed"] is False
    assert data["external_network_executed"] is False


def test_opportunity_evidence_plan_preview_blocks_queries_and_alerts():
    plan = MarketIntelService().build_opportunity_evidence_plan()

    assert plan["mode"] == "opportunity_evidence_plan_preview"
    assert plan["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert plan["ready_for_evidence_bundle"] is False
    assert plan["evidence_bundle_created"] is False
    assert plan["evidence_query_executed"] is False
    assert plan["sample_evidence_generated"] is False
    assert plan["alert_candidate_created"] is False
    assert plan["telegram_dispatched"] is False
    assert plan["ai_summary_generated"] is False
    assert plan["database_session_created"] is False
    assert plan["database_write_executed"] is False
    assert plan["database_commit_executed"] is False
    assert plan["external_network_executed"] is False
    assert plan["scheduler_attached"] is False
    assert plan["writes_executed"] is False
    assert plan["would_write_database"] is False
    assert plan["section_count"] == 5
    assert {item["key"] for item in plan["sections"]} == {
        "campaign_context",
        "market_product_snapshot",
        "match_review_state",
        "momo_reference",
        "scoring_trace",
    }
    assert "confirmed_match_evidence_available" in plan["blocked_reasons"]
    assert "scoring_trace_available" in plan["blocked_reasons"]
    assert "manual_operator_approval" in plan["blocked_reasons"]
    assert "do_not_query_database_from_evidence_preview" in plan["safe_boundaries"]
    assert "do_not_generate_placeholder_evidence" in plan["safe_boundaries"]
    assert plan["bundle_contract"]["freshness_window_hours"] == 24


def test_opportunity_evidence_plan_route_is_preview_only():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.get("/api/market_intel/opportunity_evidence_plan")
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "opportunity_evidence_plan_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["evidence_bundle_created"] is False
    assert data["evidence_query_executed"] is False
    assert data["sample_evidence_generated"] is False
    assert data["alert_candidate_created"] is False
    assert data["database_write_executed"] is False
    assert data["external_network_executed"] is False


def test_opportunity_alert_plan_preview_blocks_dispatch_and_llm_calls():
    plan = MarketIntelService().build_opportunity_alert_plan()

    assert plan["mode"] == "opportunity_alert_plan_preview"
    assert plan["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert plan["ready_for_alert_candidates"] is False
    assert plan["alert_candidate_created"] is False
    assert plan["alert_queue_created"] is False
    assert plan["review_queue_created"] is False
    assert plan["review_queue_contract_defined"] is True
    assert plan["review_queue_contract_written"] is False
    assert plan["review_queue_table_created"] is False
    assert plan["review_action_executed"] is False
    assert plan["approval_record_written"] is False
    assert plan["telegram_dispatched"] is False
    assert plan["ai_summary_generated"] is False
    assert plan["llm_call_executed"] is False
    assert plan["notification_sent"] is False
    assert plan["database_session_created"] is False
    assert plan["database_write_executed"] is False
    assert plan["database_commit_executed"] is False
    assert plan["external_network_executed"] is False
    assert plan["scheduler_attached"] is False
    assert plan["writes_executed"] is False
    assert plan["would_write_database"] is False
    assert plan["channel_count"] == 4
    assert {item["key"] for item in plan["channels"]} == {
        "operator_review",
        "daily_digest",
        "telegram_candidate",
        "ai_briefing_candidate",
    }
    assert plan["review_state_count"] == 6
    assert {item["key"] for item in plan["review_states"]} == {
        "draft",
        "needs_review",
        "approved_for_digest",
        "approved_for_telegram",
        "rejected",
        "deferred",
    }
    assert {item["key"] for item in plan["review_actions"]} == {
        "approve_digest",
        "approve_telegram",
        "reject",
        "defer",
    }
    assert plan["review_queue_contract"]["table_name"] == "market_alert_review_queue"
    assert "alert_candidate_id" in plan["review_queue_contract"]["required_fields"]
    assert "reviewer_identity" in plan["review_queue_contract"]["audit_fields"]
    assert "payment_or_shipping_data" in plan["review_queue_contract"]["forbidden_fields"]
    assert {item["key"] for item in plan["review_priority_lanes"]} == {
        "critical",
        "high",
        "medium",
        "watch",
    }
    assert {item["key"] for item in plan["review_queue_indexes"]} == {
        "idx_market_alert_review_queue_state_priority",
        "ux_market_alert_review_queue_dedupe",
        "idx_market_alert_review_queue_bundle",
    }
    assert plan["approval_policy"]["manual_approval_required_for_dispatch"] is True
    assert plan["approval_policy"]["reviewer_identity_required"] is True
    assert "evidence_bundle_ready" in plan["blocked_reasons"]
    assert "scoring_job_ready" in plan["blocked_reasons"]
    assert "operator_approval" in plan["blocked_reasons"]
    assert "do_not_dispatch_telegram_from_alert_preview" in plan["safe_boundaries"]
    assert "do_not_create_review_queue_table_from_preview" in plan["safe_boundaries"]
    assert "do_not_write_review_queue_contract_from_preview" in plan["safe_boundaries"]
    assert "do_not_call_llm_from_alert_preview" in plan["safe_boundaries"]
    assert "customer_personal_data" in plan["payload_contract"]["forbidden_fields"]


def test_opportunity_alert_plan_route_is_preview_only():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.get("/api/market_intel/opportunity_alert_plan")
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "opportunity_alert_plan_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["alert_candidate_created"] is False
    assert data["alert_queue_created"] is False
    assert data["review_queue_created"] is False
    assert data["review_queue_contract_defined"] is True
    assert data["review_queue_contract_written"] is False
    assert data["review_queue_table_created"] is False
    assert data["review_action_executed"] is False
    assert data["approval_record_written"] is False
    assert data["telegram_dispatched"] is False
    assert data["llm_call_executed"] is False
    assert data["database_write_executed"] is False
    assert data["external_network_executed"] is False


def test_mcp_deploy_preflight_blocks_without_required_env():
    preflight = build_mcp_deploy_preflight_plan(env={})

    assert preflight["mode"] == "mcp_external_deploy_preflight_preview"
    assert preflight["compose_file_present"] is True
    assert preflight["ready_to_start_stack"] is False
    assert preflight["checks"]["compose_file_present"] is True
    assert preflight["checks"]["all_expected_services_declared"] is True
    assert preflight["checks"]["all_expected_containers_declared"] is True
    assert preflight["checks"]["all_public_mcp_ports_localhost_only"] is True
    assert preflight["checks"]["required_env_vars_present"] is False
    assert preflight["checks"]["router_flag_still_off_before_health"] is True
    assert "required_env_vars_present" in preflight["blocked_reasons"]
    assert preflight["operator_command_preview"] == "docker compose -f docker-compose.mcp.yml up -d"
    assert preflight["deployment_actions_executed"] is False
    assert preflight["docker_command_executed"] is False
    assert preflight["ssh_command_executed"] is False
    assert preflight["database_session_created"] is False
    assert preflight["database_write_executed"] is False
    assert preflight["database_commit_executed"] is False
    assert preflight["external_network_executed"] is False
    assert preflight["scheduler_attached"] is False
    assert preflight["would_write_database"] is False


def test_mcp_compose_is_mounted_read_only_for_preflight():
    compose = Path("docker-compose.yml").read_text(encoding="utf-8")

    assert "./docker-compose.mcp.yml:/app/docker-compose.mcp.yml:ro" in compose


def test_mcp_deploy_preflight_ready_when_env_contract_is_present():
    preflight = build_mcp_deploy_preflight_plan(
        env={
            "MCP_POSTGRES_PASSWORD": "secret",
            "TAVILY_API_KEY": "tavily",
            "EXA_API_KEY": "exa",
            "MCP_ROUTER_ENABLED": "false",
        }
    )

    assert preflight["ready_to_start_stack"] is True
    assert preflight["blocked_reasons"] == []
    assert preflight["checks"]["required_env_vars_present"] is True
    assert preflight["checks"]["router_flag_still_off_before_health"] is True
    assert all(item["localhost_only"] for item in preflight["port_statuses"])


def test_mcp_deploy_preflight_route_is_preview_only():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.get("/api/market_intel/mcp_deploy_preflight")
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "mcp_external_deploy_preflight_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["deployment_actions_executed"] is False
    assert data["docker_command_executed"] is False
    assert data["ssh_command_executed"] is False
    assert data["database_write_executed"] is False
    assert data["external_network_executed"] is False
    assert data["scheduler_attached"] is False


def test_mcp_readiness_default_is_planned_only(monkeypatch):
    monkeypatch.delenv("MCP_ROUTER_ENABLED", raising=False)

    readiness = MarketIntelService().build_mcp_readiness()

    assert readiness["mode"] == "mcp_readiness_planned"
    assert readiness["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert readiness["execute_requested"] is False
    assert readiness["router_enabled"] is False
    assert readiness["external_mcp_complete"] is False
    assert readiness["internal_mcp_complete"] is False
    assert readiness["market_intel_mcp_integrated"] is True
    assert readiness["mcp_tool_contract"]["contract_ready"] is True
    assert readiness["database_session_created"] is False
    assert readiness["database_write_executed"] is False
    assert readiness["database_commit_executed"] is False
    assert readiness["external_network_executed"] is False
    assert readiness["scheduler_attached"] is False
    assert readiness["writes_executed"] is False
    assert readiness["would_write_database"] is False
    assert readiness["telemetry"]["read_only_query_executed"] is False
    assert readiness["telemetry"]["database_session_created"] is False
    assert readiness["telemetry"]["database_write_executed"] is False
    assert readiness["readiness_checks"]["base_callers_registered"] is True
    assert readiness["readiness_checks"]["market_intel_caller_registered"] is True
    assert readiness["readiness_checks"]["market_intel_tools_registered"] is True
    assert readiness["readiness_checks"]["market_intel_tool_contract_ready"] is True
    assert len(readiness["server_statuses"]) == 4
    assert all(item["health_checked"] is False for item in readiness["server_statuses"])
    assert all(item["healthy"] is False for item in readiness["server_statuses"])
    assert "execute_false_planned_only" in readiness["blocked_reasons"]
    assert "market_intel_caller_registered" not in readiness["blocked_reasons"]
    assert "market_intel_tools_registered" not in readiness["blocked_reasons"]


def test_mcp_readiness_sqlite_read_only_counts_telemetry(monkeypatch):
    monkeypatch.delenv("MCP_ROUTER_ENABLED", raising=False)
    monkeypatch.setattr(
        "services.market_intel.mcp_readiness._health_check_servers",
        lambda base_hosts, timeout_sec: [
            {
                "server": "postgres",
                "base_url": "http://127.0.0.1:3001",
                "configured": True,
                "health_checked": True,
                "healthy": False,
                "status": "error",
                "error_message": "test skipped network",
            },
            {
                "server": "omnisearch",
                "base_url": "http://127.0.0.1:3003",
                "configured": True,
                "health_checked": True,
                "healthy": False,
                "status": "error",
                "error_message": "test skipped network",
            },
            {
                "server": "firecrawl",
                "base_url": "http://127.0.0.1:3002",
                "configured": True,
                "health_checked": True,
                "healthy": False,
                "status": "error",
                "error_message": "test skipped network",
            },
            {
                "server": "filesystem",
                "base_url": "http://127.0.0.1:3004",
                "configured": True,
                "health_checked": True,
                "healthy": False,
                "status": "error",
                "error_message": "test skipped network",
            },
        ],
    )
    engine = create_engine("sqlite:///:memory:")
    with engine.begin() as conn:
        conn.execute(
            text(
                """
                CREATE TABLE mcp_calls (
                    id INTEGER PRIMARY KEY,
                    server TEXT,
                    called_at TEXT
                )
                """
            )
        )
        conn.execute(
            text(
                """
                INSERT INTO mcp_calls (server, called_at)
                VALUES
                    ('omnisearch', '2026-05-18 10:00:00'),
                    ('omnisearch', '2026-05-18 10:05:00'),
                    ('postgres', '2026-05-18 10:10:00')
                """
            )
        )

    readiness = build_mcp_readiness_plan(
        execute_requested=True,
        timeout_sec=1,
        engine=engine,
        database_type="sqlite",
    )

    assert readiness["mode"] == "mcp_readiness_read_only"
    assert readiness["execute_requested"] is True
    assert readiness["router_enabled"] is False
    assert readiness["external_mcp_complete"] is False
    assert readiness["internal_mcp_complete"] is True
    assert readiness["market_intel_mcp_integrated"] is True
    assert readiness["mcp_tool_contract"]["contract_ready"] is True
    assert readiness["telemetry"]["mode"] == "mcp_telemetry_read_only"
    assert readiness["telemetry"]["table_exists"] is True
    assert readiness["telemetry"]["total_calls"] == 3
    assert readiness["telemetry"]["recent_24h_calls"] == 3
    assert readiness["telemetry"]["read_only_query_executed"] is True
    assert readiness["telemetry"]["database_session_created"] is False
    assert readiness["telemetry"]["database_write_executed"] is False
    assert readiness["telemetry"]["database_commit_executed"] is False
    assert readiness["database_session_created"] is False
    assert readiness["database_write_executed"] is False
    assert readiness["database_commit_executed"] is False
    assert readiness["scheduler_attached"] is False
    assert readiness["writes_executed"] is False
    assert readiness["would_write_database"] is False
    assert readiness["server_statuses"][0]["health_checked"] is True
    assert {item["server"]: item["calls"] for item in readiness["telemetry"]["server_counts"]} == {
        "omnisearch": 2,
        "postgres": 1,
    }
    assert "mcp_router_enabled" in readiness["blocked_reasons"]
    assert "market_intel_caller_registered" not in readiness["blocked_reasons"]


def test_market_intel_schema_smoke_checks_platform_columns():
    smoke = MarketIntelService().build_schema_smoke()["schema_smoke"]

    assert smoke["passed"] is True
    assert smoke["missing_tables"] == []
    assert smoke["missing_market_platform_columns"] == []
    assert "crawl_policy_json" in smoke["market_platform_required_columns"]


def test_platform_seed_plan_is_read_only_and_adapter_derived():
    plan = MarketIntelService().build_platform_seed_plan()
    seed_codes = {seed["code"] for seed in plan["seeds"]}

    assert {"momo", "pchome", "coupang", "shopee"} <= seed_codes
    assert plan["would_write_database"] is False
    assert plan["required_gates"]["schema_smoke_required"] is True
    assert plan["required_gates"]["migration_required"] is True
    assert plan["required_gates"]["manual_operator_approval_required"] is True

    for seed in plan["seeds"]:
        policy = seed["crawl_policy_json"]
        assert seed["enabled"] is False
        assert seed["source_count"] == len(seed["sources"])
        assert policy["allow_login"] is False
        assert policy["allow_database_write"] is False
        assert policy["allow_scheduler_attach"] is False


def test_platform_seed_plan_unknown_adapter_returns_diagnostic_error():
    plan = MarketIntelService().build_platform_seed_plan("unknown")

    assert plan["found"] is False
    assert plan["seed_count"] == 0
    assert plan["error"] == "未知平台 adapter"


def test_platform_seed_write_guard_blocks_default_environment():
    guard = MarketIntelService().build_platform_seed_write_guard()

    assert guard["ready_to_write"] is False
    assert guard["would_write_database"] is False
    assert guard["database_write_allowed"] is False
    assert guard["seed_count"] == 4
    assert "market_intel_enabled" in guard["blocked_reasons"]
    assert "market_intel_write_enabled" in guard["blocked_reasons"]
    assert "database_write_allowed" in guard["blocked_reasons"]
    assert "migration_confirmed" in guard["blocked_reasons"]
    assert "manual_operator_approval" in guard["blocked_reasons"]
    assert guard["schema_smoke"]["passed"] is True
    assert "schema_smoke_confirmed" not in guard["blocked_reasons"]


def test_platform_seed_writer_plan_is_dry_run_only():
    writer_plan = MarketIntelService().build_platform_seed_writer_plan()

    assert writer_plan["mode"] == "dry_run"
    assert writer_plan["ready_to_write"] is False
    assert writer_plan["writes_executed"] is False
    assert writer_plan["would_write_database"] is False
    assert writer_plan["operation_count"] == 4
    assert writer_plan["schema_smoke"]["passed"] is True

    first_operation = writer_plan["operations"][0]
    assert first_operation["operation"] == "upsert"
    assert first_operation["table"] == "market_platforms"
    assert first_operation["write_status"] == "blocked_dry_run_only"
    assert first_operation["values"]["enabled"] is False
    assert "ON CONFLICT(code)" in first_operation["sql_shape"]


def test_schema_db_probe_planned_does_not_connect_or_write():
    probe = MarketIntelService().build_schema_db_probe()

    assert probe["mode"] == "schema_db_probe_planned"
    assert probe["execute_requested"] is False
    assert probe["read_only_query_executed"] is False
    assert probe["database_connection_opened"] is False
    assert probe["database_session_created"] is False
    assert probe["explicit_transaction_opened"] is False
    assert probe["database_write_executed"] is False
    assert probe["database_commit_executed"] is False
    assert probe["migration_executed"] is False
    assert probe["missing_tables"] == list(MARKET_INTEL_TABLES)
    assert "execute_false_planned_only" in probe["blocked_reasons"]


def test_schema_db_probe_sqlite_read_only_reports_existing_and_missing_tables():
    engine = create_engine("sqlite:///:memory:")
    with engine.begin() as conn:
        conn.execute(text("CREATE TABLE market_platforms (id INTEGER PRIMARY KEY)"))

    probe = build_schema_db_probe_plan(
        ["market_platforms", "market_campaigns"],
        execute_requested=True,
        database_type="sqlite",
        engine=engine,
    )

    assert probe["mode"] == "schema_db_probe_read_only"
    assert probe["execute_requested"] is True
    assert probe["read_only_query_executed"] is True
    assert probe["database_connection_opened"] is True
    assert probe["database_session_created"] is False
    assert probe["explicit_transaction_opened"] is False
    assert probe["database_write_executed"] is False
    assert probe["database_commit_executed"] is False
    assert probe["existing_tables"] == ["market_platforms"]
    assert probe["missing_tables"] == ["market_campaigns"]
    assert probe["schema_tables_exist"] is False
    assert "market_tables_missing" in probe["blocked_reasons"]


def test_platform_seed_db_diff_planned_does_not_connect_or_write():
    diff = MarketIntelService().build_platform_seed_db_diff()

    assert diff["mode"] == "platform_seed_db_diff_planned"
    assert diff["execute_requested"] is False
    assert diff["read_only_query_executed"] is False
    assert diff["database_connection_opened"] is False
    assert diff["database_session_created"] is False
    assert diff["explicit_transaction_opened"] is False
    assert diff["database_write_executed"] is False
    assert diff["database_commit_executed"] is False
    assert diff["seed_write_executed"] is False
    assert diff["expected_seed_count"] == 4
    assert set(diff["missing_codes"]) == {"momo", "pchome", "coupang", "shopee"}
    assert "execute_false_planned_only" in diff["blocked_reasons"]
    assert "seed_write_still_blocked" in diff["blocked_reasons"]


def test_platform_seed_db_diff_sqlite_read_only_reports_missing_and_matching_seed_rows():
    seed_plan = {
        "seeds": [
            {
                "code": "momo",
                "name": "MOMO",
                "base_url": "https://momo.example",
                "enabled": False,
                "crawl_policy_json": {
                    "allow_login": False,
                    "allow_database_write": False,
                    "seed_source_keys": ["momo_edm"],
                },
            },
            {
                "code": "pchome",
                "name": "PChome",
                "base_url": "https://pchome.example",
                "enabled": False,
                "crawl_policy_json": {
                    "allow_login": False,
                    "allow_database_write": False,
                    "seed_source_keys": ["pchome_region"],
                },
            },
        ]
    }
    engine = create_engine("sqlite:///:memory:")
    with engine.begin() as conn:
        conn.execute(
            text(
                """
                CREATE TABLE market_platforms (
                    code TEXT PRIMARY KEY,
                    name TEXT,
                    base_url TEXT,
                    enabled BOOLEAN,
                    crawl_policy_json TEXT
                )
                """
            )
        )
        conn.execute(
            text(
                """
                INSERT INTO market_platforms
                    (code, name, base_url, enabled, crawl_policy_json)
                VALUES
                    (:code, :name, :base_url, :enabled, :crawl_policy_json)
                """
            ),
            {
                "code": "momo",
                "name": "MOMO",
                "base_url": "https://momo.example",
                "enabled": False,
                "crawl_policy_json": json.dumps(
                    seed_plan["seeds"][0]["crawl_policy_json"],
                    ensure_ascii=False,
                    sort_keys=True,
                ),
            },
        )

    diff = build_platform_seed_db_diff_plan(
        seed_plan,
        execute_requested=True,
        database_type="sqlite",
        engine=engine,
    )

    assert diff["mode"] == "platform_seed_db_diff_read_only"
    assert diff["execute_requested"] is True
    assert diff["read_only_query_executed"] is True
    assert diff["database_connection_opened"] is True
    assert diff["database_session_created"] is False
    assert diff["explicit_transaction_opened"] is False
    assert diff["database_write_executed"] is False
    assert diff["database_commit_executed"] is False
    assert diff["seed_write_executed"] is False
    assert diff["expected_seed_count"] == 2
    assert diff["existing_seed_count"] == 1
    assert diff["existing_codes"] == ["momo"]
    assert diff["missing_codes"] == ["pchome"]
    assert diff["changed_codes"] == []
    assert diff["matching_codes"] == ["momo"]
    assert diff["seed_rows_ready"] is False
    assert {item["code"]: item["diff_status"] for item in diff["seed_diffs"]} == {
        "momo": "matches_expected",
        "pchome": "missing",
    }
    assert "seed_rows_missing" in diff["blocked_reasons"]
    assert "seed_write_still_blocked" in diff["blocked_reasons"]


def test_deployment_readiness_reports_app_only_release_gate():
    readiness = MarketIntelService().build_deployment_readiness()

    step_keys = {step["key"] for step in readiness["required_manual_steps"]}
    fallback_keys = {item["key"] for item in readiness["fallback_plan"]}
    boundary_keys = {item["key"] for item in readiness["safe_deploy_boundaries"]}

    assert readiness["mode"] == "app_only_release_gate"
    assert readiness["production_deployed"] is False
    assert readiness["git_committed"] is False
    assert readiness["git_pushed"] is False
    assert readiness["ready_for_production_deploy"] is True
    assert readiness["deployment_actions_executed"] is False
    assert readiness["execution_boundary"]["api_executes_scp"] is False
    assert readiness["execution_boundary"]["api_recreates_container"] is False
    assert readiness["execution_boundary"]["api_runs_migration"] is False
    assert readiness["execution_boundary"]["api_writes_database"] is False
    assert readiness["requires_backup_before_major_update"] is True
    assert readiness["backup_command"] == "python backup_system.py"
    assert readiness["checks"]["schema_smoke_passed"] is True
    assert readiness["checks"]["schema_db_probe_planned_safe"] is True
    assert readiness["checks"]["platform_seed_db_diff_planned_safe"] is True
    assert readiness["checks"]["legacy_source_bridge_planned_safe"] is True
    assert readiness["checks"]["mcp_readiness_planned_safe"] is True
    assert readiness["checks"]["mcp_tool_contract_ready"] is True
    assert readiness["checks"]["mcp_deploy_preflight_preview_safe"] is True
    assert readiness["checks"]["mcp_activation_runbook_preview_safe"] is True
    assert readiness["checks"]["mcp_fetch_gate_preview_safe"] is True
    assert readiness["checks"]["scheduler_plan_preview_safe"] is True
    assert readiness["checks"]["manual_sample_plan_preview_safe"] is True
    assert readiness["checks"]["manual_sample_acceptance_preview_safe"] is True
    assert readiness["checks"]["manual_sample_review_preview_safe"] is True
    assert readiness["checks"]["manual_sample_review_evaluation_post_safe"] is True
    assert readiness["checks"]["manual_sample_candidate_handoff_post_safe"] is True
    assert readiness["checks"]["manual_sample_candidate_queue_draft_post_safe"] is True
    assert readiness["checks"]["manual_sample_candidate_queue_approval_post_safe"] is True
    assert readiness["checks"]["manual_sample_candidate_queue_transaction_post_safe"] is True
    assert readiness["checks"]["candidate_queue_writer_cli_status_safe"] is True
    assert readiness["checks"]["candidate_queue_writer_preflight_planned_safe"] is True
    assert (
        readiness["checks"]["candidate_queue_writer_postwrite_smoke_planned_safe"]
        is True
    )
    assert (
        readiness["checks"]["candidate_queue_writer_operator_drill_preview_safe"]
        is True
    )
    assert (
        readiness["checks"]["candidate_queue_writer_run_package_preview_safe"]
        is True
    )
    assert (
        readiness["checks"]["candidate_queue_writer_run_readiness_preview_safe"]
        is True
    )
    assert (
        readiness["checks"]["candidate_queue_writer_run_receipt_preview_safe"]
        is True
    )
    assert (
        readiness["checks"]["candidate_queue_writer_run_closeout_preview_safe"]
        is True
    )
    assert (
        readiness["checks"]["candidate_queue_review_handoff_preview_safe"]
        is True
    )
    assert (
        readiness["checks"]["candidate_queue_review_inventory_preview_safe"]
        is True
    )
    assert (
        readiness["checks"]["candidate_queue_review_decision_preview_safe"]
        is True
    )
    assert (
        readiness["checks"][
            "candidate_queue_review_decision_approval_preview_safe"
        ]
        is True
    )
    assert (
        readiness["checks"][
            "candidate_queue_review_decision_transaction_preview_safe"
        ]
        is True
    )
    assert (
        readiness["checks"][
            "candidate_queue_review_decision_writer_preflight_safe"
        ]
        is True
    )
    assert (
        readiness["checks"][
            "candidate_queue_review_decision_writer_postwrite_smoke_planned_safe"
        ]
        is True
    )
    assert (
        readiness["checks"][
            "candidate_queue_review_decision_writer_operator_drill_preview_safe"
        ]
        is True
    )
    assert (
        readiness["checks"][
            "candidate_queue_review_decision_writer_run_package_preview_safe"
        ]
        is True
    )
    assert (
        readiness["checks"][
            "candidate_queue_review_decision_writer_run_readiness_preview_safe"
        ]
        is True
    )
    assert (
        readiness["checks"][
            "candidate_queue_review_decision_writer_run_receipt_preview_safe"
        ]
        is True
    )
    assert (
        readiness["checks"][
            "candidate_queue_review_decision_writer_run_closeout_preview_safe"
        ]
        is True
    )
    assert (
        readiness["checks"][
            "candidate_queue_review_decision_post_closeout_inventory_preview_safe"
        ]
        is True
    )
    assert (
        readiness["checks"][
            "candidate_queue_review_completion_archive_preview_safe"
        ]
        is True
    )
    assert (
        readiness["checks"][
            "candidate_queue_review_archive_summary_preview_safe"
        ]
        is True
    )
    assert (
        readiness["checks"][
            "candidate_queue_review_ai_summary_preflight_preview_safe"
        ]
        is True
    )
    assert (
        readiness["checks"][
            "candidate_queue_review_ai_summary_run_package_preview_safe"
        ]
        is True
    )
    assert (
        readiness["checks"][
            "candidate_queue_review_decision_writer_cli_status_safe"
        ]
        is True
    )
    assert readiness["checks"]["match_review_plan_preview_safe"] is True
    assert readiness["checks"]["opportunity_plan_preview_safe"] is True
    assert readiness["checks"]["opportunity_scoring_plan_preview_safe"] is True
    assert readiness["checks"]["opportunity_evidence_plan_preview_safe"] is True
    assert readiness["checks"]["opportunity_alert_plan_preview_safe"] is True
    assert readiness["checks"]["migration_apply_drill_preview_safe"] is True
    assert readiness["checks"]["migration_catalog_review_preview_safe"] is True
    assert readiness["checks"]["migration_live_smoke_preview_safe"] is True
    assert readiness["checks"]["live_db_inventory_preview_safe"] is True
    assert readiness["checks"]["writer_plan_dry_run_only"] is True
    assert readiness["writer_plan_summary"]["writes_executed"] is False
    assert "readiness_checks_not_all_passed" not in readiness["blocked_reasons"]
    assert "production_deploy_not_executed_by_api" in readiness["blocked_reasons"]
    assert "backup_must_be_verified_by_operator" in readiness["blocked_reasons"]
    assert "run_backup_system" in step_keys
    assert "verify_health_endpoint" in step_keys
    assert "feature_flag_kill_switch" in fallback_keys
    assert "database_write_blocked" in fallback_keys
    assert "no_remove_orphans" in boundary_keys
    assert "no_momo_db_lifecycle_change" in boundary_keys
    assert "/health" in readiness["production_smoke_targets"]
    assert "/api/market_intel/deployment_readiness" in readiness["production_smoke_targets"]
    assert "/api/market_intel/platform_seed_db_diff" in readiness["production_smoke_targets"]
    assert "/api/market_intel/legacy_source_bridge" in readiness["production_smoke_targets"]
    assert "/api/market_intel/mcp_readiness" in readiness["production_smoke_targets"]
    assert "/api/market_intel/mcp_tool_contract" in readiness["production_smoke_targets"]
    assert "/api/market_intel/mcp_deploy_preflight" in readiness["production_smoke_targets"]
    assert "/api/market_intel/mcp_activation_runbook" in readiness["production_smoke_targets"]
    assert "/api/market_intel/mcp_fetch_gate" in readiness["production_smoke_targets"]
    assert "/api/market_intel/scheduler_plan" in readiness["production_smoke_targets"]
    assert "/api/market_intel/manual_sample_plan" in readiness["production_smoke_targets"]
    assert "/api/market_intel/manual_sample_acceptance" in readiness["production_smoke_targets"]
    assert "/api/market_intel/manual_sample_review" in readiness["production_smoke_targets"]
    assert "/api/market_intel/match_review_plan" in readiness["production_smoke_targets"]
    assert "/api/market_intel/opportunity_plan" in readiness["production_smoke_targets"]
    assert "/api/market_intel/opportunity_scoring_plan" in readiness["production_smoke_targets"]
    assert "/api/market_intel/opportunity_evidence_plan" in readiness["production_smoke_targets"]
    assert "/api/market_intel/opportunity_alert_plan" in readiness["production_smoke_targets"]
    assert "/api/market_intel/migration_apply_drill" in readiness["production_smoke_targets"]
    assert "/api/market_intel/migration_catalog_review" in readiness["production_smoke_targets"]
    assert "/api/market_intel/migration_live_smoke" in readiness["production_smoke_targets"]
    assert "/api/market_intel/live_db_inventory" in readiness["production_smoke_targets"]
    assert (
        "/api/market_intel/manual_sample_review/candidate_queue_writer_postwrite_smoke"
        in readiness["production_smoke_targets"]
    )
    assert (
        "/api/market_intel/manual_sample_review/candidate_queue_writer_operator_drill"
        in readiness["production_smoke_targets"]
    )
    assert (
        "/api/market_intel/manual_sample_review/candidate_queue_writer_run_package"
        in readiness["production_smoke_targets"]
    )
    assert (
        "/api/market_intel/manual_sample_review/candidate_queue_writer_run_readiness"
        in readiness["production_smoke_targets"]
    )
    assert (
        "/api/market_intel/manual_sample_review/candidate_queue_writer_run_receipt"
        in readiness["production_smoke_targets"]
    )
    assert (
        "/api/market_intel/manual_sample_review/candidate_queue_writer_run_closeout"
        in readiness["production_smoke_targets"]
    )
    assert (
        "/api/market_intel/manual_sample_review/candidate_queue_review_handoff"
        in readiness["production_smoke_targets"]
    )
    assert (
        "/api/market_intel/manual_sample_review/candidate_queue_review_inventory"
        in readiness["production_smoke_targets"]
    )
    assert (
        "/api/market_intel/manual_sample_review/candidate_queue_review_decision"
        in readiness["production_smoke_targets"]
    )
    assert (
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_approval"
        in readiness["production_smoke_targets"]
    )
    assert (
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_transaction"
        in readiness["production_smoke_targets"]
    )
    assert (
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_preflight"
        in readiness["production_smoke_targets"]
    )
    assert (
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_postwrite_smoke"
        in readiness["production_smoke_targets"]
    )
    assert (
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_operator_drill"
        in readiness["production_smoke_targets"]
    )
    assert (
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_run_package"
        in readiness["production_smoke_targets"]
    )
    assert (
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_run_readiness"
        in readiness["production_smoke_targets"]
    )
    assert (
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_run_receipt"
        in readiness["production_smoke_targets"]
    )
    assert (
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_run_closeout"
        in readiness["production_smoke_targets"]
    )
    assert (
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_post_closeout_inventory"
        in readiness["production_smoke_targets"]
    )
    assert (
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_completion_archive"
        in readiness["production_smoke_targets"]
    )
    assert (
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_archive_summary"
        in readiness["production_smoke_targets"]
    )
    assert (
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_ai_summary_preflight"
        in readiness["production_smoke_targets"]
    )
    assert (
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_ai_summary_run_package"
        in readiness["production_smoke_targets"]
    )
    assert (
        "/api/market_intel/manual_sample_review/"
        "candidate_queue_review_decision_writer_status"
        in readiness["production_smoke_targets"]
    )
    assert readiness["write_approval_runbook"]["ready_for_real_write"] is False
    assert readiness["write_approval_runbook"]["writes_executed"] is False
    assert readiness["migration_blueprint"]["migration_executed"] is False
    assert readiness["migration_blueprint"]["file_created"] is True
    assert readiness["migration_blueprint"]["file_matches_blueprint"] is True
    assert readiness["migration_apply_drill"]["mode"] == "migration_apply_drill_preview"
    assert readiness["migration_apply_drill"]["migration_executed"] is False
    assert readiness["migration_apply_drill"]["rollback_executed"] is False
    assert readiness["migration_apply_drill"]["database_write_executed"] is False
    assert readiness["migration_apply_drill"]["api_executes_migration"] is False
    assert readiness["migration_catalog_review"]["mode"] == "migration_catalog_review_preview"
    assert readiness["migration_catalog_review"]["catalog_state"] == "planned_no_probe"
    assert readiness["migration_catalog_review"]["migration_executed"] is False
    assert readiness["migration_catalog_review"]["database_write_executed"] is False
    assert readiness["migration_catalog_review"]["api_executes_migration"] is False
    assert readiness["migration_live_smoke"]["mode"] == "migration_live_smoke_preview"
    assert readiness["migration_live_smoke"]["smoke_result"] == "planned_no_execution"
    assert readiness["migration_live_smoke"]["migration_executed"] is False
    assert readiness["migration_live_smoke"]["database_write_executed"] is False
    assert readiness["migration_live_smoke"]["api_executes_migration"] is False
    assert readiness["live_db_inventory"]["mode"] == "live_db_inventory_planned"
    assert readiness["live_db_inventory"]["read_only_query_executed"] is False
    assert readiness["live_db_inventory"]["database_write_executed"] is False
    assert readiness["live_db_inventory"]["migration_executed"] is False
    assert readiness["schema_db_probe"]["read_only_query_executed"] is False
    assert readiness["platform_seed_db_diff"]["read_only_query_executed"] is False
    assert readiness["legacy_source_bridge"]["read_only_query_executed"] is False
    assert readiness["mcp_readiness"]["mode"] == "mcp_readiness_planned"
    assert readiness["mcp_readiness"]["telemetry"]["read_only_query_executed"] is False
    assert readiness["mcp_tool_contract"]["contract_ready"] is True
    assert readiness["mcp_tool_contract"]["database_write_executed"] is False
    assert readiness["mcp_deploy_preflight"]["deployment_actions_executed"] is False
    assert readiness["mcp_deploy_preflight"]["docker_command_executed"] is False
    assert readiness["mcp_activation_runbook"]["deployment_actions_executed"] is False
    assert readiness["mcp_activation_runbook"]["docker_command_executed"] is False
    assert readiness["mcp_fetch_gate"]["network_request_allowed"] is False
    assert readiness["mcp_fetch_gate"]["external_network_executed"] is False
    assert readiness["manual_sample_plan"]["mode"] == "manual_sample_fetch_plan_preview"
    assert readiness["manual_sample_plan"]["sample_fetch_executed"] is False
    assert readiness["manual_sample_plan"]["external_network_executed"] is False
    assert readiness["manual_sample_plan"]["database_write_executed"] is False
    assert readiness["manual_sample_plan"]["scheduler_attached"] is False
    assert readiness["manual_sample_acceptance"]["mode"] == "manual_sample_acceptance_preview"
    assert readiness["manual_sample_acceptance"]["sample_result_loaded"] is False
    assert readiness["manual_sample_acceptance"]["candidate_import_allowed"] is False
    assert readiness["manual_sample_acceptance"]["external_network_executed"] is False
    assert readiness["manual_sample_acceptance"]["database_write_executed"] is False
    assert readiness["manual_sample_acceptance"]["scheduler_attached"] is False
    assert readiness["manual_sample_review"]["mode"] == "manual_sample_review_preview"
    assert readiness["manual_sample_review"]["sample_result_loaded"] is False
    assert readiness["manual_sample_review"]["sample_result_reviewed"] is False
    assert readiness["manual_sample_review"]["candidate_import_allowed"] is False
    assert readiness["manual_sample_review"]["external_network_executed"] is False
    assert readiness["manual_sample_review"]["database_write_executed"] is False
    assert readiness["manual_sample_review"]["scheduler_attached"] is False
    assert (
        readiness["manual_sample_review_evaluation"]["mode"]
        == "manual_sample_review_evaluation_preview"
    )
    assert readiness["manual_sample_review_evaluation"]["payload_received"] is True
    assert readiness["manual_sample_review_evaluation"]["payload_persisted"] is False
    assert readiness["manual_sample_review_evaluation"]["sample_result_persisted"] is False
    assert (
        readiness["manual_sample_review_evaluation"]["candidate_import_allowed"]
        is False
    )
    assert (
        readiness["manual_sample_review_evaluation"]["external_network_executed"]
        is False
    )
    assert (
        readiness["manual_sample_review_evaluation"]["database_write_executed"]
        is False
    )
    assert readiness["manual_sample_review_evaluation"]["scheduler_attached"] is False
    assert (
        readiness["manual_sample_candidate_handoff"]["mode"]
        == "manual_sample_candidate_handoff_preview"
    )
    assert readiness["manual_sample_candidate_handoff"]["payload_received"] is True
    assert readiness["manual_sample_candidate_handoff"]["payload_persisted"] is False
    assert (
        readiness["manual_sample_candidate_handoff"]["candidate_handoff_persisted"]
        is False
    )
    assert (
        readiness["manual_sample_candidate_handoff"]["candidate_import_allowed"]
        is False
    )
    assert (
        readiness["manual_sample_candidate_handoff"]["external_network_executed"]
        is False
    )
    assert (
        readiness["manual_sample_candidate_handoff"]["database_write_executed"]
        is False
    )
    assert readiness["manual_sample_candidate_handoff"]["scheduler_attached"] is False
    assert (
        readiness["manual_sample_candidate_queue_draft"]["mode"]
        == "manual_sample_candidate_queue_draft_preview"
    )
    assert (
        readiness["manual_sample_candidate_queue_draft"]["payload_received"]
        is True
    )
    assert (
        readiness["manual_sample_candidate_queue_draft"]["payload_persisted"]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_draft"]["review_queue_created"]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_draft"]["review_queue_persisted"]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_draft"]["candidate_import_allowed"]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_draft"]["external_network_executed"]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_draft"]["database_write_executed"]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_draft"]["scheduler_attached"]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_approval"]["mode"]
        == "manual_sample_candidate_queue_approval_preview"
    )
    assert (
        readiness["manual_sample_candidate_queue_approval"]["payload_received"]
        is True
    )
    assert (
        readiness["manual_sample_candidate_queue_approval"]["payload_persisted"]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_approval"][
            "approval_request_created"
        ]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_approval"][
            "approval_record_written"
        ]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_approval"][
            "review_queue_write_allowed"
        ]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_approval"]["review_queue_created"]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_approval"][
            "review_queue_persisted"
        ]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_approval"][
            "candidate_import_allowed"
        ]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_approval"][
            "external_network_executed"
        ]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_approval"][
            "database_write_executed"
        ]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_approval"]["scheduler_attached"]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_transaction"]["mode"]
        == "manual_sample_candidate_queue_transaction_preview"
    )
    assert (
        readiness["manual_sample_candidate_queue_transaction"]["payload_received"]
        is True
    )
    assert (
        readiness["manual_sample_candidate_queue_transaction"]["payload_persisted"]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_transaction"]["transaction_ready"]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_transaction"]["transaction_opened"]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_transaction"]["transaction_committed"]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_transaction"][
            "approval_record_written"
        ]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_transaction"]["review_queue_created"]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_transaction"][
            "review_queue_persisted"
        ]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_transaction"][
            "candidate_import_allowed"
        ]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_transaction"][
            "external_network_executed"
        ]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_transaction"][
            "database_write_executed"
        ]
        is False
    )
    assert (
        readiness["manual_sample_candidate_queue_transaction"]["scheduler_attached"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_cli_status"]["mode"]
        == "candidate_queue_writer_cli_blocked"
    )
    assert (
        readiness["candidate_queue_writer_cli_status"]["ready_for_real_write"]
        is False
    )
    assert readiness["candidate_queue_writer_cli_status"]["writes_executed"] is False
    assert (
        readiness["candidate_queue_writer_cli_status"]["would_write_database"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_cli_status"]["database_connection_opened"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_cli_status"]["explicit_transaction_opened"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_cli_status"]["database_write_executed"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_cli_status"]["database_commit_executed"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_cli_status"]["scheduler_attached"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_preflight"]["mode"]
        == "candidate_queue_writer_preflight_planned"
    )
    assert (
        readiness["candidate_queue_writer_preflight"]["read_only_query_executed"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_preflight"]["database_connection_opened"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_preflight"]["database_write_executed"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_preflight"]["database_commit_executed"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_preflight"]["scheduler_attached"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_postwrite_smoke"]["mode"]
        == "candidate_queue_writer_postwrite_smoke_planned"
    )
    assert (
        readiness["candidate_queue_writer_postwrite_smoke"][
            "read_only_query_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_writer_postwrite_smoke"][
            "database_connection_opened"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_writer_postwrite_smoke"][
            "database_write_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_writer_postwrite_smoke"][
            "database_commit_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_writer_postwrite_smoke"]["scheduler_attached"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_operator_drill"]["mode"]
        == "candidate_queue_writer_operator_drill_preview"
    )
    assert (
        readiness["candidate_queue_writer_operator_drill"]["api_executes_cli"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_operator_drill"][
            "api_reads_approval_token"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_writer_operator_drill"][
            "database_connection_opened"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_writer_operator_drill"][
            "database_write_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_writer_operator_drill"][
            "database_commit_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_writer_operator_drill"]["scheduler_attached"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_run_package"]["mode"]
        == "candidate_queue_writer_run_package_preview"
    )
    assert (
        readiness["candidate_queue_writer_run_package"]["package_artifact_created"]
        is False
    )
    assert readiness["candidate_queue_writer_run_package"]["api_writes_file"] is False
    assert (
        readiness["candidate_queue_writer_run_package"]["api_executes_cli"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_run_package"]["api_reads_approval_token"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_run_package"][
            "database_connection_opened"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_writer_run_package"]["database_write_executed"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_run_package"]["database_commit_executed"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_run_package"]["scheduler_attached"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_run_readiness"]["mode"]
        == "candidate_queue_writer_run_readiness_preview"
    )
    assert (
        readiness["candidate_queue_writer_run_readiness"][
            "ready_for_api_database_write"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_writer_run_readiness"]["api_executes_cli"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_run_readiness"][
            "api_reads_approval_token"
        ]
        is False
    )
    assert readiness["candidate_queue_writer_run_readiness"]["api_writes_file"] is False
    assert (
        readiness["candidate_queue_writer_run_readiness"][
            "database_connection_opened"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_writer_run_readiness"][
            "database_write_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_writer_run_readiness"][
            "database_commit_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_writer_run_readiness"]["scheduler_attached"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_run_receipt"]["mode"]
        == "candidate_queue_writer_run_receipt_preview"
    )
    assert (
        readiness["candidate_queue_writer_run_receipt"]["ready_for_api_database_write"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_run_receipt"]["ready_for_scheduler_attach"]
        is False
    )
    assert readiness["candidate_queue_writer_run_receipt"]["api_executes_cli"] is False
    assert (
        readiness["candidate_queue_writer_run_receipt"]["api_reads_approval_token"]
        is False
    )
    assert readiness["candidate_queue_writer_run_receipt"]["api_writes_file"] is False
    assert (
        readiness["candidate_queue_writer_run_receipt"]["database_connection_opened"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_run_receipt"]["database_write_executed"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_run_receipt"]["database_commit_executed"]
        is False
    )
    assert readiness["candidate_queue_writer_run_receipt"]["scheduler_attached"] is False
    assert (
        readiness["candidate_queue_writer_run_closeout"]["mode"]
        == "candidate_queue_writer_run_closeout_preview"
    )
    assert readiness["candidate_queue_writer_run_closeout"]["closeout_passed"] is False
    assert (
        readiness["candidate_queue_writer_run_closeout"]["ready_for_api_database_write"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_run_closeout"]["ready_for_scheduler_attach"]
        is False
    )
    assert readiness["candidate_queue_writer_run_closeout"]["api_executes_cli"] is False
    assert (
        readiness["candidate_queue_writer_run_closeout"]["api_reads_approval_token"]
        is False
    )
    assert readiness["candidate_queue_writer_run_closeout"]["api_writes_file"] is False
    assert (
        readiness["candidate_queue_writer_run_closeout"]["database_connection_opened"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_run_closeout"]["database_write_executed"]
        is False
    )
    assert (
        readiness["candidate_queue_writer_run_closeout"]["database_commit_executed"]
        is False
    )
    assert readiness["candidate_queue_writer_run_closeout"]["scheduler_attached"] is False
    assert (
        readiness["candidate_queue_review_handoff"]["mode"]
        == "candidate_queue_review_handoff_preview"
    )
    assert readiness["candidate_queue_review_handoff"]["handoff_ready"] is False
    assert (
        readiness["candidate_queue_review_handoff"]["ready_for_api_database_write"]
        is False
    )
    assert (
        readiness["candidate_queue_review_handoff"]["ready_for_scheduler_attach"]
        is False
    )
    assert readiness["candidate_queue_review_handoff"]["api_executes_cli"] is False
    assert (
        readiness["candidate_queue_review_handoff"]["api_reads_approval_token"]
        is False
    )
    assert (
        readiness["candidate_queue_review_handoff"]["api_writes_database"]
        is False
    )
    assert (
        readiness["candidate_queue_review_handoff"]["api_updates_review_state"]
        is False
    )
    assert (
        readiness["candidate_queue_review_handoff"]["database_connection_opened"]
        is False
    )
    assert (
        readiness["candidate_queue_review_handoff"]["database_write_executed"]
        is False
    )
    assert (
        readiness["candidate_queue_review_handoff"]["database_commit_executed"]
        is False
    )
    assert readiness["candidate_queue_review_handoff"]["scheduler_attached"] is False
    assert (
        readiness["candidate_queue_review_inventory"]["mode"]
        == "candidate_queue_review_inventory_preview"
    )
    assert (
        readiness["candidate_queue_review_inventory"]["review_inventory_ready"]
        is False
    )
    assert (
        readiness["candidate_queue_review_inventory"][
            "ready_for_api_review_state_update"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_inventory"][
            "ready_for_api_database_write"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_inventory"]["api_updates_review_state"]
        is False
    )
    assert (
        readiness["candidate_queue_review_inventory"]["read_only_query_executed"]
        is False
    )
    assert (
        readiness["candidate_queue_review_inventory"]["database_connection_opened"]
        is False
    )
    assert (
        readiness["candidate_queue_review_inventory"]["database_write_executed"]
        is False
    )
    assert (
        readiness["candidate_queue_review_inventory"]["database_commit_executed"]
        is False
    )
    assert readiness["candidate_queue_review_inventory"]["scheduler_attached"] is False
    assert (
        readiness["candidate_queue_review_decision"]["mode"]
        == "candidate_queue_review_decision_preview"
    )
    assert readiness["candidate_queue_review_decision"]["decision_ready"] is False
    assert (
        readiness["candidate_queue_review_decision"][
            "ready_for_api_review_state_update"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision"]["api_updates_review_state"]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision"]["decision_record_written"]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision"][
            "review_state_update_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision"]["database_write_executed"]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision"]["database_commit_executed"]
        is False
    )
    assert readiness["candidate_queue_review_decision"]["scheduler_attached"] is False
    assert (
        readiness["candidate_queue_review_decision_approval"]["mode"]
        == "candidate_queue_review_decision_approval_preview"
    )
    assert (
        readiness["candidate_queue_review_decision_approval"]["approval_ready"]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_approval"][
            "ready_for_api_review_state_update"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_approval"][
            "ready_for_api_database_write"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_approval"][
            "api_updates_review_state"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_approval"][
            "approval_record_written"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_approval"][
            "decision_record_written"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_approval"][
            "review_state_update_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_approval"][
            "database_write_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_approval"][
            "database_commit_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_approval"]["scheduler_attached"]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_transaction"]["mode"]
        == "candidate_queue_review_decision_transaction_preview"
    )
    assert (
        readiness["candidate_queue_review_decision_transaction"][
            "transaction_preview_created"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_transaction"][
            "transaction_ready"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_transaction"][
            "ready_for_api_review_state_update"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_transaction"][
            "api_updates_review_state"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_transaction"][
            "approval_record_written"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_transaction"][
            "decision_record_written"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_transaction"][
            "review_state_update_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_transaction"][
            "database_connection_opened"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_transaction"][
            "transaction_opened"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_transaction"][
            "transaction_committed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_transaction"][
            "database_write_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_transaction"][
            "database_commit_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_transaction"][
            "scheduler_attached"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_preflight"]["mode"]
        == "candidate_queue_review_decision_writer_preflight_preview"
    )
    assert (
        readiness["candidate_queue_review_decision_writer_preflight"][
            "preflight_payload_ready"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_preflight"][
            "ready_for_api_review_state_update"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_preflight"][
            "api_updates_review_state"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_preflight"][
            "read_only_query_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_preflight"][
            "database_connection_opened"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_preflight"][
            "database_write_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_preflight"][
            "database_commit_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_preflight"][
            "review_state_update_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_preflight"][
            "scheduler_attached"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_postwrite_smoke"]["mode"]
        == "candidate_queue_review_decision_writer_postwrite_smoke_planned"
    )
    assert (
        readiness["candidate_queue_review_decision_writer_postwrite_smoke"][
            "read_only_query_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_postwrite_smoke"][
            "database_connection_opened"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_postwrite_smoke"][
            "database_write_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_postwrite_smoke"][
            "database_commit_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_postwrite_smoke"][
            "review_state_update_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_postwrite_smoke"][
            "api_updates_review_state"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_postwrite_smoke"][
            "scheduler_attached"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_operator_drill"]["mode"]
        == "candidate_queue_review_decision_writer_operator_drill_preview"
    )
    assert (
        readiness["candidate_queue_review_decision_writer_operator_drill"][
            "api_executes_cli"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_operator_drill"][
            "api_reads_approval_token"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_operator_drill"][
            "api_updates_review_state"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_operator_drill"][
            "database_connection_opened"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_operator_drill"][
            "database_write_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_operator_drill"][
            "database_commit_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_operator_drill"][
            "review_state_update_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_operator_drill"][
            "scheduler_attached"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_package"]["mode"]
        == "candidate_queue_review_decision_writer_run_package_preview"
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_package"][
            "package_artifact_created"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_package"][
            "api_writes_file"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_package"][
            "api_executes_cli"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_package"][
            "api_reads_approval_token"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_package"][
            "api_updates_review_state"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_package"][
            "database_write_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_package"][
            "scheduler_attached"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_readiness"]["mode"]
        == "candidate_queue_review_decision_writer_run_readiness_preview"
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_readiness"][
            "ready_for_api_review_state_update"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_readiness"][
            "ready_for_api_database_write"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_readiness"][
            "api_executes_cli"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_readiness"][
            "api_reads_approval_token"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_readiness"][
            "api_updates_review_state"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_readiness"][
            "review_state_update_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_readiness"][
            "database_write_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_readiness"][
            "scheduler_attached"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_receipt"]["mode"]
        == "candidate_queue_review_decision_writer_run_receipt_preview"
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_receipt"][
            "ready_for_api_review_state_update"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_receipt"][
            "ready_for_api_database_write"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_receipt"][
            "api_executes_cli"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_receipt"][
            "api_reads_approval_token"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_receipt"][
            "api_updates_review_state"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_receipt"][
            "review_state_update_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_receipt"][
            "database_write_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_receipt"][
            "scheduler_attached"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_closeout"]["mode"]
        == "candidate_queue_review_decision_writer_run_closeout_preview"
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_closeout"][
            "closeout_passed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_closeout"][
            "ready_for_api_review_state_update"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_closeout"][
            "ready_for_api_database_write"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_closeout"][
            "api_executes_cli"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_closeout"][
            "api_reads_approval_token"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_closeout"][
            "api_updates_review_state"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_closeout"][
            "review_state_update_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_closeout"][
            "database_write_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_run_closeout"][
            "scheduler_attached"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_post_closeout_inventory"][
            "mode"
        ]
        == "candidate_queue_review_decision_post_closeout_inventory_preview"
    )
    assert (
        readiness["candidate_queue_review_decision_post_closeout_inventory"][
            "post_closeout_inventory_ready"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_post_closeout_inventory"][
            "ready_for_api_review_state_update"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_post_closeout_inventory"][
            "ready_for_api_database_write"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_post_closeout_inventory"][
            "api_executes_cli"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_post_closeout_inventory"][
            "api_reads_approval_token"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_post_closeout_inventory"][
            "api_updates_review_state"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_post_closeout_inventory"][
            "review_state_update_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_post_closeout_inventory"][
            "read_only_query_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_post_closeout_inventory"][
            "database_write_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_post_closeout_inventory"][
            "scheduler_attached"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_completion_archive"]["mode"]
        == "candidate_queue_review_completion_archive_preview"
    )
    assert (
        readiness["candidate_queue_review_completion_archive"][
            "review_completion_archive_ready"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_completion_archive"][
            "archive_manifest_ready"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_completion_archive"][
            "ready_for_api_review_state_update"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_completion_archive"][
            "ready_for_api_database_write"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_completion_archive"]["api_executes_cli"]
        is False
    )
    assert (
        readiness["candidate_queue_review_completion_archive"][
            "api_reads_approval_token"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_completion_archive"][
            "api_updates_review_state"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_completion_archive"][
            "archive_file_written"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_completion_archive"][
            "archive_record_written"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_completion_archive"][
            "review_state_update_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_completion_archive"][
            "read_only_query_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_completion_archive"][
            "database_write_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_completion_archive"][
            "scheduler_attached"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_archive_summary"]["mode"]
        == "candidate_queue_review_archive_summary_preview"
    )
    assert (
        readiness["candidate_queue_review_archive_summary"][
            "archive_summary_ready"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_archive_summary"][
            "summary_input_ready"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_archive_summary"][
            "ready_for_ai_summary_generation"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_archive_summary"]["ready_for_llm_call"]
        is False
    )
    assert (
        readiness["candidate_queue_review_archive_summary"][
            "ready_for_telegram_dispatch"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_archive_summary"][
            "api_reads_approval_token"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_archive_summary"][
            "api_updates_review_state"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_archive_summary"][
            "summary_file_written"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_archive_summary"][
            "ai_summary_generated"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_archive_summary"]["llm_call_executed"]
        is False
    )
    assert (
        readiness["candidate_queue_review_archive_summary"][
            "telegram_dispatched"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_archive_summary"][
            "database_write_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_archive_summary"]["scheduler_attached"]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_preflight"]["mode"]
        == "candidate_queue_review_ai_summary_preflight_preview"
    )
    assert (
        readiness["candidate_queue_review_ai_summary_preflight"][
            "ai_summary_preflight_ready"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_preflight"][
            "ready_for_manual_ollama_summary_run"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_preflight"][
            "ready_for_ai_summary_generation"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_preflight"][
            "ready_for_llm_call"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_preflight"][
            "ready_for_telegram_dispatch"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_preflight"][
            "api_reads_approval_token"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_preflight"][
            "api_writes_file"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_preflight"][
            "summary_file_written"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_preflight"][
            "summary_record_written"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_preflight"][
            "ai_summary_generated"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_preflight"][
            "llm_call_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_preflight"][
            "ollama_call_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_preflight"][
            "gemini_call_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_preflight"][
            "telegram_dispatched"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_preflight"][
            "database_write_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_preflight"][
            "scheduler_attached"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_preflight"][
            "model_route_policy"
        ]["primary_policy"]
        == "ollama_first"
    )
    assert (
        readiness["candidate_queue_review_ai_summary_run_package"]["mode"]
        == "candidate_queue_review_ai_summary_run_package_preview"
    )
    assert (
        readiness["candidate_queue_review_ai_summary_run_package"][
            "ai_summary_run_package_ready"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_run_package"][
            "ready_for_manual_ollama_summary_run"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_run_package"][
            "ready_for_ai_summary_generation"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_run_package"][
            "ready_for_llm_call"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_run_package"][
            "ready_for_telegram_dispatch"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_run_package"][
            "api_executes_llm"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_run_package"][
            "run_package_file_written"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_run_package"][
            "summary_file_written"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_run_package"][
            "ai_summary_generated"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_run_package"][
            "llm_call_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_run_package"][
            "ollama_call_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_run_package"][
            "gemini_call_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_run_package"][
            "telegram_dispatched"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_run_package"][
            "database_write_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_run_package"][
            "scheduler_attached"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_ai_summary_run_package"][
            "summary_output_schema"
        ]["schema_version"]
        == "market_intel_ai_summary_v1"
    )
    assert (
        readiness["candidate_queue_review_decision_writer_status"]["mode"]
        == "candidate_queue_review_decision_writer_cli_blocked"
    )
    assert (
        readiness["candidate_queue_review_decision_writer_status"][
            "ready_for_real_write"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_status"][
            "writer_implementation_enabled"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_status"][
            "api_updates_review_state"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_status"][
            "review_state_update_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_status"][
            "database_write_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_status"][
            "database_commit_executed"
        ]
        is False
    )
    assert (
        readiness["candidate_queue_review_decision_writer_status"][
            "scheduler_attached"
        ]
        is False
    )
    assert readiness["scheduler_plan"]["scheduler_registration_executed"] is False
    assert readiness["scheduler_plan"]["crawler_job_started"] is False
    assert readiness["scheduler_plan"]["database_write_executed"] is False
    assert readiness["match_review_plan"]["review_queue_created"] is False
    assert readiness["match_review_plan"]["auto_confirm_executed"] is False
    assert readiness["match_review_plan"]["database_write_executed"] is False
    assert readiness["opportunity_plan"]["opportunity_queue_created"] is False
    assert readiness["opportunity_plan"]["threat_alert_dispatched"] is False
    assert readiness["opportunity_plan"]["database_write_executed"] is False
    assert readiness["opportunity_scoring_plan"]["scoring_job_created"] is False
    assert readiness["opportunity_scoring_plan"]["score_calculation_executed"] is False
    assert readiness["opportunity_scoring_plan"]["database_write_executed"] is False
    assert readiness["opportunity_evidence_plan"]["evidence_bundle_created"] is False
    assert readiness["opportunity_evidence_plan"]["evidence_query_executed"] is False
    assert readiness["opportunity_evidence_plan"]["database_write_executed"] is False
    assert readiness["opportunity_alert_plan"]["alert_candidate_created"] is False
    assert readiness["opportunity_alert_plan"]["review_queue_contract_written"] is False
    assert readiness["opportunity_alert_plan"]["review_queue_table_created"] is False
    assert readiness["opportunity_alert_plan"]["review_action_executed"] is False
    assert readiness["opportunity_alert_plan"]["approval_record_written"] is False
    assert readiness["opportunity_alert_plan"]["telegram_dispatched"] is False
    assert readiness["opportunity_alert_plan"]["llm_call_executed"] is False
    assert readiness["opportunity_alert_plan"]["database_write_executed"] is False


def test_market_intel_service_keeps_readiness_modularized():
    service_path = Path("services/market_intel/service.py")
    readiness_path = Path("services/market_intel/deployment_readiness.py")

    assert service_path.exists()
    assert readiness_path.exists()
    assert len(service_path.read_text().splitlines()) < 800
    assert "build_deployment_readiness_preview" in readiness_path.read_text()


def test_write_approval_runbook_is_read_only_and_blocks_real_write():
    runbook = MarketIntelService().build_write_approval_runbook()
    gate_keys = {gate["key"] for gate in runbook["approval_gates"]}

    assert runbook["mode"] == "approval_runbook_read_only"
    assert runbook["ready_for_real_write"] is False
    assert runbook["writes_executed"] is False
    assert runbook["would_write_database"] is False
    assert runbook["database_session_created"] is False
    assert runbook["database_commit_executed"] is False
    assert runbook["external_network_executed"] is False
    assert runbook["scheduler_attached"] is False
    assert runbook["approval_required"] is True
    assert runbook["approval_token_present"] is False
    assert runbook["seed_count"] == 4
    assert runbook["writer_operation_count"] == 4
    assert runbook["schema_smoke"]["passed"] is True
    assert "schema_smoke_passed" in gate_keys
    assert "backup_completed" in gate_keys
    assert "migration_file_reviewed" in gate_keys
    assert "manual_operator_approval" in gate_keys
    assert "database_write_allowed" in runbook["blocked_reasons"]
    assert "manual_operator_approval" in runbook["blocked_reasons"]
    assert "no_momo_db_container_lifecycle_change" in runbook["hard_safety_boundaries"]
    assert "no_remove_orphans" in runbook["hard_safety_boundaries"]


def test_migration_blueprint_is_additive_preview_only():
    blueprint = MarketIntelService().build_migration_blueprint()
    forward_sql_lower = blueprint["forward_sql"].lower()
    migration_file = Path(blueprint["suggested_filename"])

    assert blueprint["mode"] == "migration_file_draft_read_only"
    assert blueprint["suggested_filename"] == "migrations/032_market_intel_core_schema.sql"
    assert blueprint["file_created"] is True
    assert blueprint["file_matches_blueprint"] is True
    assert blueprint["file_status"] == "local_draft_matches_blueprint"
    assert blueprint["migration_executed"] is False
    assert blueprint["database_session_created"] is False
    assert blueprint["database_commit_executed"] is False
    assert blueprint["external_network_executed"] is False
    assert blueprint["scheduler_attached"] is False
    assert blueprint["table_count"] == 8
    assert blueprint["forward_has_destructive_sql"] is False
    assert blueprint["safety_checks"]["forward_sql_additive_only"] is True
    assert blueprint["safety_checks"]["writes_seed_rows_only_with_cli_apply_flag"] is True
    assert "migration_not_executed" in blueprint["blocked_reasons"]
    assert "migration_file_not_created" not in blueprint["blocked_reasons"]
    assert "seed_writer_real_write_requires_cli_apply_flag" in blueprint["blocked_reasons"]
    assert migration_file.exists()
    assert migration_file.read_text(encoding="utf-8").strip() == blueprint["forward_sql"]
    assert "CREATE TABLE IF NOT EXISTS market_platforms".lower() in forward_sql_lower
    assert "CREATE TABLE IF NOT EXISTS market_crawler_runs".lower() in forward_sql_lower
    assert "CREATE TABLE IF NOT EXISTS market_alert_review_queue".lower() in forward_sql_lower
    assert "ux_market_alert_review_queue_dedupe".lower() in forward_sql_lower
    assert "drop table" not in forward_sql_lower
    assert "truncate " not in forward_sql_lower
    assert "delete from" not in forward_sql_lower
    assert "MARKET_INTEL_CRAWLER_ENABLED=false" in blueprint["command_plan"]["seed_writer_command"]["command"]
    assert blueprint["command_plan"]["seed_writer_command"]["script_created"] is True
    assert blueprint["command_plan"]["seed_writer_command"]["script_path"] == "scripts/market_intel_seed_writer.py"
    assert blueprint["rollback_requires_manual_approval"] is True
    assert "DROP TABLE IF EXISTS market_alert_review_queue" in blueprint["rollback_sql"]


def test_migration_apply_drill_planned_is_safe_and_manual_only():
    drill = MarketIntelService().build_migration_apply_drill()

    assert drill["mode"] == "migration_apply_drill_preview"
    assert drill["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert drill["execute_requested"] is False
    assert drill["schema_state"] == "planned_no_db_probe"
    assert drill["drill_ready_for_operator_review"] is True
    assert drill["ready_for_manual_apply_review"] is False
    assert drill["ready_to_apply_migration"] is False
    assert drill["read_only_query_executed"] is False
    assert drill["database_connection_opened"] is False
    assert drill["database_session_created"] is False
    assert drill["database_write_executed"] is False
    assert drill["database_commit_executed"] is False
    assert drill["migration_executed"] is False
    assert drill["rollback_executed"] is False
    assert drill["api_executes_migration"] is False
    assert drill["api_executes_rollback"] is False
    assert drill["checks"]["migration_file_matches_blueprint"] is True
    assert drill["checks"]["forward_sql_additive_only"] is True
    assert "read_only_db_probe_not_executed" in drill["blocked_reasons"]
    assert "api_never_runs_migration" in drill["blocked_reasons"]
    assert drill["rollback_drill"]["rollback_executed"] is False
    assert drill["rollback_drill"]["requires_manual_approval"] is True
    assert "market_alert_review_queue" in drill["rollback_drill"]["rollback_table_order"]
    assert len(drill["pre_apply_checklist"]) >= 6
    assert len(drill["post_apply_verification"]) >= 4
    assert len(drill["risk_register"]) >= 4


def test_migration_apply_drill_sqlite_read_only_reports_already_applied():
    service = MarketIntelService()
    seed_rows = service.build_platform_seed_plan()["seeds"]
    engine = create_engine("sqlite:///:memory:")
    with engine.begin() as conn:
        conn.execute(
            text(
                """
                CREATE TABLE market_platforms (
                    code TEXT PRIMARY KEY,
                    name TEXT,
                    base_url TEXT,
                    enabled BOOLEAN,
                    crawl_policy_json TEXT
                )
                """
            )
        )
        for table_name in MARKET_INTEL_TABLES:
            if table_name == "market_platforms":
                continue
            conn.execute(text(f"CREATE TABLE {table_name} (id INTEGER PRIMARY KEY)"))
        for seed in seed_rows:
            conn.execute(
                text(
                    """
                    INSERT INTO market_platforms
                        (code, name, base_url, enabled, crawl_policy_json)
                    VALUES
                        (:code, :name, :base_url, :enabled, :crawl_policy_json)
                    """
                ),
                {
                    "code": seed["code"],
                    "name": seed["name"],
                    "base_url": seed["base_url"],
                    "enabled": seed["enabled"],
                    "crawl_policy_json": json.dumps(
                        seed["crawl_policy_json"],
                        ensure_ascii=False,
                        sort_keys=True,
                    ),
                },
            )

    drill = service.build_migration_apply_drill(
        execute_requested=True,
        schema_engine=engine,
        seed_diff_engine=engine,
        database_type="sqlite",
    )

    assert drill["mode"] == "migration_apply_drill_preview"
    assert drill["execute_requested"] is True
    assert drill["read_only_query_executed"] is True
    assert drill["database_connection_opened"] is True
    assert drill["schema_state"] == "already_applied"
    assert drill["schema_db_probe_summary"]["schema_tables_exist"] is True
    assert drill["schema_db_probe_summary"]["missing_tables"] == []
    assert drill["platform_seed_db_diff_summary"]["seed_rows_ready"] is True
    assert set(drill["platform_seed_db_diff_summary"]["matching_codes"]) == {
        "momo",
        "pchome",
        "coupang",
        "shopee",
    }
    assert drill["database_session_created"] is False
    assert drill["database_write_executed"] is False
    assert drill["database_commit_executed"] is False
    assert drill["migration_executed"] is False
    assert "market_schema_already_present_apply_not_required" in drill["blocked_reasons"]


def test_migration_apply_drill_route_is_preview_only():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.get("/api/market_intel/migration_apply_drill?execute=false")
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "migration_apply_drill_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["execute_requested"] is False
    assert data["migration_executed"] is False
    assert data["rollback_executed"] is False
    assert data["database_write_executed"] is False
    assert data["api_executes_migration"] is False


def test_migration_catalog_review_planned_is_safe_and_diagnostic():
    review = MarketIntelService().build_migration_catalog_review()

    assert review["mode"] == "migration_catalog_review_preview"
    assert review["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert review["execute_requested"] is False
    assert review["catalog_state"] == "planned_no_probe"
    assert review["seed_state"] == "planned_no_probe"
    assert review["risk_level"] == "info"
    assert review["apply_path"] == "run_execute_true_read_only_probe_first"
    assert review["review_ready"] is True
    assert review["ready_for_manual_migration_review"] is False
    assert review["ready_to_apply_migration"] is False
    assert review["read_only_query_executed"] is False
    assert review["database_connection_opened"] is False
    assert review["database_session_created"] is False
    assert review["database_write_executed"] is False
    assert review["database_commit_executed"] is False
    assert review["migration_executed"] is False
    assert review["rollback_executed"] is False
    assert review["api_executes_migration"] is False
    assert review["table_catalog"]["expected_count"] == 8
    assert review["table_catalog"]["existing_count"] == 0
    assert review["table_catalog"]["missing_count"] == 8
    assert "execute_false_planned_only" in review["blocked_reasons"]
    assert "migration_not_executed_by_catalog_review" in review["blocked_reasons"]
    assert {item["key"] for item in review["findings"]} >= {
        "catalog_probe_not_executed",
        "seed_diff_not_executed",
    }


def test_migration_catalog_review_sqlite_read_only_detects_partial_schema():
    service = MarketIntelService()
    seed_rows = service.build_platform_seed_plan()["seeds"]
    engine = create_engine("sqlite:///:memory:")
    with engine.begin() as conn:
        conn.execute(
            text(
                """
                CREATE TABLE market_platforms (
                    code TEXT PRIMARY KEY,
                    name TEXT,
                    base_url TEXT,
                    enabled BOOLEAN,
                    crawl_policy_json TEXT
                )
                """
            )
        )
        for seed in seed_rows:
            conn.execute(
                text(
                    """
                    INSERT INTO market_platforms
                        (code, name, base_url, enabled, crawl_policy_json)
                    VALUES
                        (:code, :name, :base_url, :enabled, :crawl_policy_json)
                    """
                ),
                {
                    "code": seed["code"],
                    "name": seed["name"],
                    "base_url": seed["base_url"],
                    "enabled": seed["enabled"],
                    "crawl_policy_json": json.dumps(
                        seed["crawl_policy_json"],
                        ensure_ascii=False,
                        sort_keys=True,
                    ),
                },
            )

    review = service.build_migration_catalog_review(
        execute_requested=True,
        schema_engine=engine,
        seed_diff_engine=engine,
        database_type="sqlite",
    )

    assert review["mode"] == "migration_catalog_review_preview"
    assert review["execute_requested"] is True
    assert review["read_only_query_executed"] is True
    assert review["database_connection_opened"] is True
    assert review["catalog_state"] == "partial_schema"
    assert review["seed_state"] == "ready"
    assert review["risk_level"] == "high"
    assert review["apply_path"] == "blocked_until_partial_schema_reviewed"
    assert review["ready_for_manual_migration_review"] is False
    assert review["table_catalog"]["expected_count"] == 8
    assert review["table_catalog"]["existing_count"] == 1
    assert review["table_catalog"]["missing_count"] == 7
    assert review["seed_catalog"]["seed_rows_ready"] is True
    assert "partial_schema_requires_manual_reconciliation" in review["blocked_reasons"]
    assert review["database_session_created"] is False
    assert review["database_write_executed"] is False
    assert review["database_commit_executed"] is False
    assert review["migration_executed"] is False
    assert {item["key"] for item in review["findings"]} >= {
        "partial_market_schema_detected",
        "platform_seed_ready",
    }


def test_migration_catalog_review_route_is_preview_only():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.get("/api/market_intel/migration_catalog_review?execute=false")
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "migration_catalog_review_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["execute_requested"] is False
    assert data["catalog_state"] == "planned_no_probe"
    assert data["migration_executed"] is False
    assert data["rollback_executed"] is False
    assert data["database_write_executed"] is False
    assert data["api_executes_migration"] is False


def test_migration_live_smoke_planned_is_preview_only():
    smoke = MarketIntelService().build_migration_live_smoke()

    assert smoke["mode"] == "migration_live_smoke_preview"
    assert smoke["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert smoke["execute_requested"] is False
    assert smoke["smoke_result"] == "planned_no_execution"
    assert smoke["live_smoke_passed"] is False
    assert smoke["catalog_state"] == "planned_no_probe"
    assert smoke["seed_state"] == "planned_no_probe"
    assert smoke["read_only_probe_completed"] is False
    assert smoke["database_connection_opened"] is False
    assert smoke["database_session_created"] is False
    assert smoke["database_write_executed"] is False
    assert smoke["database_commit_executed"] is False
    assert smoke["migration_executed"] is False
    assert smoke["rollback_executed"] is False
    assert smoke["api_executes_migration"] is False
    assert "execute_false_planned_only" in smoke["blocked_reasons"]
    assert "migration_not_executed_by_live_smoke" in smoke["blocked_reasons"]


def test_migration_live_smoke_sqlite_not_applied_tolerates_seed_table_missing():
    service = MarketIntelService()
    engine = create_engine("sqlite:///:memory:")

    smoke = service.build_migration_live_smoke(
        execute_requested=True,
        schema_engine=engine,
        seed_diff_engine=engine,
        database_type="sqlite",
    )

    assert smoke["mode"] == "migration_live_smoke_preview"
    assert smoke["execute_requested"] is True
    assert smoke["read_only_query_executed"] is True
    assert smoke["database_connection_opened"] is True
    assert smoke["catalog_state"] == "not_applied"
    assert smoke["seed_state"] == "probe_error"
    assert smoke["seed_probe_error_tolerated"] is True
    assert smoke["smoke_result"] == "passed_not_applied_seed_table_missing"
    assert smoke["live_smoke_passed"] is True
    assert smoke["read_only_probe_completed"] is True
    assert smoke["ready_for_manual_migration_review"] is True
    assert smoke["database_session_created"] is False
    assert smoke["database_write_executed"] is False
    assert smoke["database_commit_executed"] is False
    assert smoke["migration_executed"] is False
    assert smoke["catalog_review_summary"]["table_catalog"]["missing_count"] == 8


def test_migration_live_smoke_route_is_preview_only():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.get("/api/market_intel/migration_live_smoke?execute=false")
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "migration_live_smoke_preview"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["execute_requested"] is False
    assert data["smoke_result"] == "planned_no_execution"
    assert data["migration_executed"] is False
    assert data["rollback_executed"] is False
    assert data["database_write_executed"] is False
    assert data["api_executes_migration"] is False


def test_live_db_inventory_planned_is_preview_only():
    inventory = MarketIntelService().build_live_db_inventory()

    assert inventory["mode"] == "live_db_inventory_planned"
    assert inventory["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert inventory["execute_requested"] is False
    assert inventory["read_only_query_executed"] is False
    assert inventory["database_connection_opened"] is False
    assert inventory["database_session_created"] is False
    assert inventory["database_write_executed"] is False
    assert inventory["database_commit_executed"] is False
    assert inventory["migration_executed"] is False
    assert inventory["external_network_executed"] is False
    assert inventory["scheduler_attached"] is False
    assert inventory["summary_ready"] is False
    assert inventory["total_rows"] == 0
    assert "execute_false_planned_only" in inventory["blocked_reasons"]
    assert "inventory_not_loaded" in inventory["blocked_reasons"]


def test_live_db_inventory_sqlite_read_only_counts_market_tables():
    engine = create_engine("sqlite:///:memory:")
    with engine.begin() as conn:
        conn.execute(text("CREATE TABLE market_platforms (code TEXT, name TEXT, enabled BOOLEAN)"))
        conn.execute(text("CREATE TABLE market_campaigns (platform_code TEXT, status TEXT)"))
        conn.execute(text("CREATE TABLE market_campaign_snapshots (status TEXT)"))
        conn.execute(
            text(
                "CREATE TABLE market_campaign_products "
                "(platform_code TEXT, is_active BOOLEAN, last_seen_at TEXT, discount_rate FLOAT)"
            )
        )
        conn.execute(
            text(
                "CREATE TABLE market_product_price_history "
                "(platform_code TEXT, crawled_at TEXT, price FLOAT)"
            )
        )
        conn.execute(
            text(
                "CREATE TABLE market_product_matches "
                "(match_status TEXT, match_score FLOAT, reviewed_at TEXT)"
            )
        )
        conn.execute(
            text(
                "CREATE TABLE market_crawler_runs "
                "(platform_code TEXT, status TEXT, dry_run BOOLEAN, started_at TEXT, finished_at TEXT, error_count INTEGER)"
            )
        )
        conn.execute(
            text(
                "CREATE TABLE market_alert_review_queue "
                "(review_state TEXT, priority_lane TEXT, total_score FLOAT, updated_at TEXT)"
            )
        )
        conn.execute(
            text(
                "INSERT INTO market_platforms (code, name, enabled) "
                "VALUES ('momo', 'MOMO', 0), ('pchome', 'PChome', 0)"
            )
        )
        conn.execute(
            text(
                "INSERT INTO market_campaigns (platform_code, status) "
                "VALUES ('momo', 'active'), ('pchome', 'unknown')"
            )
        )
        conn.execute(text("INSERT INTO market_campaign_snapshots (status) VALUES ('success')"))
        conn.execute(
            text(
                "INSERT INTO market_campaign_products "
                "(platform_code, is_active, last_seen_at, discount_rate) "
                "VALUES ('momo', 1, '2026-05-18 09:00:00', 0.2), "
                "('pchome', 0, '2026-05-18 08:00:00', 0.1)"
            )
        )
        conn.execute(
            text(
                "INSERT INTO market_product_price_history (platform_code, crawled_at, price) "
                "VALUES ('momo', '2026-05-18 09:00:00', 199)"
            )
        )
        conn.execute(
            text(
                "INSERT INTO market_product_matches (match_status, match_score, reviewed_at) "
                "VALUES ('needs_review', 0.72, NULL), ('confirmed', 0.91, '2026-05-18 10:00:00')"
            )
        )
        conn.execute(
            text(
                "INSERT INTO market_crawler_runs "
                "(platform_code, status, dry_run, started_at, finished_at, error_count) "
                "VALUES ('momo', 'success', 1, '2026-05-18 09:00:00', '2026-05-18 09:01:00', 0)"
            )
        )
        conn.execute(
            text(
                "INSERT INTO market_alert_review_queue "
                "(review_state, priority_lane, total_score, updated_at) "
                "VALUES ('draft', 'watch', 0.61, '2026-05-18 11:00:00')"
            )
        )

    inventory = build_live_db_inventory_preview(
        MARKET_INTEL_TABLES,
        execute_requested=True,
        engine=engine,
        database_type="sqlite",
    )

    assert inventory["mode"] == "live_db_inventory_read_only"
    assert inventory["execute_requested"] is True
    assert inventory["read_only_query_executed"] is True
    assert inventory["database_connection_opened"] is True
    assert inventory["database_session_created"] is False
    assert inventory["database_write_executed"] is False
    assert inventory["database_commit_executed"] is False
    assert inventory["migration_executed"] is False
    assert inventory["external_network_executed"] is False
    assert inventory["scheduler_attached"] is False
    assert inventory["missing_tables"] == []
    assert inventory["summary_ready"] is True
    assert inventory["table_counts"]["market_platforms"] == 2
    assert inventory["table_counts"]["market_campaign_products"] == 2
    assert inventory["total_rows"] == 12
    assert {item["code"] for item in inventory["platform_breakdown"]} == {"momo", "pchome"}
    assert {item["status"] for item in inventory["campaign_status_breakdown"]} == {"active", "unknown"}
    assert {item["match_status"] for item in inventory["match_status_breakdown"]} == {"confirmed", "needs_review"}
    assert inventory["alert_review_state_breakdown"][0]["review_state"] == "draft"
    assert inventory["crawler_run_summary"][0]["status"] == "success"


def test_live_db_inventory_route_is_preview_only():
    from routes.market_intel_routes import market_intel_bp

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.get("/api/market_intel/live_db_inventory?execute=false")
    data = response.get_json()

    assert response.status_code == 200
    assert data["mode"] == "live_db_inventory_planned"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["execute_requested"] is False
    assert data["read_only_query_executed"] is False
    assert data["database_write_executed"] is False
    assert data["migration_executed"] is False


def test_seed_writer_cli_status_blocks_real_write():
    status = MarketIntelService().build_seed_writer_cli_status(
        platform_code="all",
        execute_requested=True,
        approval_token=TEST_APPROVAL_TOKEN,
        approval_token_secret=TEST_APPROVAL_TOKEN,
    )

    assert status["mode"] == "seed_writer_cli_blocked"
    assert status["execute_requested"] is True
    assert status["apply_real_write_requested"] is False
    assert status["approval_token_present"] is True
    assert status["approval_token_valid"] is True
    assert status["approval_token_secret_configured"] is True
    assert "approval_token_hint" not in status
    assert status["ready_for_real_write"] is False
    assert status["writes_executed"] is False
    assert status["would_write_database"] is False
    assert status["database_session_created"] is False
    assert status["explicit_transaction_opened"] is False
    assert status["database_write_executed"] is False
    assert status["database_commit_executed"] is False
    assert status["external_network_executed"] is False
    assert status["scheduler_attached"] is False
    assert status["exit_code"] == 2
    assert "apply_real_write_requested" in status["blocked_reasons"]
    assert "approval_token_valid" not in status["blocked_reasons"]
    preview = status["transaction_preview"]
    assert preview["mode"] == "seed_transaction_preview_no_session"
    assert preview["statement_count"] == 4
    assert preview["database_session_created"] is False
    assert preview["transaction_opened"] is False
    assert preview["database_commit_executed"] is False
    assert preview["database_snapshot_loaded"] is False
    assert preview["statements"][0]["table"] == "market_platforms"
    assert preview["statements"][0]["diff_status"] == "not_loaded_no_db_session"
    assert "ON CONFLICT (code) DO UPDATE SET" in preview["statements"][0]["sql_template"]
    assert preview["statements"][0]["parameter_payload_hash"]
    assert status["safety_contract"]["refuses_execute_without_apply_flag"] is True
    assert status["safety_contract"]["keeps_crawler_disabled_for_seed_write"] is True
    assert status["safety_contract"]["uses_core_connection_not_orm_session"] is True


def test_seed_writer_cli_status_route_never_leaks_approval_token(monkeypatch):
    from routes.market_intel_routes import market_intel_bp

    monkeypatch.setenv("MARKET_INTEL_SEED_WRITE_APPROVAL", TEST_APPROVAL_TOKEN)

    app = Flask(__name__)
    app.secret_key = "test-secret"
    app.register_blueprint(market_intel_bp)
    client = app.test_client()
    with client.session_transaction() as session:
        session["logged_in"] = True

    response = client.get("/api/market_intel/seed_writer_cli_status?execute=true&platform=all")
    data = response.get_json()
    payload = json.dumps(data, ensure_ascii=False, sort_keys=True)

    assert response.status_code == 200
    assert data["mode"] == "seed_writer_cli_blocked"
    assert data["execute_requested"] is True
    assert data["apply_real_write_requested"] is False
    assert data["approval_token_present"] is False
    assert data["approval_token_valid"] is False
    assert data["approval_token_secret_configured"] is True
    assert data["ready_for_real_write"] is False
    assert data["writes_executed"] is False
    assert data["would_write_database"] is False
    assert data["database_session_created"] is False
    assert data["database_commit_executed"] is False
    assert "approval_token_present" in data["blocked_reasons"]
    assert "approval_token_valid" in data["blocked_reasons"]
    assert "apply_real_write_requested" in data["blocked_reasons"]
    assert "approval_token_hint" not in payload
    assert TEST_APPROVAL_TOKEN not in payload
    assert "APPROVED_MARKET_INTEL_SEED_WRITE" not in payload


def test_seed_writer_cli_real_write_sqlite_upserts_seed_rows():
    engine = create_engine("sqlite:///:memory:")
    with engine.begin() as conn:
        conn.execute(
            text(
                """
                CREATE TABLE market_platforms (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    code TEXT NOT NULL UNIQUE,
                    name TEXT NOT NULL,
                    base_url TEXT,
                    enabled BOOLEAN NOT NULL DEFAULT 0,
                    crawl_policy_json TEXT,
                    created_at TEXT NOT NULL,
                    updated_at TEXT NOT NULL
                )
                """
            )
        )

    status = MarketIntelService().build_seed_writer_cli_status(
        platform_code="all",
        execute_requested=True,
        apply_real_write=True,
        approval_token=TEST_APPROVAL_TOKEN,
        approval_token_secret=TEST_APPROVAL_TOKEN,
        engine=engine,
        database_type="sqlite",
    )

    with engine.connect() as conn:
        rows = conn.execute(
            text("SELECT code, enabled FROM market_platforms ORDER BY code")
        ).fetchall()

    assert status["mode"] == "seed_writer_cli_executed"
    assert status["ready_for_real_write"] is True
    assert status["writes_executed"] is True
    assert status["would_write_database"] is True
    assert status["database_connection_opened"] is True
    assert status["database_session_created"] is False
    assert status["explicit_transaction_opened"] is True
    assert status["database_write_executed"] is True
    assert status["database_commit_executed"] is True
    assert status["database_rollback_executed"] is False
    assert status["external_network_executed"] is False
    assert status["scheduler_attached"] is False
    assert status["exit_code"] == 0
    assert status["blocked_reasons"] == []
    assert status["execution_result"]["inserted_codes"] == [
        "momo",
        "pchome",
        "coupang",
        "shopee",
    ]
    assert status["execution_result"]["updated_codes"] == []
    assert [row[0] for row in rows] == ["coupang", "momo", "pchome", "shopee"]
    assert all(row[1] in (False, 0) for row in rows)


def test_seed_writer_cli_script_outputs_blocked_plan():
    env = {
        **os.environ,
        "MOMO_ALLOW_INSECURE_CONFIG_FOR_TESTS": "true",
        "SECRET_KEY": "test",
        "LOGIN_PASSWORD": "test",
    }
    result = subprocess.run(
        [sys.executable, "scripts/market_intel_seed_writer.py", "--platform", "all"],
        capture_output=True,
        check=False,
        env=env,
        text=True,
    )
    data = json.loads(result.stdout)

    assert result.returncode == 0
    assert data["mode"] == "seed_writer_cli_blocked"
    assert data["execute_requested"] is False
    assert data["apply_real_write_requested"] is False
    assert data["writes_executed"] is False
    assert data["database_session_created"] is False
    assert data["database_commit_executed"] is False
    assert data["exit_code"] == 0
    assert data["transaction_preview"]["statement_count"] == 4
    assert data["transaction_preview"]["transaction_opened"] is False


def test_candidate_queue_writer_cli_script_outputs_blocked_gate(tmp_path):
    sample_file = tmp_path / "sample.json"
    sample_file.write_text(
        json.dumps(
            {
                "batch_id": "sample-batch-15",
                "platform_code": "momo",
                "source_key": "homepage",
                "source_url": "https://www.momoshop.com.tw/",
                "status": "fetched",
                "status_code": 200,
                "content_length": 1700,
                "page_hash": "c" * 64,
                "title": "MOMO 活動",
                "diagnostics": {
                    "link_count": 1,
                    "same_host_link_count": 1,
                    "campaign_link_candidates": [
                        {
                            "confidence_band": "high",
                            "score": 94,
                            "url": "https://www.momoshop.com.tw/activity/sample",
                            "text": "品牌活動",
                        },
                    ],
                },
            },
            ensure_ascii=False,
        ),
        encoding="utf-8",
    )
    env = {
        **os.environ,
        "MOMO_ALLOW_INSECURE_CONFIG_FOR_TESTS": "true",
        "SECRET_KEY": "test",
        "LOGIN_PASSWORD": "test",
    }
    result = subprocess.run(
        [
            sys.executable,
            "scripts/market_intel_candidate_queue_writer.py",
            "--sample-json",
            str(sample_file),
        ],
        capture_output=True,
        check=False,
        env=env,
        text=True,
    )
    data = json.loads(result.stdout)

    assert result.returncode == 0
    assert data["mode"] == "candidate_queue_writer_cli_blocked"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["execute_requested"] is False
    assert data["apply_real_write_requested"] is False
    assert data["writes_executed"] is False
    assert data["database_connection_opened"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["transaction_preview_summary"]["statement_count"] == 1
    assert "execute_requested" in data["blocked_reasons"]


def test_review_decision_writer_cli_script_outputs_blocked_gate_without_login_env():
    env = {
        key: value
        for key, value in os.environ.items()
        if key not in {"LOGIN_PASSWORD", "SECRET_KEY"}
    }
    result = subprocess.run(
        [sys.executable, "scripts/market_intel_review_decision_writer.py"],
        capture_output=True,
        check=False,
        env=env,
        text=True,
    )
    data = json.loads(result.stdout)

    assert result.returncode == 0
    assert data["mode"] == "candidate_queue_review_decision_writer_cli_blocked"
    assert data["phase"] == "phase_81_candidate_queue_review_ai_summary_run_package"
    assert data["execute_requested"] is False
    assert data["apply_real_write_requested"] is False
    assert data["approval_token_present"] is False
    assert data["writer_implementation_enabled"] is False
    assert data["ready_for_real_write"] is False
    assert data["api_executes_cli"] is False
    assert data["api_reads_approval_token"] is False
    assert data["database_connection_opened"] is False
    assert data["database_write_executed"] is False
    assert data["database_commit_executed"] is False
    assert data["scheduler_attached"] is False
    assert data["writes_executed"] is False
    assert data["exit_code"] == 0
