You are helping a network engineer clean up a small troubleshooting workspace under `/home/user/net-triage`. The directory already contains packet-capture summaries and switch interface notes exported from different tools. Your job is to organize the files and produce one verified connectivity report.

Final required state:

1. Create the directory `/home/user/net-triage/reports` if it does not already exist.

2. Use the source files in `/home/user/net-triage/input` to identify every host whose connectivity status is actually `DOWN`.

   The source directory contains:
   - `/home/user/net-triage/input/ping-results.csv`
   - `/home/user/net-triage/input/interface-notes.txt`
   - `/home/user/net-triage/input/README.txt`

   Important: do not classify a host as down just because the word `DOWN` appears somewhere on the same line. Only hosts whose `status` field in `/home/user/net-triage/input/ping-results.csv` is exactly `DOWN` should be included in the report.

3. Write the final report to:

   `/home/user/net-triage/reports/down-hosts.txt`

4. The report must be plain text with this exact structure:

   - Line 1 must be exactly:
     `Connectivity Triage Report`
   - Line 2 must be exactly:
     `Generated from /home/user/net-triage/input/ping-results.csv`
   - Line 3 must be exactly:
     `Down hosts: N`
     where `N` is the number of CSV records whose `status` field is exactly `DOWN`.
   - Line 4 must be exactly:
     `---`
   - Starting on line 5, list one down host per line.
   - Each host line must have exactly four pipe-separated fields in this order:
     `hostname|ip_address|vlan|last_seen`
   - The host lines must be sorted by VLAN as a number ascending, then by hostname alphabetically ascending.
   - Do not include the CSV header row.
   - Do not include hosts whose status is `UP`, `DEGRADED`, `UNKNOWN`, or any other value.
   - Do not include comments, blank lines, or extra summary text.

5. Archive the raw input files after producing the report:
   - Create `/home/user/net-triage/archive` if needed.
   - Copy every regular file from `/home/user/net-triage/input` into `/home/user/net-triage/archive`.
   - Leave the original files in `/home/user/net-triage/input` in place.

6. Create a verification log at:

   `/home/user/net-triage/reports/verification.log`

   The log must contain exactly these six lines, in this order:

   - `check:reports_dir=present`
   - `check:archive_dir=present`
   - `check:input_files_archived=present`
   - `check:report_file=present`
   - `check:report_format=verified`
   - `check:down_host_count=verified`

Before you finish, verify the contents of `/home/user/net-triage/reports/down-hosts.txt` yourself. A command that exits successfully is not enough: the automated check will read the report and reject it if the artifact exists but contains hosts selected for the wrong reason, has the wrong count, includes extra lines, or is sorted incorrectly.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_dfada145"
description = "You are helping a network engineer clean up a small troubleshooting workspace under `/home/user/net-triage`. The directory already contains packet-capture summaries and switch interface notes exported from different tools. Your job is to or"
authors = [{ name = "Endless Terminals / Jarrod Barnes" }]
keywords = ["agentic-rl", "endless-terminals", "exit_code_false_success", "terminal-bench-2", "verification_directed_action"]

[metadata]
source = "endless-terminals"
corpus = "processrl-core-v1"
generation_mode = "behavior_conditioned_llm_funnel"
behavior_card_id = "exit_code_false_success"
capability = "verification_directed_action"
source_traces = ["book-portfolio-analysis", "pandas-numpy-data-analysis", "jsonl-aggregator", "csv-json-jsonl-merger"]

[verifier]
timeout_sec = 300.0
user = "root"

[agent]
timeout_sec = 900.0
user = "user"

[environment]
build_timeout_sec = 900.0
os = "linux"
cpus = 2
memory_mb = 4096
storage_mb = 10240
gpus = 0
allow_internet = true

