"""Coordinator + council delivery E2E cases for the live delivery battery.

These exercise the async seam that unit tests mock heavily:

  kanban workers finish → guard-marked delivery user bubble → (optional) parent
  synthesis wake → board/council pointer cleared.

Coordinator cases use a minimal 2-task DAG (root + child) under an isolated tenant
with ``origin_thread_id`` wired to a fresh chat thread. Council cases spawn via
``/council`` (slash override) — expensive (3 real MLX seats); long timeouts.

Imported by ``kernel_live_delivery_battery.py``.
"""
from __future__ import annotations

from scripts.kernel_live_delivery_types import DeliveryCase

_DOC = "docs/validator-api.md"

_KANBAN_RESULT_HINT = (
    "End your final assistant message with a valid ```kanban-result``` fence "
    "(summary ≥48 chars). Use read_file/list_directory only — no web search."
)

DELIVERY_CASES: list[DeliveryCase] = [
    # ── Coordinator: fan-out/fan-in → single batch-terminal delivery ─────────
    DeliveryCase(
        id="coordinator_batch_delivery",
        pillar="coordinator",
        seed="coordinator_batch",
        batch_items=[
            {
                "title": "Delivery battery: coordinator root",
                "assignee": "general",
                "body": (
                    "Emit a kanban-result whose summary states ROOT_PLAN is complete. "
                    "No file reads required. "
                    f"{_KANBAN_RESULT_HINT}"
                ),
                "priority": 4,
                "metadata": {
                    "acceptance": {
                        "min_summary_chars": 32,
                        "reject_deferred_prose": True,
                    }
                },
            },
            {
                "title": "Delivery battery: coordinator child read",
                "assignee": "general",
                "parent_index": 0,
                "body": (
                    f"Call read_file on {_DOC} (first 18 lines). Summarize which "
                    "module the file documents (name 'validation' or 'validator' "
                    "must appear in your summary). "
                    f"{_KANBAN_RESULT_HINT}"
                ),
                "priority": 4,
                "metadata": {
                    "acceptance": {
                        "min_summary_chars": 48,
                        "reject_deferred_prose": True,
                    }
                },
            },
        ],
        expect_task_count=2,
        expect_tasks_done=2,
        timeout_sec=420.0,
        max_guard_deliveries=1,
        require_delivery_banner_substrings=("batch finished",),
        require_delivery_body_substrings=("validation",),
        expect_coordinator_inactive=True,
        wait_parent_synthesis=True,
        synthesis_timeout_sec=300.0,
        # Monitor-only: the delivery seam is exercised, but PASS requires both workers
        # to produce model-content that meets acceptance (min_summary_chars, the
        # 'validation' token). That is nondeterministic under soak, so a failure here
        # is observability, not a gate. The deterministic delivery contract lives in
        # the HTTP-forced failure-path cases below (partial failure / no-early-wake).
        monitor_only=True,
        notes=(
            "Golden path (MONITOR-ONLY): 2-task coordinator DAG → exactly one "
            "batch-terminal delivery → coordinator board inactive → parent synthesis "
            "reply. Non-gating because success depends on model content."
        ),
    ),
    # ── Council: Researcher → Verifier → Contrarian → delivery wake ───────────
    DeliveryCase(
        id="council_seats_delivery",
        pillar="council",
        seed="council_slash",
        council_frame=(
            "For auditing docs/validator-api.md in the workspace, is read_file "
            "alone sufficient for a one-line module summary, or is grep needed?"
        ),
        expect_task_count=3,
        expect_tasks_done=3,
        timeout_sec=1200.0,
        poll_sec=8.0,
        max_guard_deliveries=1,
        require_delivery_banner_substrings=("council seats finished",),
        expect_council_inactive=True,
        wait_parent_synthesis=True,
        synthesis_timeout_sec=360.0,
        # Monitor-only: a full 3-seat council happy path depends on model behavior —
        # e.g. the Verifier legitimately rejecting claims cancels the Contrarian, which
        # is correct pipeline behavior but not the success this case asserts. Reported,
        # never gating. The deterministic council contract is council_failure_delivery
        # (HTTP-forced Contrarian block → failure delivery).
        monitor_only=True,
        notes=(
            "Full council pipeline (3 MLX seats), MONITOR-ONLY. Fails closed on "
            "Lucas/metadata issues; long timeout. Slash spawn bypasses offer flow. "
            "Non-gating because seat outcomes are model-dependent."
        ),
    ),
    # ── Coordinator: partial failure delivery (root done, child blocked) ───────
    DeliveryCase(
        id="coordinator_partial_failure_delivery",
        pillar="coordinator",
        seed="coordinator_block_child",
        batch_items=[
            {
                "title": "Delivery battery: partial root",
                "assignee": "general",
                "body": (
                    "Emit a kanban-result whose summary states PARTIAL_ROOT done. "
                    "No file reads. "
                    f"{_KANBAN_RESULT_HINT}"
                ),
                "priority": 4,
                "metadata": {
                    "acceptance": {
                        "min_summary_chars": 32,
                        "reject_deferred_prose": True,
                    }
                },
            },
            {
                "title": "Delivery battery: partial child (blocked by harness)",
                "assignee": "general",
                "parent_index": 0,
                "body": (
                    f"Call read_file on {_DOC} (first 12 lines) and summarize. "
                    f"{_KANBAN_RESULT_HINT}"
                ),
                "priority": 4,
                "metadata": {
                    "acceptance": {
                        "min_summary_chars": 48,
                        "reject_deferred_prose": True,
                    }
                },
            },
        ],
        expect_task_count=2,
        expect_tasks_done=1,
        expect_tasks_failed=1,
        timeout_sec=480.0,
        max_guard_deliveries=1,
        require_delivery_banner_substrings=("batch finished",),
        require_delivery_body_substrings=("partial failure",),
        expect_coordinator_inactive=True,
        wait_parent_synthesis=True,
        synthesis_timeout_sec=300.0,
        notes="Root succeeds; harness blocks child → partial-failure batch delivery.",
    ),
    # ── Coordinator: no delivery until entire batch terminal ─────────────────
    DeliveryCase(
        id="coordinator_no_early_wake",
        pillar="coordinator",
        seed="coordinator_batch",
        batch_items=[
            {
                "title": "Delivery battery: early-wake root",
                "assignee": "general",
                "body": (
                    "Emit kanban-result summary ROOT_EARLY done. No tools. "
                    f"{_KANBAN_RESULT_HINT}"
                ),
                "priority": 4,
                "metadata": {
                    "acceptance": {
                        "min_summary_chars": 32,
                        "reject_deferred_prose": True,
                    }
                },
            },
            {
                "title": "Delivery battery: early-wake child read",
                "assignee": "general",
                "parent_index": 0,
                "body": (
                    f"Call read_file on {_DOC} (first 15 lines). Summarize the module. "
                    f"{_KANBAN_RESULT_HINT}"
                ),
                "priority": 4,
                "metadata": {
                    "acceptance": {
                        "min_summary_chars": 48,
                        "reject_deferred_prose": True,
                    }
                },
            },
        ],
        expect_task_count=2,
        expect_tasks_done=2,
        timeout_sec=420.0,
        assert_no_delivery_before_all_terminal=True,
        max_guard_deliveries=1,
        require_delivery_banner_substrings=("batch finished",),
        expect_coordinator_inactive=True,
        wait_parent_synthesis=False,
        notes="While child is open, root done must not deliver/wake parent thread.",
    ),
    # ── Council: forced seat failure → failure delivery, no success synthesis ──
    DeliveryCase(
        id="council_failure_delivery",
        pillar="council",
        seed="council_block_contrarian",
        council_frame=(
            "For docs/validator-api.md, is read_file alone enough for a one-line "
            "module summary?"
        ),
        expect_task_count=3,
        expect_tasks_done=2,
        expect_tasks_failed=1,
        timeout_sec=900.0,
        poll_sec=6.0,
        max_guard_deliveries=1,
        require_delivery_banner_substrings=("could not complete",),
        forbid_delivery_banner_substrings=("seats finished",),
        expect_council_inactive=True,
        wait_parent_synthesis=True,
        synthesis_timeout_sec=300.0,
        notes=(
            "After Researcher+Verifier finish, HTTP-block Contrarian → pipeline "
            "failure delivery (deterministic unhappy path)."
        ),
    ),
]