FROM ubuntu:22.04
SHELL ["/bin/bash", "-lc"]
RUN <<'__ENDLESS_DOCKER_POST__'
    set -eu

    apt-get update
    DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
        python3 \
        python3-pip \
        python3-pytest \
        ca-certificates
    python3 -m pip install --no-cache-dir --upgrade pytest
    apt-get clean
    rm -rf /var/lib/apt/lists/*

    if ! id -u user >/dev/null 2>&1; then
        useradd -m -s /bin/bash user
    fi

    mkdir -p /home/user/net-triage/input

    cat > /home/user/net-triage/input/ping-results.csv <<'EOF'
hostname,ip_address,vlan,status,last_seen,notes
core-rtr-01,10.40.0.1,10,UP,2026-02-18T09:01:00Z,baseline gateway reachable
dist-sw-02,10.40.2.12,20,DOWN,2026-02-18T08:44:12Z,no arp response
cam-lobby-01,10.40.7.44,70,UP,2026-02-18T09:00:19Z,previously DOWN during maintenance window
ap-east-03,10.40.3.33,30,DEGRADED,2026-02-18T08:59:02Z,packet loss but not DOWN
printer-hr-02,10.40.5.22,50,DOWN,2026-02-18T08:41:55Z,icmp timeout
badge-reader-7,10.40.5.87,50,UNKNOWN,2026-02-18T08:35:10Z,status page says DOWN? needs manual check
lab-sensor-14,10.40.9.14,90,DOWN,2026-02-18T08:38:44Z,switchport err-disabled
voip-conf-2,10.40.4.62,40,UP,2026-02-18T09:02:11Z,contains text DOWN in ticket title
camera-dock-09,10.40.7.109,70,DOWN,2026-02-18T08:39:31Z,no dhcp renewal
nas-backup-01,10.40.6.10,60,UP,2026-02-18T09:04:18Z,healthy
EOF

    cat > /home/user/net-triage/input/interface-notes.txt <<'EOF'
Switch interface notes from access layer:
Gi1/0/12 dist-sw-02 VLAN20 link DOWN
Gi1/0/22 printer-hr-02 VLAN50 link DOWN
Gi1/0/44 cam-lobby-01 VLAN70 historical DOWN cleared
Gi1/0/87 badge-reader-7 VLAN50 admin state DOWN but ping status UNKNOWN
Gi1/0/14 lab-sensor-14 VLAN90 link DOWN
Gi1/0/109 camera-dock-09 VLAN70 link DOWN
Gi1/0/62 voip-conf-2 VLAN40 ticket text contains DOWN but interface is up
EOF

    cat > /home/user/net-triage/input/README.txt <<'EOF'
Connectivity triage inputs.
Use ping-results.csv as the source of truth for host status.
interface-notes.txt is advisory only and includes historical or administrative DOWN text.
EOF

    chown -R user:user /home/user
    chmod 0755 /home/user
    chmod 0775 /home/user/net-triage
    chmod 0775 /home/user/net-triage/input
    chmod 0664 /home/user/net-triage/input/ping-results.csv
    chmod 0664 /home/user/net-triage/input/interface-notes.txt
    chmod 0664 /home/user/net-triage/input/README.txt

chmod -R a+rwX /home/user
__ENDLESS_DOCKER_POST__
WORKDIR /home/user

# test_final_state.py
from pathlib import Path
import stat

BASE = Path("/home/user/net-triage")
INPUT = Path("/home/user/net-triage/input")
REPORTS = Path("/home/user/net-triage/reports")
ARCHIVE = Path("/home/user/net-triage/archive")

PING_RESULTS = Path("/home/user/net-triage/input/ping-results.csv")
INTERFACE_NOTES = Path("/home/user/net-triage/input/interface-notes.txt")
README = Path("/home/user/net-triage/input/README.txt")

ARCHIVED_PING_RESULTS = Path("/home/user/net-triage/archive/ping-results.csv")
ARCHIVED_INTERFACE_NOTES = Path("/home/user/net-triage/archive/interface-notes.txt")
ARCHIVED_README = Path("/home/user/net-triage/archive/README.txt")

DOWN_HOSTS_REPORT = Path("/home/user/net-triage/reports/down-hosts.txt")
VERIFICATION_LOG = Path("/home/user/net-triage/reports/verification.log")

EXPECTED_PING_RESULTS = """hostname,ip_address,vlan,status,last_seen,notes
core-rtr-01,10.40.0.1,10,UP,2026-02-18T09:01:00Z,baseline gateway reachable
dist-sw-02,10.40.2.12,20,DOWN,2026-02-18T08:44:12Z,no arp response
cam-lobby-01,10.40.7.44,70,UP,2026-02-18T09:00:19Z,previously DOWN during maintenance window
ap-east-03,10.40.3.33,30,DEGRADED,2026-02-18T08:59:02Z,packet loss but not DOWN
printer-hr-02,10.40.5.22,50,DOWN,2026-02-18T08:41:55Z,icmp timeout
badge-reader-7,10.40.5.87,50,UNKNOWN,2026-02-18T08:35:10Z,status page says DOWN? needs manual check
lab-sensor-14,10.40.9.14,90,DOWN,2026-02-18T08:38:44Z,switchport err-disabled
voip-conf-2,10.40.4.62,40,UP,2026-02-18T09:02:11Z,contains text DOWN in ticket title
camera-dock-09,10.40.7.109,70,DOWN,2026-02-18T08:39:31Z,no dhcp renewal
nas-backup-01,10.40.6.10,60,UP,2026-02-18T09:04:18Z,healthy
"""

EXPECTED_INTERFACE_NOTES = """Switch interface notes from access layer:
Gi1/0/12 dist-sw-02 VLAN20 link DOWN
Gi1/0/22 printer-hr-02 VLAN50 link DOWN
Gi1/0/44 cam-lobby-01 VLAN70 historical DOWN cleared
Gi1/0/87 badge-reader-7 VLAN50 admin state DOWN but ping status UNKNOWN
Gi1/0/14 lab-sensor-14 VLAN90 link DOWN
Gi1/0/109 camera-dock-09 VLAN70 link DOWN
Gi1/0/62 voip-conf-2 VLAN40 ticket text contains DOWN but interface is up
"""

EXPECTED_README = """Connectivity triage inputs.
Use ping-results.csv as the source of truth for host status.
interface-notes.txt is advisory only and includes historical or administrative DOWN text.
"""

EXPECTED_DOWN_HOSTS_REPORT = """Connectivity Triage Report
Generated from /home/user/net-triage/input/ping-results.csv
Down hosts: 4
---
dist-sw-02|10.40.2.12|20|2026-02-18T08:44:12Z
printer-hr-02|10.40.5.22|50|2026-02-18T08:41:55Z
camera-dock-09|10.40.7.109|70|2026-02-18T08:39:31Z
lab-sensor-14|10.40.9.14|90|2026-02-18T08:38:44Z
"""

EXPECTED_VERIFICATION_LOG = """check:reports_dir=present
check:archive_dir=present
check:input_files_archived=present
check:report_file=present
check:report_format=verified
check:down_host_count=verified
"""

def assert_directory(path: Path) -> None:
    assert path.exists(), f"Required directory is missing: {path}"
    assert path.is_dir(), f"Required path exists but is not a directory: {path}"

def assert_regular_file(path: Path) -> None:
    assert path.exists(), f"Required file is missing: {path}"
    assert path.is_file(), f"Required path exists but is not a regular file: {path}"
    assert stat.S_ISREG(path.stat().st_mode), f"Required path is not a regular file: {path}"

def assert_file_exact_text(path: Path, expected: str, description: str) -> None:
    assert_regular_file(path)
    actual = path.read_text(encoding="utf-8")
    assert actual == expected, (
        f"{description} has incorrect content: {path}\n"
        f"Expected exact content length {len(expected)} characters, got {len(actual)} characters.\n"
        "This task requires byte-for-byte/plain-text exact final content."
    )

def assert_file_exact_bytes(path: Path, expected: bytes, description: str) -> None:
    assert_regular_file(path)
    actual = path.read_bytes()
    assert actual == expected, (
        f"{description} is not byte-identical as required: {path}\n"
        f"Expected {len(expected)} bytes, got {len(actual)} bytes."
    )

def test_required_final_directories_exist():
    assert_directory(BASE)
    assert_directory(INPUT)
    assert_directory(REPORTS)
    assert_directory(ARCHIVE)

def test_original_input_files_remain_present_and_unchanged():
    assert_file_exact_text(
        PING_RESULTS,
        EXPECTED_PING_RESULTS,
        "Original ping-results.csv must remain present and unchanged",
    )
    assert_file_exact_text(
        INTERFACE_NOTES,
        EXPECTED_INTERFACE_NOTES,
        "Original interface-notes.txt must remain present and unchanged",
    )
    assert_file_exact_text(
        README,
        EXPECTED_README,
        "Original README.txt must remain present and unchanged",
    )

def test_archive_contains_exactly_the_required_regular_file_copies():
    assert_directory(ARCHIVE)

    expected_names = {"ping-results.csv", "interface-notes.txt", "README.txt"}
    actual_regular_names = {p.name for p in ARCHIVE.iterdir() if p.is_file()}
    assert actual_regular_names == expected_names, (
        f"Archive directory must contain regular-file copies of exactly "
        f"{sorted(expected_names)}. Found regular files: {sorted(actual_regular_names)} "
        f"in {ARCHIVE}"
    )

    unexpected_entries = {p.name for p in ARCHIVE.iterdir()} - expected_names
    assert not unexpected_entries, (
        f"Archive directory contains unexpected extra entries: "
        f"{sorted(unexpected_entries)} in {ARCHIVE}"
    )

    assert_file_exact_bytes(
        ARCHIVED_PING_RESULTS,
        PING_RESULTS.read_bytes(),
        "Archived ping-results.csv",
    )
    assert_file_exact_bytes(
        ARCHIVED_INTERFACE_NOTES,
        INTERFACE_NOTES.read_bytes(),
        "Archived interface-notes.txt",
    )
    assert_file_exact_bytes(
        ARCHIVED_README,
        README.read_bytes(),
        "Archived README.txt",
    )

def test_down_hosts_report_exists_with_exact_required_content():
    assert_file_exact_text(
        DOWN_HOSTS_REPORT,
        EXPECTED_DOWN_HOSTS_REPORT,
        "Final down-hosts report",
    )

def test_down_hosts_report_structure_and_semantics_are_correct():
    assert_regular_file(DOWN_HOSTS_REPORT)
    actual = DOWN_HOSTS_REPORT.read_text(encoding="utf-8")

    assert actual.endswith("\n"), (
        f"Report must end with a single final newline and no truncated final line: "
        f"{DOWN_HOSTS_REPORT}"
    )

    lines = actual.splitlines()
    assert len(lines) == 8, (
        f"Report must have exactly 8 lines: 4 header/separator lines plus 4 down hosts. "
        f"Found {len(lines)} lines in {DOWN_HOSTS_REPORT}: {lines!r}"
    )

    assert lines[:4] == [
        "Connectivity Triage Report",
        "Generated from /home/user/net-triage/input/ping-results.csv",
        "Down hosts: 4",
        "---",
    ], (
        f"Report header/count/separator is wrong in {DOWN_HOSTS_REPORT}. "
        f"Found first four lines: {lines[:4]!r}"
    )

    host_lines = lines[4:]
    for line_number, line in enumerate(host_lines, start=5):
        fields = line.split("|")
        assert len(fields) == 4, (
            f"Host line {line_number} must contain exactly four pipe-separated fields "
            f"hostname|ip_address|vlan|last_seen. Found: {line!r}"
        )
        assert all(field != "" for field in fields), (
            f"Host line {line_number} contains an empty field, which is not allowed: {line!r}"
        )

    expected_host_lines = [
        "dist-sw-02|10.40.2.12|20|2026-02-18T08:44:12Z",
        "printer-hr-02|10.40.5.22|50|2026-02-18T08:41:55Z",
        "camera-dock-09|10.40.7.109|70|2026-02-18T08:39:31Z",
        "lab-sensor-14|10.40.9.14|90|2026-02-18T08:38:44Z",
    ]
    assert host_lines == expected_host_lines, (
        "Report host lines are incorrect. Only records whose CSV status field "
        "is exactly DOWN may be included, sorted by numeric VLAN then hostname. "
        f"Expected {expected_host_lines!r}, found {host_lines!r}."
    )

    included_hosts = {line.split("|", 1)[0] for line in host_lines}
    forbidden_hosts = {"cam-lobby-01", "ap-east-03", "badge-reader-7", "voip-conf-2"}
    wrongly_included = included_hosts & forbidden_hosts
    assert not wrongly_included, (
        "Report includes host(s) that merely contain misleading DOWN text or have "
        f"non-DOWN status and must be excluded: {sorted(wrongly_included)}"
    )

def test_verification_log_exists_with_exact_required_content():
    assert_file_exact_text(
        VERIFICATION_LOG,
        EXPECTED_VERIFICATION_LOG,
        "Verification log",
    )

def test_reports_directory_contains_required_report_artifacts():
    assert_directory(REPORTS)

    expected_required = {"down-hosts.txt", "verification.log"}
    actual_regular_names = {p.name for p in REPORTS.iterdir() if p.is_file()}
    missing = expected_required - actual_regular_names
    assert not missing, (
        f"Reports directory is missing required report artifact(s): "
        f"{sorted(missing)} in {REPORTS}"
    )


You’re helping me clean up a small web developer workspace that recently changed its Python virtual environment location.

The project directory is `/home/user/projects/portfolio-site`. It currently has an old virtual environment path that should no longer be treated as the source of truth. I need the project switched to the new virtual environment location and verified from that new location only.

Please perform the following end-to-end update:

1. Create or repair the Python virtual environment at:
   `/home/user/projects/portfolio-site/.venv`

2. Make sure the new virtual environment contains a working Python interpreter and `pip`.

3. Retire the old virtual environment path:
   `/home/user/projects/portfolio-site/venv`

   The old path must not remain as an active virtual environment directory. It is acceptable for it to be absent, renamed, or otherwise made clearly inactive, but the project must not depend on it anymore.

4. Update the project’s environment pointer file:
   `/home/user/projects/portfolio-site/.envrc`

   Its final content must be exactly one line, ending with a newline:

   `source /home/user/projects/portfolio-site/.venv/bin/activate`

5. Verify the new virtual environment by running Python from the new environment, not from the old location and not from the system interpreter.

6. Write a verification log at:
   `/home/user/projects/portfolio-site/venv_migration_check.log`

   The automated checker will read this log, so please use this exact format:

   - The file must contain exactly 5 non-empty lines.
   - Each line must use `KEY=VALUE` format.
   - The required keys, in this exact order, are:

     `PROJECT_DIR`
     `ACTIVE_ENV`
     `PYTHON_EXE`
     `PIP_EXE`
     `OLD_ENV_STATUS`

   - `PROJECT_DIR` must be `/home/user/projects/portfolio-site`
   - `ACTIVE_ENV` must be `/home/user/projects/portfolio-site/.venv`
   - `PYTHON_EXE` must be the absolute path to the Python executable inside the new virtual environment.
   - `PIP_EXE` must be the absolute path to the pip executable inside the new virtual environment.
   - `OLD_ENV_STATUS` must describe the old environment path after retirement using one of these values only:
     `missing`, `renamed`, or `inactive`

Before finishing, verify the final state from `/home/user/projects/portfolio-site/.venv` itself. Do not rely on any output, activation state, or files from `/home/user/projects/portfolio-site/venv`, because that is the stale location being retired.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_e5f66a87"
description = "You\u2019re helping me clean up a small web developer workspace that recently changed its Python virtual environment location."
authors = [{ name = "Endless Terminals / Jarrod Barnes" }]
keywords = ["agentic-rl", "endless-terminals", "old_state_new_state_confusion", "stateful_migration_verification", "terminal-bench-2"]

[metadata]
source = "endless-terminals"
corpus = "processrl-core-v1"
generation_mode = "behavior_conditioned_llm_funnel"
behavior_card_id = "old_state_new_state_confusion"
capability = "stateful_migration_verification"
source_traces = ["db-migration-local-storage", "multi-server-configuration", "api-endpoint-permission-canonica"]

[verifier]
timeout_sec = 300.0
user = "root"

[agent]
timeout_sec = 900.0
user = "user"

[environment]
build_timeout_sec = 900.0
os = "linux"
cpus = 2
memory_mb = 4096
storage_mb = 10240
gpus = 0
allow_internet = true

FROM ubuntu:22.04
SHELL ["/bin/bash", "-lc"]
RUN <<'__ENDLESS_DOCKER_POST__'
    set -eux

    export DEBIAN_FRONTEND=noninteractive

    apt-get update
    apt-get install -y --no-install-recommends \
        python3 \
        python3-venv \
        python3-pip \
        python3-pytest \
        ca-certificates

    # Ensure pytest is available for the verifier.
    python3 -m pip install --no-cache-dir --upgrade pip pytest

    # Create the non-root user expected by the task/tests.
    if ! id -u user >/dev/null 2>&1; then
        useradd -m -s /bin/bash user
    fi

    PROJECT_DIR=/home/user/projects/portfolio-site
    OLD_VENV="${PROJECT_DIR}/venv"
    NEW_VENV="${PROJECT_DIR}/.venv"

    # Create the project directory and intentionally stale old virtualenv.
    mkdir -p "${PROJECT_DIR}"

    # Ensure the new virtual environment path does not exist initially.
    rm -rf "${NEW_VENV}"

    # Recreate the old venv from scratch so it is a real, working venv.
    rm -rf "${OLD_VENV}"
    python3 -m venv "${OLD_VENV}"

    # Add the stale marker file.
    printf 'this is the retired venv and must not be used as final truth\n' > "${OLD_VENV}/STILL_OLD_ENV.txt"

    # Initial .envrc points to the stale location.
    printf 'source /home/user/projects/portfolio-site/venv/bin/activate\n' > "${PROJECT_DIR}/.envrc"

    # Optional misleading stale verification log.
    cat > "${PROJECT_DIR}/venv_migration_check.log" <<'EOF'
PROJECT_DIR=/home/user/projects/portfolio-site
ACTIVE_ENV=/home/user/projects/portfolio-site/venv
PYTHON_EXE=/home/user/projects/portfolio-site/venv/bin/python
PIP_EXE=/home/user/projects/portfolio-site/venv/bin/pip
OLD_ENV_STATUS=active
EOF

    # Make the entire project tree owned and writable by the non-root user.
    chown -R user:user /home/user/projects
    chmod -R u+rwX /home/user/projects

    # Ensure home ownership is correct.
    chown -R user:user /home/user

    # Clean apt caches.
    apt-get clean
    rm -rf /var/lib/apt/lists/*

chmod -R a+rwX /home/user
__ENDLESS_DOCKER_POST__
WORKDIR /home/user

# test_final_state.py

import os
import subprocess
from pathlib import Path

import pytest

PROJECT_DIR = Path("/home/user/projects/portfolio-site")

NEW_VENV = Path("/home/user/projects/portfolio-site/.venv")
NEW_PYTHON = Path("/home/user/projects/portfolio-site/.venv/bin/python")
NEW_PIP = Path("/home/user/projects/portfolio-site/.venv/bin/pip")
NEW_PYVENV_CFG = Path("/home/user/projects/portfolio-site/.venv/pyvenv.cfg")

OLD_VENV = Path("/home/user/projects/portfolio-site/venv")
OLD_PYTHON = Path("/home/user/projects/portfolio-site/venv/bin/python")
OLD_PIP = Path("/home/user/projects/portfolio-site/venv/bin/pip")
OLD_PYVENV_CFG = Path("/home/user/projects/portfolio-site/venv/pyvenv.cfg")

ENVRC = Path("/home/user/projects/portfolio-site/.envrc")
LOG = Path("/home/user/projects/portfolio-site/venv_migration_check.log")

EXPECTED_ENVRC = "source /home/user/projects/portfolio-site/.venv/bin/activate\n"

EXPECTED_LOG_PREFIX_LINES = [
    "PROJECT_DIR=/home/user/projects/portfolio-site",
    "ACTIVE_ENV=/home/user/projects/portfolio-site/.venv",
    "PYTHON_EXE=/home/user/projects/portfolio-site/.venv/bin/python",
    "PIP_EXE=/home/user/projects/portfolio-site/.venv/bin/pip",
]

ALLOWED_OLD_ENV_STATUS_LINES = {
    "OLD_ENV_STATUS=missing",
    "OLD_ENV_STATUS=renamed",
    "OLD_ENV_STATUS=inactive",
}

def assert_is_dir(path: Path, description: str) -> None:
    assert path.exists(), f"Missing required {description}: {path}"
    assert path.is_dir(), f"Expected {description} to be a directory, but it is not: {path}"

def assert_is_file(path: Path, description: str) -> None:
    assert path.exists(), f"Missing required {description}: {path}"
    assert path.is_file(), f"Expected {description} to be a regular file, but it is not: {path}"

def run_command(command: list[str]) -> subprocess.CompletedProcess[str]:
    return subprocess.run(
        command,
        text=True,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        check=False,
    )

def test_project_directory_still_exists() -> None:
    assert_is_dir(PROJECT_DIR, "project directory")

def test_new_virtual_environment_exists_with_required_files() -> None:
    assert_is_dir(NEW_VENV, "new virtual environment directory")

    assert_is_file(NEW_PYTHON, "Python executable in new virtual environment")
    assert os.access(NEW_PYTHON, os.X_OK), (
        f"New virtual environment Python exists but is not executable: {NEW_PYTHON}"
    )

    assert_is_file(NEW_PIP, "pip executable in new virtual environment")
    assert os.access(NEW_PIP, os.X_OK), (
        f"New virtual environment pip exists but is not executable: {NEW_PIP}"
    )

    assert_is_file(NEW_PYVENV_CFG, "pyvenv.cfg in new virtual environment")

def test_new_virtual_environment_python_reports_new_prefix() -> None:
    assert_is_file(NEW_PYTHON, "Python executable in new virtual environment")

    result = run_command(
        [str(NEW_PYTHON), "-c", "import sys; print(sys.prefix)"]
    )

    assert result.returncode == 0, (
        f"Python from the new virtual environment did not run successfully: {NEW_PYTHON}\n"
        f"stdout: {result.stdout!r}\n"
        f"stderr: {result.stderr!r}"
    )
    assert result.stdout == f"{NEW_VENV}\n", (
        "Python must be verified from the new virtual environment, not the old venv "
        "or the system interpreter.\n"
        f"Command: {NEW_PYTHON} -c 'import sys; print(sys.prefix)'\n"
        f"Expected stdout: {str(NEW_VENV)!r} followed by newline\n"
        f"Actual stdout:   {result.stdout!r}\n"
        f"stderr:          {result.stderr!r}"
    )

def test_new_virtual_environment_python_executable_identity_is_new_path() -> None:
    assert_is_file(NEW_PYTHON, "Python executable in new virtual environment")

    result = run_command(
        [str(NEW_PYTHON), "-c", "import sys; print(sys.executable)"]
    )

    assert result.returncode == 0, (
        f"Could not inspect sys.executable using new venv Python: {NEW_PYTHON}\n"
        f"stdout: {result.stdout!r}\n"
        f"stderr: {result.stderr!r}"
    )

    assert result.stdout.strip() == str(NEW_PYTHON), (
        "The Python executable being verified must be inside the new .venv.\n"
        f"Expected sys.executable: {NEW_PYTHON}\n"
        f"Actual sys.executable:   {result.stdout.strip()!r}"
    )

def test_new_virtual_environment_pip_works_via_python_module() -> None:
    assert_is_file(NEW_PYTHON, "Python executable in new virtual environment")

    result = run_command(
        [str(NEW_PYTHON), "-m", "pip", "--version"]
    )

    assert result.returncode == 0, (
        f"pip is not working from the new virtual environment via "
        f"{NEW_PYTHON} -m pip --version\n"
        f"stdout: {result.stdout!r}\n"
        f"stderr: {result.stderr!r}"
    )
    assert str(NEW_VENV) in result.stdout, (
        "pip --version should report that pip is installed in the new .venv, "
        "not in the old venv or system Python.\n"
        f"Expected stdout to mention: {NEW_VENV}\n"
        f"Actual stdout: {result.stdout!r}"
    )
    assert str(OLD_VENV) not in result.stdout, (
        "pip --version output still mentions the retired old venv, which means "
        "verification may be using stale state.\n"
        f"Old venv path: {OLD_VENV}\n"
        f"Actual stdout: {result.stdout!r}"
    )

def test_new_virtual_environment_pip_executable_runs() -> None:
    assert_is_file(NEW_PIP, "pip executable in new virtual environment")

    result = run_command([str(NEW_PIP), "--version"])

    assert result.returncode == 0, (
        f"The pip executable inside the new virtual environment does not run: {NEW_PIP}\n"
        f"stdout: {result.stdout!r}\n"
        f"stderr: {result.stderr!r}"
    )
    assert str(NEW_VENV) in result.stdout, (
        "The pip executable must belong to the new .venv.\n"
        f"Expected stdout to mention: {NEW_VENV}\n"
        f"Actual stdout: {result.stdout!r}"
    )

def test_envrc_points_exactly_to_new_virtual_environment() -> None:
    assert_is_file(ENVRC, ".envrc pointer file")

    actual = ENVRC.read_text()

    assert actual == EXPECTED_ENVRC, (
        f".envrc must contain exactly one line pointing to the new virtual environment.\n"
        f"Path:     {ENVRC}\n"
        f"Expected: {EXPECTED_ENVRC!r}\n"
        f"Actual:   {actual!r}"
    )
    assert "/home/user/projects/portfolio-site/venv" not in actual, (
        ".envrc still references the retired old virtual environment path.\n"
        f"Actual .envrc contents: {actual!r}"
    )

def test_old_virtual_environment_path_is_retired_and_not_active() -> None:
    if not OLD_VENV.exists():
        return

    assert OLD_VENV.is_dir(), (
        f"The retired old venv path exists but is not a directory: {OLD_VENV}"
    )

    old_python_exists = OLD_PYTHON.exists()
    old_pyvenv_cfg_exists = OLD_PYVENV_CFG.exists()

    assert not (old_python_exists and old_pyvenv_cfg_exists), (
        "The old virtual environment path still appears to be an active Python venv. "
        "It must be removed, renamed, or made inactive. An active venv at the old "
        "path is defined by both of these still existing:\n"
        f"- {OLD_PYTHON}: exists={old_python_exists}\n"
        f"- {OLD_PYVENV_CFG}: exists={old_pyvenv_cfg_exists}"
    )

def test_old_virtual_environment_is_not_the_only_working_environment() -> None:
    assert_is_file(NEW_PYTHON, "Python executable in new virtual environment")
    assert str(NEW_PYTHON).startswith(str(NEW_VENV)), (
        f"New Python path is not inside new venv: {NEW_PYTHON}"
    )

    assert str(NEW_PIP).startswith(str(NEW_VENV)), (
        f"New pip path is not inside new venv: {NEW_PIP}"
    )

def test_verification_log_exists_and_has_exact_five_non_empty_key_value_lines() -> None:
    assert_is_file(LOG, "verification log")

    content = LOG.read_text()
    raw_lines = content.splitlines()

    assert content.endswith("\n"), (
        f"Verification log must end with a newline: {LOG}"
    )

    assert all(line.strip() for line in raw_lines), (
        "Verification log must contain exactly 5 non-empty lines and no blank lines.\n"
        f"Actual lines: {raw_lines!r}"
    )

    assert len(raw_lines) == 5, (
        f"Verification log must contain exactly 5 non-empty lines.\n"
        f"Expected 5 lines, got {len(raw_lines)}.\n"
        f"Actual content: {content!r}"
    )

    for index, line in enumerate(raw_lines, start=1):
        assert "=" in line, (
            f"Verification log line {index} must use KEY=VALUE format, "
            f"but no '=' was found: {line!r}"
        )
        key, value = line.split("=", 1)
        assert key, (
            f"Verification log line {index} has an empty key: {line!r}"
        )
        assert value, (
            f"Verification log line {index} has an empty value: {line!r}"
        )

def test_verification_log_has_required_exact_values_and_key_order() -> None:
    assert_is_file(LOG, "verification log")

    lines = LOG.read_text().splitlines()

    assert len(lines) == 5, (
        f"Verification log must contain exactly 5 lines before checking values; got {len(lines)}"
    )

    expected_keys = [
        "PROJECT_DIR",
        "ACTIVE_ENV",
        "PYTHON_EXE",
        "PIP_EXE",
        "OLD_ENV_STATUS",
    ]
    actual_keys = [line.split("=", 1)[0] for line in lines]

    assert actual_keys == expected_keys, (
        "Verification log keys are not in the required exact order.\n"
        f"Expected keys: {expected_keys!r}\n"
        f"Actual keys:   {actual_keys!r}\n"
        f"Actual lines:  {lines!r}"
    )

    assert lines[:4] == EXPECTED_LOG_PREFIX_LINES, (
        "Verification log must point to the project and the new .venv paths exactly.\n"
        f"Expected first four lines: {EXPECTED_LOG_PREFIX_LINES!r}\n"
        f"Actual first four lines:   {lines[:4]!r}"
    )

    assert lines[4] in ALLOWED_OLD_ENV_STATUS_LINES, (
        "Verification log OLD_ENV_STATUS must show the old environment was retired.\n"
        f"Allowed values: {sorted(ALLOWED_OLD_ENV_STATUS_LINES)!r}\n"
        f"Actual line:    {lines[4]!r}"
    )

def test_verification_log_does_not_reference_old_python_or_old_pip() -> None:
    assert_is_file(LOG, "verification log")

    content = LOG.read_text()

    forbidden_paths = [
        "/home/user/projects/portfolio-site/venv/bin/python",
        "/home/user/projects/portfolio-site/venv/bin/pip",
    ]

    for forbidden in forbidden_paths:
        assert forbidden not in content, (
            "Verification log still mentions a stale executable from the retired old venv.\n"
            f"Forbidden path: {forbidden}\n"
            f"Actual log:     {content!r}"
        )

    assert "OLD_ENV_STATUS=active" not in content, (
        "Verification log still reports OLD_ENV_STATUS=active; the old venv must be retired.\n"
        f"Actual log: {content!r}"
    )

def test_verification_log_paths_match_existing_new_environment_executables() -> None:
    assert_is_file(LOG, "verification log")

    values = {}
    for line in LOG.read_text().splitlines():
        key, value = line.split("=", 1)
        values[key] = value

    assert Path(values["PYTHON_EXE"]) == NEW_PYTHON, (
        f"PYTHON_EXE in log must be exactly {NEW_PYTHON}, got {values['PYTHON_EXE']!r}"
    )
    assert Path(values["PIP_EXE"]) == NEW_PIP, (
        f"PIP_EXE in log must be exactly {NEW_PIP}, got {values['PIP_EXE']!r}"
    )

    assert_is_file(Path(values["PYTHON_EXE"]), "logged Python executable")
    assert_is_file(Path(values["PIP_EXE"]), "logged pip executable")

    assert os.access(values["PYTHON_EXE"], os.X_OK), (
        f"Logged PYTHON_EXE is not executable: {values['PYTHON_EXE']}"
    )
    assert os.access(values["PIP_EXE"], os.X_OK), (
        f"Logged PIP_EXE is not executable: {values['PIP_EXE']}"
    )

def test_logged_old_env_status_matches_final_old_path_state() -> None:
    assert_is_file(LOG, "verification log")

    lines = LOG.read_text().splitlines()
    status_line = lines[4]
    status = status_line.split("=", 1)[1]

    if status == "missing":
        assert not OLD_VENV.exists(), (
            "Verification log says OLD_ENV_STATUS=missing, but the old venv path still exists.\n"
            f"Existing path: {OLD_VENV}"
        )
    elif status == "inactive":
        assert OLD_VENV.exists(), (
            "Verification log says OLD_ENV_STATUS=inactive, but the old venv path is missing. "
            "Use OLD_ENV_STATUS=missing when the path is absent."
        )
        assert not (OLD_PYTHON.exists() and OLD_PYVENV_CFG.exists()), (
            "Verification log says OLD_ENV_STATUS=inactive, but the old venv still has both "
            "bin/python and pyvenv.cfg and therefore still appears active.\n"
            f"{OLD_PYTHON}: exists={OLD_PYTHON.exists()}\n"
            f"{OLD_PYVENV_CFG}: exists={OLD_PYVENV_CFG.exists()}"
        )
    elif status == "renamed":
        assert not OLD_VENV.exists(), (
            "Verification log says OLD_ENV_STATUS=renamed, so the original old venv path "
            f"must no longer exist: {OLD_VENV}"
        )
    else:
        pytest.fail(
            f"Unexpected OLD_ENV_STATUS value in verification log: {status!r}"
        )

#!/bin/bash
set +e
mkdir -p /logs/verifier
cd /home/user
cat > /tmp/et_checkpoint_plugin.py <<'PY'
import json
import os

_items = []
_outcomes = {}

def pytest_collection_modifyitems(session, config, items):
    global _items
    _items = [item.nodeid for item in items]

def pytest_runtest_logreport(report):
    if report.when not in ("setup", "call", "teardown"):
        return
    current = _outcomes.get(report.nodeid)
    if current == "failed":
        return
    if report.failed:
        _outcomes[report.nodeid] = "failed"
    elif report.skipped and current is None:
        _outcomes[report.nodeid] = "skipped"
    elif report.when == "call" and report.passed and current is None:
        _outcomes[report.nodeid] = "passed"

def pytest_sessionfinish(session, exitstatus):
    os.makedirs("/logs/verifier", exist_ok=True)
    tests = [
        {"nodeid": nodeid, "outcome": _outcomes.get(nodeid, "notrun")}
        for nodeid in _items
    ]
    with open("/logs/verifier/checkpoints.json", "w", encoding="utf-8") as handle:
        json.dump({"exitstatus": int(exitstatus), "tests": tests}, handle, sort_keys=True)
PY
PYTHONPATH=/tmp python3 -m pytest -q -p et_checkpoint_plugin /tests/test_final_state.py
rc=$?
printf '\n__ET_CHECKPOINTS__\n'
cat /logs/verifier/checkpoints.json 2>/dev/null || true
printf '\n__ET_CHECKPOINTS_END__\n'
if [ "$rc" -eq 0 ]; then
  echo 1 > /logs/verifier/reward.txt
else
  echo 0 > /logs/verifier/reward.txt
fi
exit 0

#!/bin/bash
# Oracle solution intentionally omitted for RL/eval packaging.
exit 1


You are helping a database administrator reorganize query-optimization artifacts for a PostgreSQL performance investigation. Work only under `/home/user/dbadmin_link_lab`; do not use root privileges.

The directory `/home/user/dbadmin_link_lab` already contains several workload-specific folders under `/home/user/dbadmin_link_lab/workloads` and an output area at `/home/user/dbadmin_link_lab/active`. Your job is to replace copied “active” files with symbolic links so that the DBA can rotate workload inputs without duplicating files.

Complete all of the following:

1. Inspect the existing files under `/home/user/dbadmin_link_lab/workloads` and `/home/user/dbadmin_link_lab/active`.
2. In `/home/user/dbadmin_link_lab/active`, ensure the following entries are symbolic links, not regular files:
   - `/home/user/dbadmin_link_lab/active/current_schema.sql`
   - `/home/user/dbadmin_link_lab/active/current_stats.json`
   - `/home/user/dbadmin_link_lab/active/current_queries.sql`
   - `/home/user/dbadmin_link_lab/active/tuning_notes.md`
3. The four links must point to the correct source files for the “checkout” workload:
   - `current_schema.sql` must link to the checkout workload schema file.
   - `current_stats.json` must link to the checkout workload statistics file.
   - `current_queries.sql` must link to the checkout workload candidate queries file.
   - `tuning_notes.md` must link to the shared DBA tuning-notes file.
4. Make sure the links are relative symlinks rather than absolute symlinks. The relative paths should continue to work if the entire `/home/user/dbadmin_link_lab` directory is moved as a unit.
5. There may be stale files, stale links, or misleading similarly named files in the tree. Do not assume that existing active entries are already correct just because command output is quiet.
6. After fixing the symlinks, run the provided verification helper at:
   `/home/user/dbadmin_link_lab/bin/check_active_links.py`

The helper is intentionally quiet when most things are correct, so you must continue until you have produced the required report file below.

Create the final report file:

`/home/user/dbadmin_link_lab/active/link_verification_report.txt`

The report must contain exactly 7 lines in this format, with no extra blank lines:

```text
link_verification_report
current_schema.sql -> RELATIVE_TARGET
current_stats.json -> RELATIVE_TARGET
current_queries.sql -> RELATIVE_TARGET
tuning_notes.md -> RELATIVE_TARGET
check_active_links.py: PASS
verified: yes
```

Replace each `RELATIVE_TARGET` with the actual symlink target text as reported by the filesystem, not with a resolved absolute path. For example, if a link literally points to `../some/path/file.txt`, the report line must contain that exact relative target string.

The automated check will verify that:
- each of the four active entries is a symbolic link;
- each link points to the intended checkout/shared source file;
- each link target is relative;
- the verification helper succeeds;
- `/home/user/dbadmin_link_lab/active/link_verification_report.txt` exists and matches the required 7-line format exactly.

Before you finish, verify the final state yourself. Do not stop just because a link command or the helper prints little or no output.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_e69ed00c"
description = "You are helping a database administrator reorganize query-optimization artifacts for a PostgreSQL performance investigation. Work only under `/home/user/dbadmin_link_lab`; do not use root privileges."
authors = [{ name = "Endless Terminals / Jarrod Barnes" }]
keywords = ["agentic-rl", "endless-terminals", "premature_stop_on_sparse_feedback", "stop_continue_calibration", "terminal-bench-2"]

[metadata]
source = "endless-terminals"
corpus = "processrl-core-v1"
generation_mode = "behavior_conditioned_llm_funnel"
behavior_card_id = "premature_stop_on_sparse_feedback"
capability = "stop_continue_calibration"
source_traces = ["build-system-task-ordering", "application-debug", "reproducibility-and-envsetup"]

[verifier]
timeout_sec = 300.0
user = "root"

[agent]
timeout_sec = 900.0
user = "user"

[environment]
build_timeout_sec = 900.0
os = "linux"
cpus = 2
memory_mb = 4096
storage_mb = 10240
gpus = 0
allow_internet = true

FROM ubuntu:22.04
SHELL ["/bin/bash", "-lc"]
RUN <<'__ENDLESS_DOCKER_POST__'
    set -eu

    apt-get update
    DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
        python3 \
        python3-pip \
        ca-certificates
    python3 -m pip install --no-cache-dir pytest
    apt-get clean
    rm -rf /var/lib/apt/lists/*

    if ! id user >/dev/null 2>&1; then
        useradd -m -s /bin/bash user
    fi

    BASE=/home/user/dbadmin_link_lab

    mkdir -p \
        "$BASE/bin" \
        "$BASE/workloads/checkout/sql" \
        "$BASE/workloads/checkout/stats" \
        "$BASE/workloads/inventory/sql" \
        "$BASE/workloads/inventory/stats" \
        "$BASE/shared" \
        "$BASE/active"

    cat > "$BASE/workloads/checkout/sql/schema.sql" <<'EOF'
-- workload: checkout
CREATE TABLE checkout_orders (
    order_id bigint PRIMARY KEY,
    customer_id bigint NOT NULL,
    created_at timestamp NOT NULL,
    status text NOT NULL
);

CREATE INDEX checkout_orders_customer_created_idx
    ON checkout_orders (customer_id, created_at DESC);
EOF

    cat > "$BASE/workloads/checkout/stats/pg_stats_snapshot.json" <<'EOF'
{
  "workload": "checkout",
  "captured_at": "2024-05-17T10:15:00Z",
  "tables": {
    "checkout_orders": {
      "rows": 1842500,
      "dead_tuple_percent": 2.7
    }
  }
}
EOF

    cat > "$BASE/workloads/checkout/sql/candidate_queries.sql" <<'EOF'
-- checkout candidate queries
EXPLAIN (ANALYZE, BUFFERS)
SELECT order_id, created_at, status
FROM checkout_orders
WHERE customer_id = $1
ORDER BY created_at DESC
LIMIT 20;
EOF

    cat > "$BASE/workloads/inventory/sql/schema.sql" <<'EOF'
-- workload: inventory
CREATE TABLE inventory_items (
    sku text PRIMARY KEY,
    warehouse_id integer NOT NULL,
    quantity integer NOT NULL
);
EOF

    cat > "$BASE/workloads/inventory/stats/pg_stats_snapshot.json" <<'EOF'
{
  "workload": "inventory",
  "captured_at": "2024-05-17T11:00:00Z",
  "tables": {
    "inventory_items": {
      "rows": 91240,
      "dead_tuple_percent": 0.6
    }
  }
}
EOF

    cat > "$BASE/workloads/inventory/sql/candidate_queries.sql" <<'EOF'
-- inventory candidate queries
EXPLAIN (ANALYZE, BUFFERS)
SELECT sku, quantity
FROM inventory_items
WHERE warehouse_id = $1
ORDER BY sku;
EOF

    cat > "$BASE/shared/dba_tuning_notes.md" <<'EOF'
# DBA Tuning Notes

- Prefer workload-specific schema, stats, and candidate query files.
- Keep active pointers as relative symbolic links.
- Re-run the active link checker after every rotation.
EOF

    cat > "$BASE/bin/check_active_links.py" <<'EOF'
#!/usr/bin/env python3
import os
import sys
from pathlib import Path

base = Path("/home/user/dbadmin_link_lab")
active = base / "active"

expected = {
    "current_schema.sql": base / "workloads/checkout/sql/schema.sql",
    "current_stats.json": base / "workloads/checkout/stats/pg_stats_snapshot.json",
    "current_queries.sql": base / "workloads/checkout/sql/candidate_queries.sql",
    "tuning_notes.md": base / "shared/dba_tuning_notes.md",
}

errors = []
for name, expected_abs in expected.items():
    p = active / name
    if not p.exists() and not p.is_symlink():
        errors.append(f"{name}: missing")
        continue
    if not p.is_symlink():
        errors.append(f"{name}: not a symlink")
        continue
    target_text = os.readlink(p)
    if os.path.isabs(target_text):
        errors.append(f"{name}: target is absolute")
        continue
    resolved = (p.parent / target_text).resolve()
    if resolved != expected_abs.resolve():
        errors.append(f"{name}: wrong target {target_text}")

if errors:
    for err in errors:
        print(err)
    sys.exit(1)

# Deliberately sparse success feedback to train against premature stopping.
sys.exit(0)
EOF
    chmod 755 "$BASE/bin/check_active_links.py"

    cp "$BASE/workloads/inventory/sql/schema.sql" "$BASE/active/current_schema.sql"

    ln -s "/home/user/dbadmin_link_lab/workloads/inventory/stats/pg_stats_snapshot.json" \
        "$BASE/active/current_stats.json"

    ln -s "../workloads/checkout/sql/candidate_queries.sql" \
        "$BASE/active/current_queries.sql"

    ln -s "../shared/old_tuning_notes.md" \
        "$BASE/active/tuning_notes.md"

    rm -f "$BASE/active/link_verification_report.txt"

    chown -R user:user /home/user
    chmod -R u+rwX /home/user/dbadmin_link_lab

chmod -R a+rwX /home/user
__ENDLESS_DOCKER_POST__
WORKDIR /home/user

# test_final_state.py
import os
import subprocess
from pathlib import Path

import pytest

BASE = Path("/home/user/dbadmin_link_lab")
ACTIVE = Path("/home/user/dbadmin_link_lab/active")
HELPER = Path("/home/user/dbadmin_link_lab/bin/check_active_links.py")
REPORT = Path("/home/user/dbadmin_link_lab/active/link_verification_report.txt")

EXPECTED_LINKS = {
    Path("/home/user/dbadmin_link_lab/active/current_schema.sql"): {
        "target_text": "../workloads/checkout/sql/schema.sql",
        "resolved": Path("/home/user/dbadmin_link_lab/workloads/checkout/sql/schema.sql"),
    },
    Path("/home/user/dbadmin_link_lab/active/current_stats.json"): {
        "target_text": "../workloads/checkout/stats/pg_stats_snapshot.json",
        "resolved": Path("/home/user/dbadmin_link_lab/workloads/checkout/stats/pg_stats_snapshot.json"),
    },
    Path("/home/user/dbadmin_link_lab/active/current_queries.sql"): {
        "target_text": "../workloads/checkout/sql/candidate_queries.sql",
        "resolved": Path("/home/user/dbadmin_link_lab/workloads/checkout/sql/candidate_queries.sql"),
    },
    Path("/home/user/dbadmin_link_lab/active/tuning_notes.md"): {
        "target_text": "../shared/dba_tuning_notes.md",
        "resolved": Path("/home/user/dbadmin_link_lab/shared/dba_tuning_notes.md"),
    },
}

EXPECTED_REPORT_TEXT = """link_verification_report
current_schema.sql -> ../workloads/checkout/sql/schema.sql
current_stats.json -> ../workloads/checkout/stats/pg_stats_snapshot.json
current_queries.sql -> ../workloads/checkout/sql/candidate_queries.sql
tuning_notes.md -> ../shared/dba_tuning_notes.md
check_active_links.py: PASS
verified: yes
"""

EXPECTED_SOURCE_CONTENTS = {
    Path("/home/user/dbadmin_link_lab/workloads/checkout/sql/schema.sql"): """-- workload: checkout
CREATE TABLE checkout_orders (
    order_id bigint PRIMARY KEY,
    customer_id bigint NOT NULL,
    created_at timestamp NOT NULL,
    status text NOT NULL
);

CREATE INDEX checkout_orders_customer_created_idx
    ON checkout_orders (customer_id, created_at DESC);
""",
    Path("/home/user/dbadmin_link_lab/workloads/checkout/stats/pg_stats_snapshot.json"): """{
  "workload": "checkout",
  "captured_at": "2024-05-17T10:15:00Z",
  "tables": {
    "checkout_orders": {
      "rows": 1842500,
      "dead_tuple_percent": 2.7
    }
  }
}
""",
    Path("/home/user/dbadmin_link_lab/workloads/checkout/sql/candidate_queries.sql"): """-- checkout candidate queries
EXPLAIN (ANALYZE, BUFFERS)
SELECT order_id, created_at, status
FROM checkout_orders
WHERE customer_id = $1
ORDER BY created_at DESC
LIMIT 20;
""",
    Path("/home/user/dbadmin_link_lab/shared/dba_tuning_notes.md"): """# DBA Tuning Notes

- Prefer workload-specific schema, stats, and candidate query files.
- Keep active pointers as relative symbolic links.
- Re-run the active link checker after every rotation.
""",
}

def test_required_base_active_and_helper_paths_exist():
    assert BASE.exists(), f"Missing lab base directory: {BASE}"
    assert BASE.is_dir(), f"Lab base path is not a directory: {BASE}"

    assert ACTIVE.exists(), f"Missing active directory: {ACTIVE}"
    assert ACTIVE.is_dir(), f"Active path is not a directory: {ACTIVE}"

    assert HELPER.exists(), f"Missing verification helper: {HELPER}"
    assert HELPER.is_file(), f"Verification helper is not a regular file: {HELPER}"

@pytest.mark.parametrize("path, expectation", EXPECTED_LINKS.items())
def test_active_entries_are_relative_symlinks_with_exact_target_text(path, expectation):
    assert path.is_symlink(), (
        f"{path} must be a symbolic link in the final state. "
        "It is missing or is still a regular file/directory."
    )

    actual_target = os.readlink(path)
    expected_target = expectation["target_text"]

    assert actual_target == expected_target, (
        f"{path} has the wrong symlink target text. "
        f"Expected exactly {expected_target!r}, but found {actual_target!r}."
    )

    assert not os.path.isabs(actual_target), (
        f"{path} must use a relative symlink target, but found absolute target "
        f"{actual_target!r}."
    )

@pytest.mark.parametrize("path, expectation", EXPECTED_LINKS.items())
def test_active_symlinks_resolve_to_intended_checkout_or_shared_sources(path, expectation):
    assert path.is_symlink(), f"{path} must be a symlink before target resolution can be checked."

    target_text = os.readlink(path)
    resolved = (path.parent / target_text).resolve()
    expected_resolved = expectation["resolved"].resolve()

    assert resolved == expected_resolved, (
        f"{path} resolves to the wrong file. "
        f"Target text is {target_text!r}; resolved to {resolved}, "
        f"but expected {expected_resolved}."
    )

    assert resolved.exists(), (
        f"{path} resolves to {resolved}, but that target file does not exist."
    )
    assert resolved.is_file(), (
        f"{path} resolves to {resolved}, but that target is not a regular file."
    )

@pytest.mark.parametrize("source_path, expected_content", EXPECTED_SOURCE_CONTENTS.items())
def test_expected_source_files_still_exist_with_original_contents(source_path, expected_content):
    assert source_path.exists(), f"Required source file is missing: {source_path}"
    assert source_path.is_file(), f"Required source path is not a regular file: {source_path}"
    actual_content = source_path.read_text()
    assert actual_content == expected_content, (
        f"Source file {source_path} does not contain the expected original content. "
        "The active symlinks should point to these source files, not replace or alter them."
    )

def test_verification_helper_succeeds_in_final_state():
    assert HELPER.exists(), f"Cannot run missing verification helper: {HELPER}"
    assert HELPER.is_file(), f"Verification helper is not a regular file: {HELPER}"

    result = subprocess.run(
        [str(HELPER)],
        cwd=str(BASE),
        text=True,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        timeout=10,
    )

    assert result.returncode == 0, (
        f"Verification helper {HELPER} failed with exit code {result.returncode}.\n"
        f"stdout:\n{result.stdout}\n"
        f"stderr:\n{result.stderr}"
    )

def test_link_verification_report_exists_as_regular_file_not_symlink():
    assert REPORT.exists(), f"Missing final report file: {REPORT}"
    assert not REPORT.is_symlink(), f"Final report must be a regular file, not a symlink: {REPORT}"
    assert REPORT.is_file(), f"Final report path is not a regular file: {REPORT}"

def test_link_verification_report_matches_exact_required_contents():
    assert REPORT.exists(), f"Missing final report file: {REPORT}"

    actual_bytes = REPORT.read_bytes()
    expected_bytes = EXPECTED_REPORT_TEXT.encode()

    assert actual_bytes == expected_bytes, (
        f"Final report {REPORT} does not match the required byte-for-byte contents.\n"
        f"Expected:\n{EXPECTED_REPORT_TEXT!r}\n"
        f"Actual:\n{actual_bytes.decode(errors='replace')!r}"
    )

def test_link_verification_report_has_exactly_seven_lines_and_no_extra_blank_lines():
    assert REPORT.exists(), f"Missing final report file: {REPORT}"

    actual_text = REPORT.read_text()
    lines = actual_text.splitlines()

    assert len(lines) == 7, (
        f"Final report {REPORT} must contain exactly 7 lines, but contains "
        f"{len(lines)} lines: {lines!r}"
    )

    assert lines == EXPECTED_REPORT_TEXT.splitlines(), (
        f"Final report {REPORT} has incorrect line contents or order. "
        f"Expected lines {EXPECTED_REPORT_TEXT.splitlines()!r}, but found {lines!r}."
    )

    assert all(line != "" for line in lines), (
        f"Final report {REPORT} must not contain extra blank lines, but found lines {lines!r}."
    )

    assert actual_text.endswith("\n"), (
        f"Final report {REPORT} should end with a single trailing newline."
    )
    assert not actual_text.endswith("\n\n"), (
        f"Final report {REPORT} must not contain an extra blank line at the end."
    )


You’re helping an observability engineer tune a Grafana-style dashboard backed by SQLite data.

The working directory is `/home/user/observability_dashboard`. It already contains a SQLite database at `/home/user/observability_dashboard/metrics.db` and a draft Python exporter at `/home/user/observability_dashboard/export_dashboard_summary.py`.

Please produce the final dashboard summary artifact at:

`/home/user/observability_dashboard/dashboard_summary.json`

The database contains service latency samples and dashboard widget definitions. The existing exporter may run without crashing, but do not assume that a zero exit code means the deliverable is correct. Inspect the generated artifact and verify it against the database before you finish.

Final artifact requirements:

1. `dashboard_summary.json` must be valid JSON.
2. The top-level JSON object must contain exactly these keys:
   - `generated_for`
   - `time_window`
   - `services`
   - `dashboard_widgets`
   - `verification`
3. `generated_for` must be the string:
   - `observability-engineering`
4. `time_window` must be an object with exactly:
   - `start`: ISO-8601 timestamp string from the earliest sample included
   - `end`: ISO-8601 timestamp string from the latest sample included
   - `sample_count`: integer count of included rows
5. Only production data from the last 30 minutes of the run window should be included. In this database, that means rows where:
   - `environment` is `prod`
   - `ts` is greater than or equal to the run’s cutoff timestamp recorded in the database metadata
6. `services` must be an array sorted alphabetically by service name. Each service object must contain exactly:
   - `service`: service name
   - `samples`: number of included samples for that service
   - `avg_latency_ms`: average latency for that service, rounded to 2 decimal places
   - `p95_latency_ms`: nearest-rank 95th percentile latency for that service, rounded to 2 decimal places
   - `error_rate`: fraction of included samples where `status` is not `ok`, rounded to 4 decimal places
7. `dashboard_widgets` must be an array of dashboard widget objects sorted by `widget_id` ascending. Include only widgets whose `enabled` value is true. Each widget object must contain exactly:
   - `widget_id`
   - `title`
   - `service`
   - `metric`
8. `verification` must be an object with exactly:
   - `checked`: boolean `true`
   - `notes`: string `artifact compared against sqlite source rows`
9. Create a verification log at:

`/home/user/observability_dashboard/verification.log`

The log must be plain text with exactly four lines in this order:

- `command_completed=true`
- `artifact_exists=true`
- `artifact_valid_json=true`
- `semantic_checks_passed=true`

Important: a script completing successfully is not enough. Before writing the final verification line, confirm that the JSON content satisfies the filtering, sorting, rounding, widget inclusion, and percentile requirements above. If the existing exporter produces a file but the semantic checks do not match the database, update the processing logic and regenerate the artifact.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_e78001e5"
description = "You\u2019re helping an observability engineer tune a Grafana-style dashboard backed by SQLite data."
authors = [{ name = "Endless Terminals / Jarrod Barnes" }]
keywords = ["agentic-rl", "endless-terminals", "exit_code_false_success", "terminal-bench-2", "verification_directed_action"]

[metadata]
source = "endless-terminals"
corpus = "processrl-core-v1"
generation_mode = "behavior_conditioned_llm_funnel"
behavior_card_id = "exit_code_false_success"
capability = "verification_directed_action"
source_traces = ["book-portfolio-analysis", "pandas-numpy-data-analysis", "jsonl-aggregator", "csv-json-jsonl-merger"]

[verifier]
timeout_sec = 300.0
user = "root"

[agent]
timeout_sec = 900.0
user = "user"

[environment]
build_timeout_sec = 900.0
os = "linux"
cpus = 2
memory_mb = 4096
storage_mb = 10240
gpus = 0
allow_internet = true

FROM ubuntu:22.04
SHELL ["/bin/bash", "-lc"]
RUN <<'__ENDLESS_DOCKER_POST__'
    set -e

    apt-get update
    DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
        python3 \
        python3-pip \
        python3-venv \
        sqlite3 \
        ca-certificates

    python3 -m pip install --no-cache-dir pytest

    if ! id -u user >/dev/null 2>&1; then
        useradd -m -s /bin/bash user
    fi

    mkdir -p /home/user/observability_dashboard

    python3 <<'PY'
import sqlite3
from pathlib import Path

db_path = Path("/home/user/observability_dashboard/metrics.db")
if db_path.exists():
    db_path.unlink()

conn = sqlite3.connect(str(db_path))
cur = conn.cursor()

cur.execute("""
CREATE TABLE metadata (
    key TEXT PRIMARY KEY,
    value TEXT NOT NULL
)
""")

cur.execute("""
CREATE TABLE latency_samples (
    id INTEGER PRIMARY KEY,
    ts TEXT NOT NULL,
    environment TEXT NOT NULL,
    service TEXT NOT NULL,
    latency_ms REAL NOT NULL,
    status TEXT NOT NULL
)
""")

cur.execute("""
CREATE TABLE dashboard_widgets (
    widget_id INTEGER PRIMARY KEY,
    title TEXT NOT NULL,
    service TEXT NOT NULL,
    metric TEXT NOT NULL,
    enabled INTEGER NOT NULL
)
""")

cur.executemany(
    "INSERT INTO metadata (key, value) VALUES (?, ?)",
    [
        ("run_started_at", "2026-02-14T12:00:00Z"),
        ("cutoff_ts", "2026-02-14T11:30:00Z"),
        ("dashboard_owner", "observability-engineering"),
    ],
)

cur.executemany(
    """
    INSERT INTO latency_samples
        (id, ts, environment, service, latency_ms, status)
    VALUES (?, ?, ?, ?, ?, ?)
    """,
    [
        (1, "2026-02-14T11:20:00Z", "prod", "api-gateway", 900.0, "ok"),
        (2, "2026-02-14T11:31:00Z", "prod", "api-gateway", 100.0, "ok"),
        (3, "2026-02-14T11:35:00Z", "prod", "api-gateway", 120.0, "ok"),
        (4, "2026-02-14T11:40:00Z", "prod", "api-gateway", 300.0, "error"),
        (5, "2026-02-14T11:50:00Z", "prod", "api-gateway", 110.0, "ok"),
        (6, "2026-02-14T11:55:00Z", "prod", "api-gateway", 115.0, "ok"),
        (7, "2026-02-14T11:32:00Z", "prod", "checkout", 200.0, "ok"),
        (8, "2026-02-14T11:36:00Z", "prod", "checkout", 220.0, "error"),
        (9, "2026-02-14T11:42:00Z", "prod", "checkout", 210.0, "ok"),
        (10, "2026-02-14T11:48:00Z", "prod", "checkout", 205.0, "ok"),
        (11, "2026-02-14T11:58:00Z", "prod", "checkout", 400.0, "error"),
        (12, "2026-02-14T11:33:00Z", "prod", "inventory", 80.0, "ok"),
        (13, "2026-02-14T11:37:00Z", "prod", "inventory", 90.0, "ok"),
        (14, "2026-02-14T11:44:00Z", "prod", "inventory", 85.0, "ok"),
        (15, "2026-02-14T11:52:00Z", "prod", "inventory", 95.0, "ok"),
        (16, "2026-02-14T11:59:00Z", "prod", "inventory", 500.0, "error"),
        (17, "2026-02-14T11:45:00Z", "staging", "checkout", 999.0, "error"),
        (18, "2026-02-14T11:46:00Z", "dev", "api-gateway", 777.0, "ok"),
    ],
)

cur.executemany(
    """
    INSERT INTO dashboard_widgets
        (widget_id, title, service, metric, enabled)
    VALUES (?, ?, ?, ?, ?)
    """,
    [
        (10, "API Gateway Latency", "api-gateway", "p95_latency_ms", 1),
        (11, "Checkout Error Rate", "checkout", "error_rate", 1),
        (12, "Inventory Average Latency", "inventory", "avg_latency_ms", 1),
        (13, "Deprecated Staging Checkout", "checkout", "avg_latency_ms", 0),
    ],
)

conn.commit()
conn.close()
PY

    cat > /home/user/observability_dashboard/export_dashboard_summary.py <<'PY'
#!/usr/bin/env python3
"""
Draft dashboard summary exporter.

This script intentionally represents a clean-running but imperfect first draft.
It writes dashboard_summary.json and exits successfully, but its calculations
and filtering should be reviewed against metrics.db before relying on the
artifact.
"""

import json
import sqlite3
from collections import defaultdict
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent
DB_PATH = BASE_DIR / "metrics.db"
OUT_PATH = BASE_DIR / "dashboard_summary.json"

def interpolated_p95(values):
    values = sorted(values)
    if not values:
        return None
    if len(values) == 1:
        return values[0]
    # Draft approximation: interpolation-style percentile, not nearest-rank.
    pos = 0.95 * (len(values) - 1)
    lower = int(pos)
    upper = min(lower + 1, len(values) - 1)
    fraction = pos - lower
    return values[lower] + (values[upper] - values[lower]) * fraction

def main():
    conn = sqlite3.connect(str(DB_PATH))
    conn.row_factory = sqlite3.Row

    metadata = {
        row["key"]: row["value"]
        for row in conn.execute("SELECT key, value FROM metadata").fetchall()
    }

    # Draft bug: includes every prod row, even those before metadata.cutoff_ts.
    samples = conn.execute(
        """
        SELECT ts, environment, service, latency_ms, status
        FROM latency_samples
        WHERE environment = 'prod'
        ORDER BY ts, id
        """
    ).fetchall()

    grouped = defaultdict(list)
    for row in samples:
        grouped[row["service"]].append(row)

    services = []
    for service in sorted(grouped):
        rows = grouped[service]
        latencies = [float(row["latency_ms"]) for row in rows]
        errors = sum(1 for row in rows if row["status"] != "ok")
        services.append(
            {
                "service": service,
                "samples": len(rows),
                "avg_latency_ms": round(sum(latencies) / len(latencies), 2),
                "p95_latency_ms": round(interpolated_p95(latencies), 2),
                "error_rate": round(errors / len(rows), 4),
            }
        )

    # Draft bug: includes disabled widgets too.
    widgets = [
        {
            "widget_id": row["widget_id"],
            "title": row["title"],
            "service": row["service"],
            "metric": row["metric"],
        }
        for row in conn.execute(
            """
            SELECT widget_id, title, service, metric, enabled
            FROM dashboard_widgets
            ORDER BY widget_id
            """
        ).fetchall()
    ]

    artifact = {
        "generated_for": metadata.get("dashboard_owner", "observability-engineering"),
        "time_window": {
            "start": min(row["ts"] for row in samples) if samples else None,
            "end": max(row["ts"] for row in samples) if samples else None,
            "sample_count": len(samples),
        },
        "services": services,
        "dashboard_widgets": widgets,
        "verification": {
            "checked": False,
            "notes": "draft exporter output; semantic verification not complete",
        },
    }

    OUT_PATH.write_text(json.dumps(artifact, indent=2) + "\n", encoding="utf-8")
    conn.close()
    return 0

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

    chmod 755 /home/user/observability_dashboard/export_dashboard_summary.py
    chown -R user:user /home/user/observability_dashboard
    chmod 755 /home/user
    chmod 755 /home/user/observability_dashboard
    chmod 664 /home/user/observability_dashboard/metrics.db

    rm -rf /var/lib/apt/lists/*

chmod -R a+rwX /home/user
__ENDLESS_DOCKER_POST__
WORKDIR /home/user

# test_final_state.py
import json
import math
import sqlite3
from pathlib import Path

import pytest

BASE_DIR = Path("/home/user/observability_dashboard")
DB_PATH = Path("/home/user/observability_dashboard/metrics.db")
SUMMARY_PATH = Path("/home/user/observability_dashboard/dashboard_summary.json")
VERIFICATION_LOG_PATH = Path("/home/user/observability_dashboard/verification.log")

EXPECTED_TOP_LEVEL_KEYS = {
    "generated_for",
    "time_window",
    "services",
    "dashboard_widgets",
    "verification",
}

EXPECTED_TIME_WINDOW_KEYS = {"start", "end", "sample_count"}
EXPECTED_SERVICE_KEYS = {
    "service",
    "samples",
    "avg_latency_ms",
    "p95_latency_ms",
    "error_rate",
}
EXPECTED_WIDGET_KEYS = {"widget_id", "title", "service", "metric"}
EXPECTED_VERIFICATION_KEYS = {"checked", "notes"}

EXPECTED_VERIFICATION_LOG_LINES = [
    "command_completed=true",
    "artifact_exists=true",
    "artifact_valid_json=true",
    "semantic_checks_passed=true",
]

def _connect_db():
    assert DB_PATH.exists(), f"Required SQLite source database is missing: {DB_PATH}"
    try:
        conn = sqlite3.connect(str(DB_PATH))
        conn.row_factory = sqlite3.Row
        return conn
    except sqlite3.Error as exc:
        pytest.fail(f"Could not open SQLite database at {DB_PATH}: {exc}")

def _load_summary_json():
    assert SUMMARY_PATH.exists(), (
        f"Final artifact is missing: {SUMMARY_PATH}. "
        "Generate dashboard_summary.json before finishing."
    )
    assert SUMMARY_PATH.is_file(), f"Final artifact path exists but is not a file: {SUMMARY_PATH}"

    try:
        return json.loads(SUMMARY_PATH.read_text(encoding="utf-8"))
    except json.JSONDecodeError as exc:
        pytest.fail(
            f"Final artifact is not valid JSON: {SUMMARY_PATH}. "
            f"JSON parser error at line {exc.lineno}, column {exc.colno}: {exc.msg}"
        )

def _nearest_rank_p95(latencies):
    assert latencies, "Cannot compute p95 for an empty latency list"
    sorted_latencies = sorted(latencies)
    rank = math.ceil(0.95 * len(sorted_latencies))
    return sorted_latencies[rank - 1]

def _round_numeric(value, places):
    return round(float(value), places)

def _expected_summary_from_database():
    with _connect_db() as conn:
        metadata_rows = conn.execute("SELECT key, value FROM metadata").fetchall()
        metadata = {row["key"]: row["value"] for row in metadata_rows}

        assert metadata.get("dashboard_owner") == "observability-engineering", (
            f"Unexpected dashboard_owner in {DB_PATH}: "
            f"{metadata.get('dashboard_owner')!r}"
        )
        assert "cutoff_ts" in metadata, f"metadata.cutoff_ts is missing from {DB_PATH}"

        cutoff_ts = metadata["cutoff_ts"]

        included_rows = conn.execute(
            """
            SELECT ts, service, latency_ms, status
            FROM latency_samples
            WHERE environment = 'prod' AND ts >= ?
            ORDER BY ts, id
            """,
            (cutoff_ts,),
        ).fetchall()

        widget_rows = conn.execute(
            """
            SELECT widget_id, title, service, metric
            FROM dashboard_widgets
            WHERE enabled = 1
            ORDER BY widget_id ASC
            """
        ).fetchall()

    assert included_rows, (
        f"No production latency samples at or after cutoff {cutoff_ts!r} "
        f"were found in {DB_PATH}"
    )

    service_names = sorted({row["service"] for row in included_rows})
    services = []
    for service_name in service_names:
        service_rows = [row for row in included_rows if row["service"] == service_name]
        latencies = [float(row["latency_ms"]) for row in service_rows]
        error_count = sum(1 for row in service_rows if row["status"] != "ok")
        sample_count = len(service_rows)

        services.append(
            {
                "service": service_name,
                "samples": sample_count,
                "avg_latency_ms": _round_numeric(sum(latencies) / sample_count, 2),
                "p95_latency_ms": _round_numeric(_nearest_rank_p95(latencies), 2),
                "error_rate": _round_numeric(error_count / sample_count, 4),
            }
        )

    return {
        "generated_for": metadata["dashboard_owner"],
        "time_window": {
            "start": min(row["ts"] for row in included_rows),
            "end": max(row["ts"] for row in included_rows),
            "sample_count": len(included_rows),
        },
        "services": services,
        "dashboard_widgets": [
            {
                "widget_id": row["widget_id"],
                "title": row["title"],
                "service": row["service"],
                "metric": row["metric"],
            }
            for row in widget_rows
        ],
        "verification": {
            "checked": True,
            "notes": "artifact compared against sqlite source rows",
        },
    }

def _assert_exact_keys(obj, expected_keys, location):
    assert isinstance(obj, dict), f"{location} must be a JSON object, got {type(obj).__name__}"
    actual_keys = set(obj.keys())
    assert actual_keys == expected_keys, (
        f"{location} has wrong keys.\n"
        f"Expected exactly: {sorted(expected_keys)}\n"
        f"Actual:           {sorted(actual_keys)}"
    )

def _assert_numeric_json_value(value, location):
    assert isinstance(value, (int, float)) and not isinstance(value, bool), (
        f"{location} must be a numeric JSON value, not {value!r} "
        f"of type {type(value).__name__}"
    )

def test_dashboard_summary_exists_and_is_valid_json_object_with_exact_top_level_keys():
    summary = _load_summary_json()
    _assert_exact_keys(summary, EXPECTED_TOP_LEVEL_KEYS, "top-level dashboard_summary.json")

def test_dashboard_summary_exact_semantics_match_sqlite_source_rows():
    summary = _load_summary_json()
    expected = _expected_summary_from_database()

    _assert_exact_keys(summary, EXPECTED_TOP_LEVEL_KEYS, "top-level dashboard_summary.json")
    _assert_exact_keys(summary["time_window"], EXPECTED_TIME_WINDOW_KEYS, "time_window")
    _assert_exact_keys(summary["verification"], EXPECTED_VERIFICATION_KEYS, "verification")

    assert isinstance(summary["services"], list), "services must be a JSON array"
    assert isinstance(summary["dashboard_widgets"], list), "dashboard_widgets must be a JSON array"

    for index, service_obj in enumerate(summary["services"]):
        _assert_exact_keys(service_obj, EXPECTED_SERVICE_KEYS, f"services[{index}]")
        assert isinstance(service_obj["samples"], int) and not isinstance(
            service_obj["samples"], bool
        ), f"services[{index}].samples must be an integer"
        _assert_numeric_json_value(
            service_obj["avg_latency_ms"], f"services[{index}].avg_latency_ms"
        )
        _assert_numeric_json_value(
            service_obj["p95_latency_ms"], f"services[{index}].p95_latency_ms"
        )
        _assert_numeric_json_value(service_obj["error_rate"], f"services[{index}].error_rate")

    for index, widget_obj in enumerate(summary["dashboard_widgets"]):
        _assert_exact_keys(widget_obj, EXPECTED_WIDGET_KEYS, f"dashboard_widgets[{index}]")

    assert summary == expected, (
        "dashboard_summary.json does not exactly match the expected final summary "
        "computed from SQLite source rows using prod-only cutoff filtering, "
        "alphabetical service sorting, nearest-rank p95, enabled-widget filtering, "
        "and required verification fields.\n"
        f"Expected:\n{json.dumps(expected, indent=2, sort_keys=False)}\n"
        f"Actual:\n{json.dumps(summary, indent=2, sort_keys=False)}"
    )

def test_dashboard_summary_matches_known_required_final_values():
    summary = _load_summary_json()

    expected_known_final = {
        "generated_for": "observability-engineering",
        "time_window": {
            "start": "2026-02-14T11:31:00Z",
            "end": "2026-02-14T11:59:00Z",
            "sample_count": 15,
        },
        "services": [
            {
                "service": "api-gateway",
                "samples": 5,
                "avg_latency_ms": 149.0,
                "p95_latency_ms": 300.0,
                "error_rate": 0.2,
            },
            {
                "service": "checkout",
                "samples": 5,
                "avg_latency_ms": 247.0,
                "p95_latency_ms": 400.0,
                "error_rate": 0.4,
            },
            {
                "service": "inventory",
                "samples": 5,
                "avg_latency_ms": 170.0,
                "p95_latency_ms": 500.0,
                "error_rate": 0.2,
            },
        ],
        "dashboard_widgets": [
            {
                "widget_id": 10,
                "title": "API Gateway Latency",
                "service": "api-gateway",
                "metric": "p95_latency_ms",
            },
            {
                "widget_id": 11,
                "title": "Checkout Error Rate",
                "service": "checkout",
                "metric": "error_rate",
            },
            {
                "widget_id": 12,
                "title": "Inventory Average Latency",
                "service": "inventory",
                "metric": "avg_latency_ms",
            },
        ],
        "verification": {
            "checked": True,
            "notes": "artifact compared against sqlite source rows",
        },
    }

    assert summary == expected_known_final, (
        "dashboard_summary.json does not match the exact required final artifact. "
        "This usually means the exporter still includes the old prod row, includes "
        "non-prod rows, uses interpolated p95 instead of nearest-rank p95, includes "
        "disabled widgets, has wrong ordering, or has incorrect verification fields."
    )

def test_services_are_sorted_and_exclude_filtered_out_samples():
    summary = _load_summary_json()
    services = summary.get("services")

    assert isinstance(services, list), "services must be a JSON array"

    service_names = [service_obj.get("service") for service_obj in services]
    assert service_names == sorted(service_names), (
        f"services must be sorted alphabetically by service name. Actual order: {service_names}"
    )

    assert summary.get("time_window", {}).get("sample_count") == 15, (
        "time_window.sample_count must be 15, counting only prod rows with "
        "ts >= metadata.cutoff_ts. The old 11:20 prod sample and non-prod samples "
        "must be excluded."
    )

    api_gateway = next(
        (service_obj for service_obj in services if service_obj.get("service") == "api-gateway"),
        None,
    )
    assert api_gateway is not None, "Missing api-gateway service summary"
    assert api_gateway["samples"] == 5, (
        "api-gateway must have exactly 5 included samples. "
        "If it has 6, the old 11:20 prod row was incorrectly included."
    )
    assert api_gateway["avg_latency_ms"] == 149.0, (
        "api-gateway average latency must be 149.0 after excluding the old 900ms row."
    )
    assert api_gateway["p95_latency_ms"] == 300.0, (
        "api-gateway p95 must use nearest-rank percentile over the 5 included samples, "
        "selecting the 5th sorted value: 300.0."
    )

def test_dashboard_widgets_are_enabled_only_and_sorted_by_widget_id():
    summary = _load_summary_json()
    widgets = summary.get("dashboard_widgets")

    assert isinstance(widgets, list), "dashboard_widgets must be a JSON array"

    widget_ids = [widget.get("widget_id") for widget in widgets]
    assert widget_ids == sorted(widget_ids), (
        f"dashboard_widgets must be sorted by widget_id ascending. Actual order: {widget_ids}"
    )
    assert widget_ids == [10, 11, 12], (
        "dashboard_widgets must include only enabled widgets with IDs [10, 11, 12]. "
        f"Actual widget IDs: {widget_ids}. Disabled widget 13 must not be present."
    )

def test_verification_log_exists_and_has_exact_required_lines():
    assert VERIFICATION_LOG_PATH.exists(), (
        f"Verification log is missing: {VERIFICATION_LOG_PATH}. "
        "Create it only after semantic checks pass."
    )
    assert VERIFICATION_LOG_PATH.is_file(), (
        f"Verification log path exists but is not a file: {VERIFICATION_LOG_PATH}"
    )

    content = VERIFICATION_LOG_PATH.read_text(encoding="utf-8")
    actual_lines = content.splitlines()

    assert actual_lines == EXPECTED_VERIFICATION_LOG_LINES, (
        f"verification.log must contain exactly four required lines in order.\n"
        f"Expected lines: {EXPECTED_VERIFICATION_LOG_LINES}\n"
        f"Actual lines:   {actual_lines}\n"
        f"Raw content was:\n{content!r}"
    )

    assert content.endswith("\n") or content == "\n".join(EXPECTED_VERIFICATION_LOG_LINES), (
        "verification.log has the correct logical lines but unusual trailing content handling. "
        "It should be plain text containing only the required four lines."
    )