You’re helping a security researcher clean up a small dataset manifest before it is shared with collaborators. The working directory is `/home/user/research_datasets`.

There is an input JSON Lines file at `/home/user/research_datasets/raw/manifests.jsonl`. Each line is a JSON object describing one dataset file with at least these fields:

- `dataset_id`
- `path`
- `sha256`
- `bytes`
- `notes`

The researcher suspects the manifest has a simple path-traversal vulnerability: some records contain unsafe relative paths that could write outside the intended dataset directory if used by an extractor. Your job is to produce a sanitized manifest that keeps only safe dataset entries.

Create the output file:

`/home/user/research_datasets/clean/safe_manifest.jsonl`

Output requirements:

1. The file must be valid JSON Lines: exactly one JSON object per line, no wrapping array, no blank lines.
2. Keep only records whose `path` is safe.
3. A safe `path` must satisfy all of the following:
   - It is a relative path.
   - It does not start with `/`.
   - It does not contain any path component equal to `..`.
   - It does not contain empty path components such as those created by `//`.
   - It does not contain shell home expansion such as `~` as a path component.
4. Preserve the original field names and values for all kept records.
5. Preserve the original order of kept records from the input file.
6. Do not modify `/home/user/research_datasets/raw/manifests.jsonl`.
7. If the output directory `/home/user/research_datasets/clean` does not exist, create it.

After creating the sanitized manifest, create a verification log at:

`/home/user/research_datasets/clean/verification.log`

The verification log must contain exactly these four lines in this format:

```text
input_records=<number>
safe_records=<number>
unsafe_records=<number>
status=<OK or FAIL>
```

Where:

- `input_records` is the total number of JSON objects read from `/home/user/research_datasets/raw/manifests.jsonl`.
- `safe_records` is the number of records written to `/home/user/research_datasets/clean/safe_manifest.jsonl`.
- `unsafe_records` is the number of records excluded.
- `status=OK` only if:
  - the counts are internally consistent,
  - the output file exists,
  - every output record has a safe `path`,
  - and at least one unsafe record was excluded.
- Otherwise write `status=FAIL`.

Before finishing, verify the contents of the generated artifact rather than relying only on a command’s exit code. A script or one-liner that exits successfully but leaves unsafe paths in the output is not sufficient.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_bc197e2f"
description = "You\u2019re helping a security researcher clean up a small dataset manifest before it is shared with collaborators. The working directory is `/home/user/research_datasets`."
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 \
        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

    mkdir -p /home/user/research_datasets/raw

    cat > /home/user/research_datasets/raw/manifests.jsonl <<'EOF'
{"dataset_id":"ds-001","path":"images/cells_a.tif","sha256":"0bd9a62c3a1b3559b2a7a9a2c8bb7029cf8f2ef96b62de8f68f9d4d76476a011","bytes":18420,"notes":"baseline microscopy image"}
{"dataset_id":"ds-002","path":"labels/cells_a.json","sha256":"70d9f7e76d4cc8f518ad921017774dc3f825d148337be740ef6ab7462d2f6b1a","bytes":912,"notes":"paired annotation"}
{"dataset_id":"ds-003","path":"../private/participants.csv","sha256":"3333a62c3a1b3559b2a7a9a2c8bb7029cf8f2ef96b62de8f68f9d4d76476a333","bytes":1024,"notes":"unsafe traversal parent"}
{"dataset_id":"ds-004","path":"/etc/passwd","sha256":"4444a62c3a1b3559b2a7a9a2c8bb7029cf8f2ef96b62de8f68f9d4d76476a444","bytes":2048,"notes":"unsafe absolute path"}
{"dataset_id":"ds-005","path":"tables/run1/results.csv","sha256":"4a4f0c6fe2fa7d3cd1ff8248075c54f95f62ab8f859bbcf41613e7a7f3b8192b","bytes":3240,"notes":"safe results table"}
{"dataset_id":"ds-006","path":"tables//run2/results.csv","sha256":"6666a62c3a1b3559b2a7a9a2c8bb7029cf8f2ef96b62de8f68f9d4d76476a666","bytes":4010,"notes":"unsafe empty path component"}
{"dataset_id":"ds-007","path":"metadata/./study.json","sha256":"7ff04b5f506f98723e6e0e37bfc580cb5f0f040cbad678d895b36656d9c7d407","bytes":688,"notes":"safe current-directory component is allowed"}
{"dataset_id":"ds-008","path":"~/secrets/token.txt","sha256":"8888a62c3a1b3559b2a7a9a2c8bb7029cf8f2ef96b62de8f68f9d4d76476a888","bytes":77,"notes":"unsafe home expansion component"}
{"dataset_id":"ds-009","path":"archives/2023-12/sample.tar.gz","sha256":"1a2d1f8f58fd8e11e2818839ab0efc48ad522b3c60c696e7467092a37ec2b1aa","bytes":55012,"notes":"safe archive"}
{"dataset_id":"ds-010","path":"archives/../../escape.tar.gz","sha256":"aaaaa62c3a1b3559b2a7a9a2c8bb7029cf8f2ef96b62de8f68f9d4d76476aaaa","bytes":9012,"notes":"unsafe nested traversal"}
{"dataset_id":"ds-011","path":"qc/reports/final.html","sha256":"df5d806891763c3a75dd5d225f44a3cb263d12a4fd4474dca1294a752f65f2df","bytes":7312,"notes":"safe quality report"}
{"dataset_id":"ds-012","path":"raw/plates/plate_17.tsv","sha256":"4fb4e7e2f8913c6f76ab1a9a4aa8efbe7cc197f0a7907c23efacb76d2dc04b09","bytes":14580,"notes":"safe raw table"}
EOF

    rm -rf /home/user/research_datasets/clean

    chown -R user:user /home/user
    chmod 755 /home/user
    chmod 777 /home/user/research_datasets
    chmod 777 /home/user/research_datasets/raw
    chmod 666 /home/user/research_datasets/raw/manifests.jsonl

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

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

import pytest

BASE_DIR = Path("/home/user/research_datasets")
RAW_DIR = Path("/home/user/research_datasets/raw")
CLEAN_DIR = Path("/home/user/research_datasets/clean")
INPUT_FILE = Path("/home/user/research_datasets/raw/manifests.jsonl")
OUTPUT_FILE = Path("/home/user/research_datasets/clean/safe_manifest.jsonl")
LOG_FILE = Path("/home/user/research_datasets/clean/verification.log")

EXPECTED_INPUT_RECORDS = [
    {
        "dataset_id": "ds-001",
        "path": "images/cells_a.tif",
        "sha256": "0bd9a62c3a1b3559b2a7a9a2c8bb7029cf8f2ef96b62de8f68f9d4d76476a011",
        "bytes": 18420,
        "notes": "baseline microscopy image",
    },
    {
        "dataset_id": "ds-002",
        "path": "labels/cells_a.json",
        "sha256": "70d9f7e76d4cc8f518ad921017774dc3f825d148337be740ef6ab7462d2f6b1a",
        "bytes": 912,
        "notes": "paired annotation",
    },
    {
        "dataset_id": "ds-003",
        "path": "../private/participants.csv",
        "sha256": "3333a62c3a1b3559b2a7a9a2c8bb7029cf8f2ef96b62de8f68f9d4d76476a333",
        "bytes": 1024,
        "notes": "unsafe traversal parent",
    },
    {
        "dataset_id": "ds-004",
        "path": "/etc/passwd",
        "sha256": "4444a62c3a1b3559b2a7a9a2c8bb7029cf8f2ef96b62de8f68f9d4d76476a444",
        "bytes": 2048,
        "notes": "unsafe absolute path",
    },
    {
        "dataset_id": "ds-005",
        "path": "tables/run1/results.csv",
        "sha256": "4a4f0c6fe2fa7d3cd1ff8248075c54f95f62ab8f859bbcf41613e7a7f3b8192b",
        "bytes": 3240,
        "notes": "safe results table",
    },
    {
        "dataset_id": "ds-006",
        "path": "tables//run2/results.csv",
        "sha256": "6666a62c3a1b3559b2a7a9a2c8bb7029cf8f2ef96b62de8f68f9d4d76476a666",
        "bytes": 4010,
        "notes": "unsafe empty path component",
    },
    {
        "dataset_id": "ds-007",
        "path": "metadata/./study.json",
        "sha256": "7ff04b5f506f98723e6e0e37bfc580cb5f0f040cbad678d895b36656d9c7d407",
        "bytes": 688,
        "notes": "safe current-directory component is allowed",
    },
    {
        "dataset_id": "ds-008",
        "path": "~/secrets/token.txt",
        "sha256": "8888a62c3a1b3559b2a7a9a2c8bb7029cf8f2ef96b62de8f68f9d4d76476a888",
        "bytes": 77,
        "notes": "unsafe home expansion component",
    },
    {
        "dataset_id": "ds-009",
        "path": "archives/2023-12/sample.tar.gz",
        "sha256": "1a2d1f8f58fd8e11e2818839ab0efc48ad522b3c60c696e7467092a37ec2b1aa",
        "bytes": 55012,
        "notes": "safe archive",
    },
    {
        "dataset_id": "ds-010",
        "path": "archives/../../escape.tar.gz",
        "sha256": "aaaaa62c3a1b3559b2a7a9a2c8bb7029cf8f2ef96b62de8f68f9d4d76476aaaa",
        "bytes": 9012,
        "notes": "unsafe nested traversal",
    },
    {
        "dataset_id": "ds-011",
        "path": "qc/reports/final.html",
        "sha256": "df5d806891763c3a75dd5d225f44a3cb263d12a4fd4474dca1294a752f65f2df",
        "bytes": 7312,
        "notes": "safe quality report",
    },
    {
        "dataset_id": "ds-012",
        "path": "raw/plates/plate_17.tsv",
        "sha256": "4fb4e7e2f8913c6f76ab1a9a4aa8efbe7cc197f0a7907c23efacb76d2dc04b09",
        "bytes": 14580,
        "notes": "safe raw table",
    },
]

EXPECTED_SAFE_RECORDS = [
    EXPECTED_INPUT_RECORDS[0],
    EXPECTED_INPUT_RECORDS[1],
    EXPECTED_INPUT_RECORDS[4],
    EXPECTED_INPUT_RECORDS[6],
    EXPECTED_INPUT_RECORDS[8],
    EXPECTED_INPUT_RECORDS[10],
    EXPECTED_INPUT_RECORDS[11],
]

EXPECTED_SAFE_IDS = ["ds-001", "ds-002", "ds-005", "ds-007", "ds-009", "ds-011", "ds-012"]
EXPECTED_UNSAFE_IDS = ["ds-003", "ds-004", "ds-006", "ds-008", "ds-010"]

EXPECTED_LOG_TEXT = (
    "input_records=12\n"
    "safe_records=7\n"
    "unsafe_records=5\n"
    "status=OK\n"
)

def _read_text(path: Path) -> str:
    try:
        return path.read_text(encoding="utf-8")
    except UnicodeDecodeError as exc:
        pytest.fail(f"{path} must be UTF-8 text, but could not be decoded: {exc}")

def _load_jsonl(path: Path):
    text = _read_text(path)

    assert text, f"{path} must not be empty"
    assert not text.lstrip().startswith("["), (
        f"{path} must be JSON Lines with one JSON object per line, not a wrapping JSON array"
    )

    lines = text.splitlines()
    assert lines, f"{path} must contain JSON Lines records"

    records = []
    for line_number, line in enumerate(lines, start=1):
        assert line.strip(), f"{path} contains a blank line at line {line_number}; JSONL must not have blank lines"
        try:
            value = json.loads(line)
        except json.JSONDecodeError as exc:
            pytest.fail(f"{path} line {line_number} is not valid JSON: {exc}")
        assert isinstance(value, dict), (
            f"{path} line {line_number} must be a JSON object, got {type(value).__name__}"
        )
        records.append(value)
    return records

def _is_safe_path(path: str) -> bool:
    if not isinstance(path, str):
        return False
    if path.startswith("/"):
        return False
    components = path.split("/")
    if any(component in ("", "..", "~") for component in components):
        return False
    return True

def test_required_final_directories_exist():
    assert BASE_DIR.is_dir(), f"Required working directory is missing: {BASE_DIR}"
    assert RAW_DIR.is_dir(), f"Required raw directory is missing: {RAW_DIR}"
    assert CLEAN_DIR.exists(), f"Output directory was not created: {CLEAN_DIR}"
    assert CLEAN_DIR.is_dir(), f"Output path exists but is not a directory: {CLEAN_DIR}"

def test_input_manifest_was_not_modified():
    assert INPUT_FILE.exists(), f"Original input manifest is missing: {INPUT_FILE}"
    assert INPUT_FILE.is_file(), f"Original input manifest is not a regular file: {INPUT_FILE}"

    records = _load_jsonl(INPUT_FILE)
    assert records == EXPECTED_INPUT_RECORDS, (
        f"The task required not modifying {INPUT_FILE}, but its parsed JSONL contents "
        "do not exactly match the original expected manifest"
    )

def test_safe_manifest_exists_and_is_non_empty_regular_file():
    assert OUTPUT_FILE.exists(), f"Sanitized manifest was not created: {OUTPUT_FILE}"
    assert OUTPUT_FILE.is_file(), f"Sanitized manifest path is not a regular file: {OUTPUT_FILE}"
    assert os.path.getsize(OUTPUT_FILE) > 0, f"Sanitized manifest is empty: {OUTPUT_FILE}"

def test_safe_manifest_is_valid_jsonl_without_blank_lines_or_array():
    records = _load_jsonl(OUTPUT_FILE)

    assert len(records) == 7, (
        f"{OUTPUT_FILE} must contain exactly 7 safe JSON objects; got {len(records)}"
    )

    for index, record in enumerate(records, start=1):
        missing = {"dataset_id", "path", "sha256", "bytes", "notes"} - set(record)
        assert not missing, (
            f"{OUTPUT_FILE} record {index} is missing required original field(s): {sorted(missing)}"
        )

def test_safe_manifest_contains_exact_expected_objects_in_original_order():
    records = _load_jsonl(OUTPUT_FILE)
    actual_ids = [record.get("dataset_id") for record in records]

    assert actual_ids == EXPECTED_SAFE_IDS, (
        f"{OUTPUT_FILE} must contain exactly safe dataset_ids in original order: "
        f"{EXPECTED_SAFE_IDS}; got {actual_ids}"
    )

    assert records == EXPECTED_SAFE_RECORDS, (
        f"{OUTPUT_FILE} does not preserve the exact original field names and values "
        "for the expected safe records"
    )

def test_safe_manifest_excludes_all_known_unsafe_records():
    records = _load_jsonl(OUTPUT_FILE)
    ids = [record.get("dataset_id") for record in records]

    for unsafe_id in EXPECTED_UNSAFE_IDS:
        assert unsafe_id not in ids, (
            f"{OUTPUT_FILE} still contains unsafe record {unsafe_id}; expected unsafe ids "
            f"to be excluded: {EXPECTED_UNSAFE_IDS}"
        )

    unsafe_paths_by_id = {
        "ds-003": "../private/participants.csv",
        "ds-004": "/etc/passwd",
        "ds-006": "tables//run2/results.csv",
        "ds-008": "~/secrets/token.txt",
        "ds-010": "archives/../../escape.tar.gz",
    }
    paths = [record.get("path") for record in records]
    for dataset_id, unsafe_path in unsafe_paths_by_id.items():
        assert unsafe_path not in paths, (
            f"{OUTPUT_FILE} still contains unsafe path {unsafe_path!r} from {dataset_id}"
        )

def test_every_output_path_satisfies_component_based_safe_path_rules():
    records = _load_jsonl(OUTPUT_FILE)

    for record in records:
        dataset_id = record.get("dataset_id", "<missing dataset_id>")
        path = record.get("path")
        assert _is_safe_path(path), (
            f"Record {dataset_id} in {OUTPUT_FILE} has unsafe path {path!r}; paths must be "
            "relative, not start with '/', and contain no empty, '..', or '~' components"
        )

def test_verification_log_exists_and_has_exact_expected_contents():
    assert LOG_FILE.exists(), f"Verification log was not created: {LOG_FILE}"
    assert LOG_FILE.is_file(), f"Verification log path is not a regular file: {LOG_FILE}"

    actual_text = _read_text(LOG_FILE)
    assert actual_text == EXPECTED_LOG_TEXT, (
        f"{LOG_FILE} contents are incorrect.\n"
        f"Expected exactly:\n{EXPECTED_LOG_TEXT!r}\n"
        f"Got:\n{actual_text!r}"
    )

def test_verification_log_counts_match_actual_artifact_state():
    log_text = _read_text(LOG_FILE)
    log_lines = log_text.splitlines()

    assert log_lines == [
        "input_records=12",
        "safe_records=7",
        "unsafe_records=5",
        "status=OK",
    ], (
        f"{LOG_FILE} must contain exactly the required four lines with status=OK; got {log_lines!r}"
    )

    input_records = _load_jsonl(INPUT_FILE)
    output_records = _load_jsonl(OUTPUT_FILE)
    unsafe_count = len(input_records) - len(output_records)

    assert len(input_records) == 12, (
        f"Actual input record count is {len(input_records)}, but verification log claims 12"
    )
    assert len(output_records) == 7, (
        f"Actual safe manifest record count is {len(output_records)}, but verification log claims 7"
    )
    assert unsafe_count == 5, (
        f"Actual excluded unsafe record count is {unsafe_count}, but verification log claims 5"
    )
    assert unsafe_count > 0, "At least one unsafe record must have been excluded for status=OK"
    assert all(_is_safe_path(record.get("path")) for record in output_records), (
        f"{LOG_FILE} reports status=OK, but {OUTPUT_FILE} contains at least one unsafe path"
    )


You are helping with a small log-analysis investigation in a Linux container.

A SQLite database has already been prepared at:

`/home/user/log-investigation/access_logs.sqlite`

It contains web access events for a single application. Your job is to identify which request path was responsible for a burst of HTTP 500 errors during the incident window.

Please inspect the database using SQLite and create a verification report at:

`/home/user/log-investigation/incident_summary.txt`

The report must contain exactly 4 lines, in this exact format:

`incident_window=<START_ISO8601>,<END_ISO8601>`
`top_error_path=<PATH>`
`error_count=<COUNT>`
`checked_candidates=<N>`

Requirements:

1. Treat the incident window as all log rows whose timestamp is between `2024-04-18T14:00:00` and `2024-04-18T14:09:59`, inclusive.
2. Consider only rows where `status = 500`.
3. Find the request path with the highest number of HTTP 500 responses during that window.
4. `checked_candidates` must be the number of distinct request paths that had at least one HTTP 500 response during the incident window.
5. Use the exact ISO8601 timestamps shown above for the first line.
6. Do not include extra whitespace, headings, blank lines, explanations, or additional output in `/home/user/log-investigation/incident_summary.txt`.
7. Before finishing, verify the file exists and that it has exactly 4 lines.

The goal is to do a focused investigation: check the relevant evidence in the database, eliminate non-leading paths, write the report, verify it, and stop.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_c51b1127"
description = "You are helping with a small log-analysis investigation in a Linux container."
authors = [{ name = "Endless Terminals / Jarrod Barnes" }]
keywords = ["agentic-rl", "bounded_search_discipline", "endless-terminals", "terminal-bench-2", "wander_loop_without_convergence"]

[metadata]
source = "endless-terminals"
corpus = "processrl-core-v1"
generation_mode = "behavior_conditioned_llm_funnel"
behavior_card_id = "wander_loop_without_convergence"
capability = "bounded_search_discipline"
source_traces = ["parking-lot-pathfinding", "acl-permissions-inheritance", "grid-pathfinding", "permutation-construction-100k"]

[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

    apt-get update
    DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
        python3 \
        python3-pip \
        sqlite3 \
        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

    mkdir -p /home/user/log-investigation

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

db_path = Path("/home/user/log-investigation/access_logs.sqlite")
if db_path.exists():
    db_path.unlink()

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

cur.execute("""
CREATE TABLE access_events (
    id INTEGER PRIMARY KEY,
    ts TEXT NOT NULL,
    method TEXT NOT NULL,
    path TEXT NOT NULL,
    status INTEGER NOT NULL,
    bytes INTEGER NOT NULL,
    user_agent TEXT NOT NULL,
    request_id TEXT NOT NULL
)
""")

rows = []

def add(ts, method, path, status, bytes_=1234, ua="Mozilla/5.0", rid=None):
    if rid is None:
        rid = f"req-{len(rows)+1:04d}"
    rows.append((ts, method, path, status, bytes_, ua, rid))

# Outside-window HTTP 500 distractors
add("2024-04-18T13:58:11", "GET", "/api/search", 500, 842, "curl/8.1")
add("2024-04-18T13:59:02", "GET", "/api/report/export", 500, 912, "Mozilla/5.0")
add("2024-04-18T13:59:41", "POST", "/api/auth/login", 500, 367, "Mozilla/5.0")
add("2024-04-18T14:10:01", "GET", "/api/search", 500, 776, "curl/8.1")
add("2024-04-18T14:11:22", "GET", "/api/report/export", 500, 1042, "Mozilla/5.0")
add("2024-04-18T14:12:03", "GET", "/api/catalog", 500, 690, "Mozilla/5.0")

# Incident-window HTTP 500 evidence rows
for ts in [
    "2024-04-18T14:00:03",
    "2024-04-18T14:01:17",
    "2024-04-18T14:02:29",
    "2024-04-18T14:04:45",
    "2024-04-18T14:07:14",
    "2024-04-18T14:09:58",
]:
    add(ts, "GET", "/api/search", 500, 815, "Mozilla/5.0")

for ts in [
    "2024-04-18T14:00:12",
    "2024-04-18T14:00:59",
    "2024-04-18T14:01:36",
    "2024-04-18T14:02:04",
    "2024-04-18T14:03:51",
    "2024-04-18T14:05:23",
    "2024-04-18T14:06:08",
    "2024-04-18T14:08:40",
    "2024-04-18T14:09:12",
]:
    add(ts, "GET", "/api/report/export", 500, 1096, "Mozilla/5.0")

for ts in [
    "2024-04-18T14:00:48",
    "2024-04-18T14:04:10",
    "2024-04-18T14:06:31",
]:
    add(ts, "POST", "/api/auth/login", 500, 401, "Mozilla/5.0")

for ts in [
    "2024-04-18T14:02:44",
    "2024-04-18T14:03:18",
    "2024-04-18T14:05:57",
    "2024-04-18T14:08:05",
]:
    add(ts, "GET", "/api/catalog", 500, 724, "Mozilla/5.0")

# Incident-window non-500 distractors across required paths and statuses
non_500_rows = [
    ("2024-04-18T14:00:05", "GET", "/healthz", 200, 24, "kube-probe/1.28"),
    ("2024-04-18T14:00:18", "GET", "/static/app.js", 200, 43122, "Mozilla/5.0"),
    ("2024-04-18T14:00:31", "GET", "/api/search", 200, 2048, "Mozilla/5.0"),
    ("2024-04-18T14:00:44", "POST", "/api/auth/login", 302, 128, "Mozilla/5.0"),
    ("2024-04-18T14:01:02", "GET", "/api/catalog", 200, 3180, "Mozilla/5.0"),
    ("2024-04-18T14:01:23", "GET", "/api/report/export", 200, 6200, "Mozilla/5.0"),
    ("2024-04-18T14:01:47", "GET", "/static/app.js", 304 if False else 200, 43122, "Mozilla/5.0"),
    ("2024-04-18T14:02:11", "POST", "/api/auth/login", 201, 96, "Mozilla/5.0"),
    ("2024-04-18T14:02:33", "GET", "/healthz", 204, 0, "kube-probe/1.28"),
    ("2024-04-18T14:02:58", "GET", "/api/search", 404, 512, "Mozilla/5.0"),
    ("2024-04-18T14:03:09", "GET", "/api/catalog", 200, 3021, "Mozilla/5.0"),
    ("2024-04-18T14:03:27", "GET", "/static/app.js", 200, 43122, "Mozilla/5.0"),
    ("2024-04-18T14:03:42", "GET", "/api/report/export", 302, 144, "Mozilla/5.0"),
    ("2024-04-18T14:04:04", "GET", "/healthz", 200, 24, "kube-probe/1.28"),
    ("2024-04-18T14:04:32", "GET", "/api/search", 200, 2101, "Mozilla/5.0"),
    ("2024-04-18T14:04:58", "GET", "/api/catalog", 404, 640, "Mozilla/5.0"),
    ("2024-04-18T14:05:16", "GET", "/static/app.js", 200, 43122, "Mozilla/5.0"),
    ("2024-04-18T14:05:41", "POST", "/api/auth/login", 302, 128, "Mozilla/5.0"),
    ("2024-04-18T14:06:02", "GET", "/api/report/export", 200, 5900, "Mozilla/5.0"),
    ("2024-04-18T14:06:24", "GET", "/healthz", 204, 0, "kube-probe/1.28"),
    ("2024-04-18T14:06:49", "GET", "/api/search", 200, 1988, "Mozilla/5.0"),
    ("2024-04-18T14:07:03", "GET", "/static/app.js", 200, 43122, "Mozilla/5.0"),
    ("2024-04-18T14:07:36", "GET", "/api/catalog", 200, 3333, "Mozilla/5.0"),
    ("2024-04-18T14:08:12", "GET", "/api/report/export", 404, 700, "Mozilla/5.0"),
    ("2024-04-18T14:08:27", "GET", "/healthz", 200, 24, "kube-probe/1.28"),
    ("2024-04-18T14:08:53", "POST", "/api/auth/login", 201, 104, "Mozilla/5.0"),
    ("2024-04-18T14:09:07", "GET", "/static/app.js", 200, 43122, "Mozilla/5.0"),
    ("2024-04-18T14:09:31", "GET", "/api/search", 302, 160, "Mozilla/5.0"),
    ("2024-04-18T14:09:45", "GET", "/api/catalog", 204, 0, "Mozilla/5.0"),
]
for ts, method, path, status, bytes_, ua in non_500_rows:
    add(ts, method, path, status, bytes_, ua)

# A small amount of additional plausible traffic outside the incident window
extra_rows = [
    ("2024-04-18T13:55:10", "GET", "/healthz", 200, 24, "kube-probe/1.28"),
    ("2024-04-18T13:56:25", "GET", "/static/app.js", 200, 43122, "Mozilla/5.0"),
    ("2024-04-18T14:12:44", "GET", "/healthz", 200, 24, "kube-probe/1.28"),
    ("2024-04-18T14:13:08", "GET", "/api/search", 200, 1901, "Mozilla/5.0"),
]
for ts, method, path, status, bytes_, ua in extra_rows:
    add(ts, method, path, status, bytes_, ua)

cur.executemany(
    """
    INSERT INTO access_events
        (ts, method, path, status, bytes, user_agent, request_id)
    VALUES (?, ?, ?, ?, ?, ?, ?)
    """,
    rows,
)
conn.commit()
conn.close()
PY

    chown -R user:user /home/user/log-investigation
    chmod 755 /home/user
    chmod 775 /home/user/log-investigation
    chmod 664 /home/user/log-investigation/access_logs.sqlite

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

# test_final_state.py
from pathlib import Path

import pytest

SUMMARY_PATH = Path("/home/user/log-investigation/incident_summary.txt")

EXPECTED_LINES = [
    "incident_window=2024-04-18T14:00:00,2024-04-18T14:09:59",
    "top_error_path=/api/report/export",
    "error_count=9",
    "checked_candidates=4",
]

EXPECTED_CONTENT_NO_TRAILING_NEWLINE = "\n".join(EXPECTED_LINES)
EXPECTED_CONTENT_WITH_TRAILING_NEWLINE = EXPECTED_CONTENT_NO_TRAILING_NEWLINE + "\n"

def _read_summary_bytes():
    assert SUMMARY_PATH.exists(), (
        "Verification report is missing. Expected file to exist at absolute path: "
        f"{SUMMARY_PATH}"
    )
    assert SUMMARY_PATH.is_file(), (
        "Verification report path exists but is not a regular file: "
        f"{SUMMARY_PATH}"
    )
    try:
        return SUMMARY_PATH.read_bytes()
    except OSError as exc:
        pytest.fail(f"Could not read verification report at {SUMMARY_PATH}: {exc}")

def test_incident_summary_file_exists_and_is_readable():
    data = _read_summary_bytes()
    assert data is not None, f"Could not read report file at {SUMMARY_PATH}"

def test_incident_summary_is_valid_utf8_text():
    data = _read_summary_bytes()
    try:
        data.decode("utf-8")
    except UnicodeDecodeError as exc:
        pytest.fail(
            f"Report file {SUMMARY_PATH} must be UTF-8/plain text, but decoding failed: {exc}"
        )

def test_incident_summary_has_exactly_four_nonblank_lines():
    text = _read_summary_bytes().decode("utf-8")

    lines = text.splitlines()
    assert len(lines) == 4, (
        f"Report must contain exactly 4 lines. Observed {len(lines)} line(s): "
        f"{lines!r}. Do not include headings, blank lines, or extra output."
    )

    blank_line_numbers = [
        index
        for index, line in enumerate(lines, start=1)
        if line == ""
    ]
    assert not blank_line_numbers, (
        "Report must not contain blank lines. Blank line number(s): "
        f"{blank_line_numbers!r}"
    )

def test_incident_summary_has_no_extra_trailing_blank_lines_or_content():
    text = _read_summary_bytes().decode("utf-8")

    assert text in {
        EXPECTED_CONTENT_NO_TRAILING_NEWLINE,
        EXPECTED_CONTENT_WITH_TRAILING_NEWLINE,
    }, (
        "Report content must be exactly the expected four lines. A single trailing "
        "newline after line 4 is acceptable, but extra blank lines, whitespace, "
        "headings, or explanations are not.\n"
        f"Expected exactly:\n{EXPECTED_CONTENT_NO_TRAILING_NEWLINE!r}\n"
        f"Observed:\n{text!r}"
    )

def test_incident_summary_line_1_incident_window_is_exact():
    lines = _read_summary_bytes().decode("utf-8").splitlines()
    assert len(lines) >= 1, "Report is missing line 1 for incident_window."

    assert lines[0] == EXPECTED_LINES[0], (
        "Line 1 must use the exact inclusive incident window timestamps shown in "
        "the task description.\n"
        f"Expected: {EXPECTED_LINES[0]!r}\n"
        f"Observed: {lines[0]!r}"
    )

def test_incident_summary_line_2_top_error_path_is_exact():
    lines = _read_summary_bytes().decode("utf-8").splitlines()
    assert len(lines) >= 2, "Report is missing line 2 for top_error_path."

    assert lines[1] == EXPECTED_LINES[1], (
        "Line 2 must identify the request path with the highest number of HTTP "
        "500 responses in the incident window. The correct leader is "
        "/api/report/export, not outside-window or non-500 distractors.\n"
        f"Expected: {EXPECTED_LINES[1]!r}\n"
        f"Observed: {lines[1]!r}"
    )

def test_incident_summary_line_3_error_count_is_exact():
    lines = _read_summary_bytes().decode("utf-8").splitlines()
    assert len(lines) >= 3, "Report is missing line 3 for error_count."

    assert lines[2] == EXPECTED_LINES[2], (
        "Line 3 must contain the exact count of HTTP 500 responses for "
        "/api/report/export within 2024-04-18T14:00:00 through "
        "2024-04-18T14:09:59 inclusive.\n"
        f"Expected: {EXPECTED_LINES[2]!r}\n"
        f"Observed: {lines[2]!r}"
    )

def test_incident_summary_line_4_checked_candidates_is_exact():
    lines = _read_summary_bytes().decode("utf-8").splitlines()
    assert len(lines) >= 4, "Report is missing line 4 for checked_candidates."

    assert lines[3] == EXPECTED_LINES[3], (
        "Line 4 must contain the number of distinct request paths with at least "
        "one HTTP 500 response in the incident window. The correct candidate "
        "count is 4.\n"
        f"Expected: {EXPECTED_LINES[3]!r}\n"
        f"Observed: {lines[3]!r}"
    )

def test_incident_summary_has_no_leading_or_trailing_whitespace_on_any_line():
    lines = _read_summary_bytes().decode("utf-8").splitlines()

    bad_lines = [
        (index, line)
        for index, line in enumerate(lines, start=1)
        if line != line.strip()
    ]
    assert not bad_lines, (
        "Report lines must not contain leading or trailing whitespace. "
        f"Offending line(s): {bad_lines!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’re helping with a small log-analysis optimization check in `/home/user/solver_case`. The directory already contains an input file at `/home/user/solver_case/events.csv` and a Python utility at `/home/user/solver_case/select_patterns.py`.

Please investigate the event patterns by using the provided optimization utility to choose the best compact set of patterns, then write a concise analyst report.

Your final deliverable must be the file:

`/home/user/solver_case/pattern_report.txt`

The report must contain exactly 5 non-empty lines in this exact format:

1. `solver_status=<status>`
2. `selected_count=<integer>`
3. `selected_patterns=<comma-separated pattern ids in ascending order>`
4. `covered_events=<integer>`
5. `total_score=<integer>`

Requirements:

- Run the provided solver utility in `/home/user/solver_case/select_patterns.py`; do not manually guess the selected pattern set.
- The utility may produce little or no terminal output, so do not treat silence as success.
- Inspect the files it creates in `/home/user/solver_case/output/`.
- Verify the final report by running the provided checker at `/home/user/solver_case/check_report.py`.
- The checker’s success message must be written verbatim to `/home/user/solver_case/verification.log`.
- Stop only after `/home/user/solver_case/pattern_report.txt` exists and the checker has confirmed it.

The report should use the solver result, not the raw event list. If the solver output includes multiple data files, use the one that records the final optimization solution.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_c72481a6"
description = "You\u2019re helping with a small log-analysis optimization check in `/home/user/solver_case`. The directory already contains an input file at `/home/user/solver_case/events.csv` and a Python utility at `/home/user/solver_case/select_patterns.py`"
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/*

    mkdir -p /home/user/solver_case

    cat > /home/user/solver_case/events.csv <<'EOF'
event_id,service,severity,region,pattern_id
1,auth,high,us-east,P03
2,billing,medium,us-east,P01
3,auth,medium,eu-west,P03
4,checkout,high,us-east,P02
5,billing,high,eu-west,P04
6,checkout,medium,us-east,P02
7,auth,low,us-east,P03
8,billing,medium,ap-south,P01
9,checkout,high,eu-west,P02
10,search,medium,us-east,P05
11,search,high,eu-west,P05
12,billing,low,us-east,P04
EOF

    cat > /home/user/solver_case/select_patterns.py <<'PY'
#!/usr/bin/env python3
import csv
import itertools
import json
from pathlib import Path

EVENTS_CSV = Path("/home/user/solver_case/events.csv")
OUTPUT_DIR = Path("/home/user/solver_case/output")
CANDIDATE_SUMMARY = OUTPUT_DIR / "candidate_summary.txt"
FINAL_SOLUTION = OUTPUT_DIR / "final_solution.json"

PATTERNS = {
    "P01": {"events": [2, 8], "score": 9},
    "P02": {"events": [4, 6, 9], "score": 15},
    "P03": {"events": [1, 3, 7], "score": 14},
    "P04": {"events": [5, 12], "score": 8},
    "P05": {"events": [10, 11], "score": 10},
}

CHOOSE_EXACTLY = 3

def read_events():
    with EVENTS_CSV.open("r", encoding="utf-8", newline="") as handle:
        return list(csv.DictReader(handle))

def write_candidate_artifact():
    CANDIDATE_SUMMARY.write_text(
        "candidate_status=generated\n"
        "candidate_patterns=P01,P03\n"
        "candidate_score=17\n"
        "note=not final optimization solution\n",
        encoding="utf-8",
    )

def solve():
    best_patterns = None
    best_score = None
    best_covered = None

    pattern_ids = sorted(PATTERNS)
    for combo in itertools.combinations(pattern_ids, CHOOSE_EXACTLY):
        score = sum(PATTERNS[pid]["score"] for pid in combo)
        covered_events = sorted(
            set().union(*(PATTERNS[pid]["events"] for pid in combo))
        )
        if (
            best_score is None
            or score > best_score
            or (score == best_score and list(combo) < best_patterns)
        ):
            best_patterns = list(combo)
            best_score = score
            best_covered = covered_events

    return {
        "solver_status": "OPTIMAL",
        "selected_patterns": best_patterns,
        "selected_count": len(best_patterns),
        "covered_events": len(best_covered),
        "total_score": best_score,
    }

def main():
    read_events()
    OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
    write_candidate_artifact()
    solution = solve()
    FINAL_SOLUTION.write_text(
        json.dumps(solution, indent=2) + "\n",
        encoding="utf-8",
    )

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

    cat > /home/user/solver_case/check_report.py <<'PY'
#!/usr/bin/env python3
import re
import sys
from pathlib import Path

REPORT_PATH = Path("/home/user/solver_case/pattern_report.txt")
SUCCESS = "REPORT CHECK PASSED: optimal pattern report verified"

EXPECTED_LINES = [
    "solver_status=OPTIMAL",
    "selected_count=3",
    "selected_patterns=P02,P03,P05",
    "covered_events=8",
    "total_score=39",
]

def fail(message: str) -> int:
    print(f"REPORT CHECK FAILED: {message}", file=sys.stderr)
    return 1

def main() -> int:
    if not REPORT_PATH.exists():
        return fail(f"missing report file: {REPORT_PATH}")
    if not REPORT_PATH.is_file():
        return fail(f"report path is not a regular file: {REPORT_PATH}")

    raw = REPORT_PATH.read_text(encoding="utf-8")

    if raw.endswith("\n"):
        body = raw[:-1]
        if body.endswith("\n"):
            return fail("report has extra trailing blank line or too many lines")
    else:
        body = raw

    lines = body.split("\n")
    if len(lines) != 5:
        return fail(f"expected exactly 5 non-empty lines, found {len(lines)}")

    for idx, line in enumerate(lines, start=1):
        if line == "":
            return fail(f"line {idx} is blank")
        if line != line.rstrip(" "):
            return fail(f"line {idx} has trailing spaces")
        if line != line.rstrip("\t"):
            return fail(f"line {idx} has trailing tabs")

    if lines != EXPECTED_LINES:
        for idx, (actual, expected) in enumerate(zip(lines, EXPECTED_LINES), start=1):
            if actual != expected:
                return fail(
                    f"line {idx} mismatch: expected {expected!r}, got {actual!r}"
                )
        return fail("report contents do not match expected values")

    selected = lines[2].split("=", 1)[1]
    parts = selected.split(",")
    if parts != sorted(parts):
        return fail("selected patterns are not in ascending order")
    if not all(re.fullmatch(r"P\d{2}", part) for part in parts):
        return fail("selected patterns are not comma-separated pattern IDs")

    print(SUCCESS)
    return 0

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

    chmod 755 /home/user/solver_case/select_patterns.py
    chmod 755 /home/user/solver_case/check_report.py
    chmod 666 /home/user/solver_case/events.csv
    chmod 777 /home/user /home/user/solver_case

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

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

import pytest

BASE_DIR = Path("/home/user/solver_case")
EVENTS_CSV = Path("/home/user/solver_case/events.csv")
SELECT_PATTERNS = Path("/home/user/solver_case/select_patterns.py")
CHECK_REPORT = Path("/home/user/solver_case/check_report.py")
OUTPUT_DIR = Path("/home/user/solver_case/output")
CANDIDATE_SUMMARY = Path("/home/user/solver_case/output/candidate_summary.txt")
FINAL_SOLUTION = Path("/home/user/solver_case/output/final_solution.json")
PATTERN_REPORT = Path("/home/user/solver_case/pattern_report.txt")
VERIFICATION_LOG = Path("/home/user/solver_case/verification.log")

EXPECTED_REPORT_TEXT = (
    "solver_status=OPTIMAL\n"
    "selected_count=3\n"
    "selected_patterns=P02,P03,P05\n"
    "covered_events=8\n"
    "total_score=39\n"
)

EXPECTED_VERIFICATION_LOG_TEXT = (
    "REPORT CHECK PASSED: optimal pattern report verified\n"
)

EXPECTED_FINAL_SOLUTION = {
    "solver_status": "OPTIMAL",
    "selected_patterns": ["P02", "P03", "P05"],
    "selected_count": 3,
    "covered_events": 8,
    "total_score": 39,
}

EXPECTED_FINAL_SOLUTION_TEXT = (
    "{\n"
    '  "solver_status": "OPTIMAL",\n'
    '  "selected_patterns": [\n'
    '    "P02",\n'
    '    "P03",\n'
    '    "P05"\n'
    "  ],\n"
    '  "selected_count": 3,\n'
    '  "covered_events": 8,\n'
    '  "total_score": 39\n'
    "}\n"
)

MISLEADING_CANDIDATE_SNIPPETS = [
    "candidate_status=generated",
    "candidate_patterns=P01,P03",
    "candidate_score=17",
    "note=not final optimization solution",
]

def _assert_regular_file(path: Path, description: str) -> None:
    assert path.exists(), f"Missing {description}: {path}"
    assert path.is_file(), f"{description} exists but is not a regular file: {path}"

def _assert_directory(path: Path, description: str) -> None:
    assert path.exists(), f"Missing {description}: {path}"
    assert path.is_dir(), f"{description} exists but is not a directory: {path}"

def _assert_user_executable(path: Path, description: str) -> None:
    mode = path.stat().st_mode
    assert mode & stat.S_IXUSR, f"{description} is not executable by its owner/user: {path}"

def test_required_base_files_and_output_directory_exist() -> None:
    _assert_directory(BASE_DIR, "solver case directory")
    _assert_regular_file(EVENTS_CSV, "input events CSV")
    _assert_regular_file(SELECT_PATTERNS, "solver utility")
    _assert_user_executable(SELECT_PATTERNS, "solver utility")
    _assert_regular_file(CHECK_REPORT, "report checker utility")
    _assert_user_executable(CHECK_REPORT, "report checker utility")
    _assert_directory(OUTPUT_DIR, "solver output directory")

def test_solver_was_run_and_final_solution_json_exists() -> None:
    _assert_regular_file(FINAL_SOLUTION, "final solver solution JSON")

    assert FINAL_SOLUTION.stat().st_size > 0, (
        f"{FINAL_SOLUTION} is empty; the solver's final optimization output "
        "must be present and populated."
    )

    assert CANDIDATE_SUMMARY.exists(), (
        f"{CANDIDATE_SUMMARY} is missing. The provided solver normally creates "
        "this misleading partial artifact before writing the final solution; "
        "its absence suggests the solver utility may not have been run."
    )

def test_candidate_summary_is_not_used_as_final_report_source() -> None:
    _assert_regular_file(CANDIDATE_SUMMARY, "candidate summary artifact")
    candidate_text = CANDIDATE_SUMMARY.read_text(encoding="utf-8")

    missing = [
        snippet for snippet in MISLEADING_CANDIDATE_SNIPPETS
        if snippet not in candidate_text
    ]
    assert not missing, (
        f"{CANDIDATE_SUMMARY} does not look like the expected misleading "
        "candidate artifact. Missing snippets: "
        + ", ".join(repr(item) for item in missing)
    )

    if PATTERN_REPORT.exists() and PATTERN_REPORT.is_file():
        report_text = PATTERN_REPORT.read_text(encoding="utf-8")
        assert "P01,P03" not in report_text, (
            f"{PATTERN_REPORT} appears to use the misleading candidate pattern "
            "set P01,P03 instead of the final optimization solution P02,P03,P05."
        )
        assert "candidate_" not in report_text, (
            f"{PATTERN_REPORT} contains candidate-summary fields. The report "
            "must be built from output/final_solution.json, not candidate_summary.txt."
        )

def test_final_solution_json_has_exact_expected_contents_and_format() -> None:
    _assert_regular_file(FINAL_SOLUTION, "final solver solution JSON")

    raw = FINAL_SOLUTION.read_text(encoding="utf-8")
    assert raw == EXPECTED_FINAL_SOLUTION_TEXT, (
        f"{FINAL_SOLUTION} does not exactly match the expected pretty-printed "
        "final optimization solution JSON."
    )

    try:
        parsed = json.loads(raw)
    except json.JSONDecodeError as exc:
        pytest.fail(f"{FINAL_SOLUTION} is not valid JSON: {exc}")

    assert parsed == EXPECTED_FINAL_SOLUTION, (
        f"{FINAL_SOLUTION} contains valid JSON but not the expected final "
        f"optimization result. Expected {EXPECTED_FINAL_SOLUTION!r}, got {parsed!r}."
    )

def test_pattern_report_exists_and_has_exact_required_contents() -> None:
    _assert_regular_file(PATTERN_REPORT, "final analyst report")

    actual = PATTERN_REPORT.read_text(encoding="utf-8")
    assert actual == EXPECTED_REPORT_TEXT, (
        f"{PATTERN_REPORT} has incorrect contents. It must contain exactly five "
        "non-empty lines in the required order, with a single trailing newline:\n"
        f"{EXPECTED_REPORT_TEXT!r}\n"
        f"Actual contents were:\n{actual!r}"
    )

    lines = actual.splitlines()
    assert len(lines) == 5, (
        f"{PATTERN_REPORT} must contain exactly 5 non-empty report lines; "
        f"found {len(lines)} lines."
    )
    assert all(line.strip() == line and line for line in lines), (
        f"{PATTERN_REPORT} must not contain blank lines or leading/trailing spaces."
    )

def test_pattern_report_matches_final_solution_json_values() -> None:
    _assert_regular_file(FINAL_SOLUTION, "final solver solution JSON")
    _assert_regular_file(PATTERN_REPORT, "final analyst report")

    solution = json.loads(FINAL_SOLUTION.read_text(encoding="utf-8"))
    report_lines = PATTERN_REPORT.read_text(encoding="utf-8").splitlines()

    expected_from_solution = [
        f"solver_status={solution['solver_status']}",
        f"selected_count={solution['selected_count']}",
        "selected_patterns=" + ",".join(solution["selected_patterns"]),
        f"covered_events={solution['covered_events']}",
        f"total_score={solution['total_score']}",
    ]

    assert report_lines == expected_from_solution, (
        f"{PATTERN_REPORT} does not faithfully reflect the values in "
        f"{FINAL_SOLUTION}. Expected lines derived from final solution: "
        f"{expected_from_solution!r}; got {report_lines!r}."
    )

    assert solution["selected_patterns"] == sorted(solution["selected_patterns"]), (
        f"{FINAL_SOLUTION} selected_patterns must be in ascending order."
    )

def test_verification_log_contains_exact_checker_success_message() -> None:
    _assert_regular_file(VERIFICATION_LOG, "checker verification log")

    actual = VERIFICATION_LOG.read_text(encoding="utf-8")
    assert actual == EXPECTED_VERIFICATION_LOG_TEXT, (
        f"{VERIFICATION_LOG} must contain exactly the checker success message "
        "written verbatim, including its trailing newline. "
        f"Expected {EXPECTED_VERIFICATION_LOG_TEXT!r}, got {actual!r}."
    )

def test_checker_currently_passes_against_final_report() -> None:
    _assert_regular_file(CHECK_REPORT, "report checker utility")
    _assert_user_executable(CHECK_REPORT, "report checker utility")
    _assert_regular_file(PATTERN_REPORT, "final analyst report")

    result = subprocess.run(
        [str(CHECK_REPORT)],
        cwd=str(BASE_DIR),
        text=True,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        timeout=10,
        check=False,
    )

    assert result.returncode == 0, (
        f"Running {CHECK_REPORT} against {PATTERN_REPORT} did not succeed. "
        f"Exit code: {result.returncode}. "
        f"stdout: {result.stdout!r}. stderr: {result.stderr!r}."
    )
    assert result.stdout == EXPECTED_VERIFICATION_LOG_TEXT, (
        f"{CHECK_REPORT} stdout is not the expected success message. "
        f"Expected {EXPECTED_VERIFICATION_LOG_TEXT!r}, got {result.stdout!r}."
    )
    assert result.stderr == "", (
        f"{CHECK_REPORT} should not write stderr on success, but wrote: "
        f"{result.stderr!r}"
    )

def test_deliverable_paths_are_absolute_and_under_expected_directory() -> None:
    for path in [
        OUTPUT_DIR,
        CANDIDATE_SUMMARY,
        FINAL_SOLUTION,
        PATTERN_REPORT,
        VERIFICATION_LOG,
    ]:
        assert path.is_absolute(), f"Tested deliverable path is not absolute: {path}"
        assert str(path).startswith("/home/user/solver_case/"), (
            f"Deliverable path is outside /home/user/solver_case: {path}"
        )


I need you to update the hostname-resolution source of truth for a small configuration-manager workspace under `/home/user/cm-dns`.

The workspace currently has an old hostname mapping file at `/home/user/cm-dns/legacy/hosts.static` and a newer DNS override file at `/home/user/cm-dns/current/dns-overrides.zone`. The configuration manager has been changed so that `/home/user/cm-dns/current/dns-overrides.zone` is now the only authoritative location. Please migrate the active hostname mappings into the new file, retire the old file so it cannot be mistaken for the active source, and write a verification log.

Final required state:

1. `/home/user/cm-dns/current/dns-overrides.zone` must exist.
2. It must contain exactly one active hostname-resolution record per line, using this format:
   `HOSTNAME A IPV4_ADDRESS`
3. The migrated records must preserve the hostname-to-IP semantics from the legacy file.
4. Lines in `/home/user/cm-dns/current/dns-overrides.zone` must be sorted lexicographically by hostname.
5. The file must not contain comments, blank lines, aliases, TTL values, or extra whitespace. Each line must have exactly three fields separated by a single space.
6. `/home/user/cm-dns/legacy/hosts.static` must no longer exist as a regular file after the migration. It should be retired in a way that makes it clear it is not authoritative anymore.
7. Create `/home/user/cm-dns/current/resolution-verification.log`.

The verification log is important because automated checks will inspect it. It must contain exactly these five lines, in this exact key/value format, with no extra lines:

`source_of_truth=/home/user/cm-dns/current/dns-overrides.zone`
`legacy_regular_file=absent`
`record_count=N`
`first_record=HOSTNAME A IPV4_ADDRESS`
`last_record=HOSTNAME A IPV4_ADDRESS`

Replace `N`, `HOSTNAME`, and `IPV4_ADDRESS` with values computed from the final `/home/user/cm-dns/current/dns-overrides.zone`, not from the retired legacy file. The first and last records must reflect the sorted final DNS override file.

Before finishing, verify the final state by reading the new source of truth at `/home/user/cm-dns/current/dns-overrides.zone`, not the legacy path.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_cd6c175f"
description = "I need you to update the hostname-resolution source of truth for a small configuration-manager workspace under `/home/user/cm-dns`."
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

    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/*

    mkdir -p /home/user/cm-dns/legacy
    mkdir -p /home/user/cm-dns/current

    cat > /home/user/cm-dns/legacy/hosts.static <<'EOF'
# managed by old config-manager v1
10.44.8.21 api.internal.test api
10.44.8.22 cache.internal.test cache
10.44.8.20 app.internal.test app
10.44.8.25 db.internal.test db
EOF

    cat > /home/user/cm-dns/current/dns-overrides.zone <<'EOF'
# managed by config-manager v2
# TODO: migrate active host records from ../legacy/hosts.static
stale.internal.test A 192.0.2.99
EOF

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

# test_final_state.py
from pathlib import Path
import ipaddress
import stat

CURRENT_ZONE = Path("/home/user/cm-dns/current/dns-overrides.zone")
LEGACY_HOSTS = Path("/home/user/cm-dns/legacy/hosts.static")
VERIFICATION_LOG = Path("/home/user/cm-dns/current/resolution-verification.log")

EXPECTED_ZONE_CONTENT = (
    "api.internal.test A 10.44.8.21\n"
    "app.internal.test A 10.44.8.20\n"
    "cache.internal.test A 10.44.8.22\n"
    "db.internal.test A 10.44.8.25\n"
)

EXPECTED_RECORDS = [
    "api.internal.test A 10.44.8.21",
    "app.internal.test A 10.44.8.20",
    "cache.internal.test A 10.44.8.22",
    "db.internal.test A 10.44.8.25",
]

EXPECTED_HOST_TO_IP = {
    "api.internal.test": "10.44.8.21",
    "app.internal.test": "10.44.8.20",
    "cache.internal.test": "10.44.8.22",
    "db.internal.test": "10.44.8.25",
}

EXPECTED_LOG_CONTENT = (
    "source_of_truth=/home/user/cm-dns/current/dns-overrides.zone\n"
    "legacy_regular_file=absent\n"
    "record_count=4\n"
    "first_record=api.internal.test A 10.44.8.21\n"
    "last_record=db.internal.test A 10.44.8.25\n"
)

def _read_zone_text():
    assert CURRENT_ZONE.exists(), (
        f"Authoritative DNS override file is missing: {CURRENT_ZONE}"
    )
    assert CURRENT_ZONE.is_file(), (
        f"Authoritative DNS override path exists but is not a regular file: "
        f"{CURRENT_ZONE}"
    )
    return CURRENT_ZONE.read_text(encoding="utf-8")

def _zone_lines():
    return _read_zone_text().splitlines()

def test_authoritative_dns_overrides_zone_exists_as_regular_file():
    assert CURRENT_ZONE.exists(), (
        f"Final source of truth must exist at absolute path {CURRENT_ZONE}"
    )
    assert CURRENT_ZONE.is_file(), (
        f"Final source of truth must be a regular file at {CURRENT_ZONE}"
    )

def test_authoritative_dns_overrides_zone_has_exact_expected_contents():
    actual = _read_zone_text()
    assert actual == EXPECTED_ZONE_CONTENT, (
        f"{CURRENT_ZONE} does not exactly match the required final migrated "
        "DNS override contents. It must replace the stale placeholder and "
        "contain only the four migrated canonical hostname records sorted by "
        "hostname.\n"
        f"Expected:\n{EXPECTED_ZONE_CONTENT!r}\n"
        f"Actual:\n{actual!r}"
    )

def test_zone_contains_only_active_records_with_strict_three_field_format():
    lines = _zone_lines()

    assert lines, f"{CURRENT_ZONE} must not be empty."
    assert all(line.strip() == line for line in lines), (
        f"{CURRENT_ZONE} contains leading or trailing whitespace on one or "
        "more lines; each line must be exactly 'HOSTNAME A IPV4_ADDRESS'."
    )
    assert all(line for line in lines), (
        f"{CURRENT_ZONE} contains blank lines; blank lines are not allowed."
    )

    for line in lines:
        assert "#" not in line, (
            f"{CURRENT_ZONE} contains a comment or comment marker, which is "
            f"not allowed in the final authoritative file: {line!r}"
        )
        assert "\t" not in line, (
            f"{CURRENT_ZONE} contains tab whitespace; fields must be separated "
            f"by a single space only: {line!r}"
        )
        assert "  " not in line, (
            f"{CURRENT_ZONE} contains extra whitespace; fields must be "
            f"separated by a single space only: {line!r}"
        )

        fields = line.split(" ")
        assert len(fields) == 3, (
            f"Bad record in {CURRENT_ZONE}: {line!r}. Each line must have "
            "exactly three fields: HOSTNAME A IPV4_ADDRESS."
        )

        hostname, record_type, ip_address = fields
        assert record_type == "A", (
            f"Bad record type in {CURRENT_ZONE}: {line!r}. The middle field "
            "must be exactly 'A'."
        )

        try:
            parsed_ip = ipaddress.ip_address(ip_address)
        except ValueError as exc:
            raise AssertionError(
                f"Bad IPv4 address in {CURRENT_ZONE}: {line!r}. "
                f"{ip_address!r} is not a valid IP address."
            ) from exc

        assert parsed_ip.version == 4, (
            f"Bad IP version in {CURRENT_ZONE}: {line!r}. The address must be "
            "IPv4."
        )

        assert hostname.endswith(".internal.test"), (
            f"Unexpected hostname in {CURRENT_ZONE}: {hostname!r}. The final "
            "records should use canonical hostnames from the legacy source."
        )

def test_zone_records_are_sorted_lexicographically_by_hostname():
    lines = _zone_lines()
    hostnames = [line.split(" ")[0] for line in lines]
    assert hostnames == sorted(hostnames), (
        f"Records in {CURRENT_ZONE} are not sorted lexicographically by "
        f"hostname. Actual order: {hostnames!r}; expected order: "
        f"{sorted(hostnames)!r}."
    )

def test_zone_preserves_legacy_hostname_to_ip_semantics_and_drops_aliases():
    lines = _zone_lines()
    parsed = {}
    for line in lines:
        fields = line.split(" ")
        assert len(fields) == 3, (
            f"Cannot validate migrated semantics because this line is not in "
            f"strict DNS override format: {line!r}"
        )
        hostname, record_type, ip_address = fields
        assert record_type == "A", (
            f"Cannot validate migrated semantics because this line does not "
            f"use an A record: {line!r}"
        )
        parsed[hostname] = ip_address

    assert parsed == EXPECTED_HOST_TO_IP, (
        f"{CURRENT_ZONE} does not preserve the exact canonical hostname-to-IP "
        "mappings from the legacy hosts file, or it contains extra/missing "
        "records.\n"
        f"Expected mapping: {EXPECTED_HOST_TO_IP!r}\n"
        f"Actual mapping: {parsed!r}"
    )

    forbidden_alias_records = {
        "api A 10.44.8.21",
        "app A 10.44.8.20",
        "cache A 10.44.8.22",
        "db A 10.44.8.25",
    }
    actual_lines = set(lines)
    present_aliases = sorted(actual_lines & forbidden_alias_records)
    assert not present_aliases, (
        f"{CURRENT_ZONE} includes aliases that should have been dropped: "
        + ", ".join(present_aliases)
    )

def test_stale_current_record_and_initial_comments_are_absent():
    actual = _read_zone_text()

    assert "stale.internal.test A 192.0.2.99" not in actual, (
        f"{CURRENT_ZONE} still contains the stale placeholder record. The "
        "current file must be replaced with migrated active records, not "
        "appended to."
    )
    assert "managed by config-manager v2" not in actual, (
        f"{CURRENT_ZONE} still contains the initial placeholder comment. "
        "Comments are not allowed in the final authoritative file."
    )
    assert "TODO: migrate active host records" not in actual, (
        f"{CURRENT_ZONE} still contains the initial TODO comment. Comments "
        "are not allowed in the final authoritative file."
    )

def test_legacy_hosts_static_is_retired_and_not_regular_file():
    if LEGACY_HOSTS.exists():
        mode = LEGACY_HOSTS.lstat().st_mode
        assert not stat.S_ISREG(mode), (
            f"Legacy source {LEGACY_HOSTS} still exists as a regular file. "
            "It must be retired so it cannot be mistaken for the authoritative "
            "source."
        )
    else:
        assert not LEGACY_HOSTS.is_file(), (
            f"Legacy source {LEGACY_HOSTS} must not exist as a regular file."
        )

def test_verification_log_exists_as_regular_file():
    assert VERIFICATION_LOG.exists(), (
        f"Required verification log is missing: {VERIFICATION_LOG}"
    )
    assert VERIFICATION_LOG.is_file(), (
        f"Verification log path exists but is not a regular file: "
        f"{VERIFICATION_LOG}"
    )

def test_verification_log_has_exact_expected_contents():
    actual = VERIFICATION_LOG.read_text(encoding="utf-8")
    assert actual == EXPECTED_LOG_CONTENT, (
        f"{VERIFICATION_LOG} does not exactly match the required verification "
        "log. The log must contain exactly five key/value lines computed from "
        f"the final authoritative file {CURRENT_ZONE}, with no extra lines.\n"
        f"Expected:\n{EXPECTED_LOG_CONTENT!r}\n"
        f"Actual:\n{actual!r}"
    )

def test_verification_log_is_consistent_with_final_zone_file():
    zone_lines = _zone_lines()
    log_lines = VERIFICATION_LOG.read_text(encoding="utf-8").splitlines()

    expected_log_lines_from_zone = [
        f"source_of_truth={CURRENT_ZONE}",
        "legacy_regular_file=absent",
        f"record_count={len(zone_lines)}",
        f"first_record={zone_lines[0]}",
        f"last_record={zone_lines[-1]}",
    ]

    assert log_lines == expected_log_lines_from_zone, (
        f"{VERIFICATION_LOG} is not consistent with the final authoritative "
        f"zone file {CURRENT_ZONE}. It must be computed from the current DNS "
        "override file, not from the retired legacy file.\n"
        f"Expected from zone file: {expected_log_lines_from_zone!r}\n"
        f"Actual log lines: {log_lines!r}"
    )

def test_final_state_has_no_legacy_hosts_style_records_in_authoritative_zone():
    for line in _zone_lines():
        fields = line.split(" ")
        assert fields[1] == "A", (
            f"{CURRENT_ZONE} appears to contain a legacy /etc/hosts-style "
            f"record instead of DNS override format: {line!r}"
        )
        assert not fields[0][0].isdigit(), (
            f"{CURRENT_ZONE} appears to start a record with an IP address, "
            f"which indicates legacy /etc/hosts-style format was copied "
            f"without conversion: {line!r}"
        )


You’re helping debug a DevOps incident report in a local Python project at `/home/user/ops-pip-debug`. The service log parser in that directory is failing because the project’s Python dependency environment is inconsistent. Please repair the environment using pip-style package/environment inspection and produce a verification report.

The project contains:
- `/home/user/ops-pip-debug/requirements.txt`
- `/home/user/ops-pip-debug/logs/service.log`
- `/home/user/ops-pip-debug/analyze_logs.py`

Your goal is to make `/home/user/ops-pip-debug/analyze_logs.py` run successfully against `/home/user/ops-pip-debug/logs/service.log`, then write a machine-checkable report to `/home/user/ops-pip-debug/env_repair_report.txt`.

Important: there is an intentionally misleading partial-fix path. Simply retrying the same install command after the initial failure will not improve the state. If a pip command reports that packages are already satisfied or repeats the same conflict/failure, inspect the actual installed package metadata and change approach rather than repeating it.

Final required behavior:
1. Run the log analyzer successfully from inside `/home/user/ops-pip-debug`.
2. The analyzer must create `/home/user/ops-pip-debug/logs/summary.json`.
3. The JSON summary must describe the service log, including total log lines, error count, warning count, and a top-level status string.
4. Create `/home/user/ops-pip-debug/env_repair_report.txt` with exactly these five lines, in this order:
   - `ENV_REPAIR_STATUS=success`
   - `PYTHON_EXECUTABLE=<absolute path to the python executable used>`
   - `REQUESTS_VERSION=<installed requests version>`
   - `URLLIB3_VERSION=<installed urllib3 version>`
   - `SUMMARY_JSON=/home/user/ops-pip-debug/logs/summary.json`

Formatting requirements for `/home/user/ops-pip-debug/env_repair_report.txt`:
- No extra blank lines.
- No leading or trailing spaces on any line.
- The Python executable path must be absolute.
- The version fields must match the versions actually importable by the Python executable used to run the analyzer.
- Do not put explanatory prose in the report file.

You may use normal user-writable Python environment tooling available in the container, such as a virtual environment under `/home/user/ops-pip-debug`, pip package inspection, package uninstall/reinstall, or equivalent pip environment repair steps. Do not use root privileges. When finished, verify that the analyzer runs cleanly and that the report points to the generated summary file.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_d224e858"
description = "You\u2019re helping debug a DevOps incident report in a local Python project at `/home/user/ops-pip-debug`. The service log parser in that directory is failing because the project\u2019s Python dependency environment is inconsistent. Please repair th"
authors = [{ name = "Endless Terminals / Jarrod Barnes" }]
keywords = ["agentic-rl", "endless-terminals", "recognition_to_action_coupling", "repeat_loop_after_dead_end", "terminal-bench-2"]

[metadata]
source = "endless-terminals"
corpus = "processrl-core-v1"
generation_mode = "behavior_conditioned_llm_funnel"
behavior_card_id = "repeat_loop_after_dead_end"
capability = "recognition_to_action_coupling"
source_traces = ["pgn-chess-repair-puzzles", "book-portfolio-analysis", "bash-log-processor-fix"]

[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-pip \
        python3-venv \
        python3-setuptools \
        python3-wheel \
        ca-certificates

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

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

    python3 -m pip install --no-cache-dir --upgrade pip
    python3 -m pip install --no-cache-dir \
        pytest \
        requests==2.31.0 \
        urllib3==2.2.0 \
        python-dateutil==2.8.2

    mkdir -p /home/user/ops-pip-debug/logs
    mkdir -p /home/user/ops-pip-debug/vendor_trap/urllib3

    cat > /home/user/ops-pip-debug/requirements.txt <<'EOF'
requests==2.31.0
urllib3==1.26.18
python-dateutil==2.8.2
EOF

    cat > /home/user/ops-pip-debug/logs/service.log <<'EOF'
2024-05-12T08:15:01Z INFO api-gateway boot sequence started
2024-05-12T08:15:03Z INFO api-gateway listening on 0.0.0.0:8080
2024-05-12T08:16:10Z WARNING auth-cache refresh took 1840ms
2024-05-12T08:17:44Z ERROR upstream inventory timeout after 3000ms
2024-05-12T08:18:01Z INFO retry scheduled for inventory request
2024-05-12T08:19:22Z WARNING payment queue depth above threshold
2024-05-12T08:21:09Z ERROR checkout request failed with HTTP 502
2024-05-12T08:22:11Z INFO api-gateway health check passed
EOF

    cat > /home/user/ops-pip-debug/analyze_logs.py <<'EOF'
#!/usr/bin/env python3
import json
import pathlib
import sys

try:
    import requests
    import urllib3
except Exception as exc:
    print(f"IMPORT_ERROR: {exc}", file=sys.stderr)
    sys.exit(2)

EXPECTED_REQUESTS = "2.31.0"
EXPECTED_URLLIB3_PREFIX = "1.26."

if requests.__version__ != EXPECTED_REQUESTS:
    print(
        f"ENV_ERROR: requests version {requests.__version__} does not match required {EXPECTED_REQUESTS}",
        file=sys.stderr,
    )
    sys.exit(3)

if not urllib3.__version__.startswith(EXPECTED_URLLIB3_PREFIX):
    print(
        f"ENV_ERROR: urllib3 version {urllib3.__version__} is incompatible; expected prefix {EXPECTED_URLLIB3_PREFIX}",
        file=sys.stderr,
    )
    sys.exit(4)

log_path = pathlib.Path("/home/user/ops-pip-debug/logs/service.log")
summary_path = pathlib.Path("/home/user/ops-pip-debug/logs/summary.json")

lines = [line.rstrip("\n") for line in log_path.read_text().splitlines()]
errors = [line for line in lines if " ERROR " in line]
warnings = [line for line in lines if " WARNING " in line]

summary = {
    "status": "degraded",
    "total_lines": len(lines),
    "error_count": len(errors),
    "warning_count": len(warnings),
    "requests_version": requests.__version__,
    "urllib3_version": urllib3.__version__,
}

summary_path.write_text(json.dumps(summary, indent=2, sort_keys=True) + "\n")
print(f"WROTE {summary_path}")
EOF

    cat > /home/user/ops-pip-debug/vendor_trap/urllib3/__init__.py <<'EOF'
__version__ = "2.2.0"
EOF

    chmod +x /home/user/ops-pip-debug/analyze_logs.py

    python3 -m venv /home/user/ops-pip-debug/.venv
    /home/user/ops-pip-debug/.venv/bin/python -m pip install --no-cache-dir --upgrade pip
    /home/user/ops-pip-debug/.venv/bin/python -m pip install --no-cache-dir \
        requests==2.31.0 \
        urllib3==2.2.0 \
        python-dateutil==2.8.2

    rm -f /home/user/ops-pip-debug/logs/summary.json
    rm -f /home/user/ops-pip-debug/env_repair_report.txt

    chown -R user:user /home/user/ops-pip-debug
    chmod -R u+rwX,go+rX /home/user/ops-pip-debug
    chmod -R u+w /home/user/ops-pip-debug/.venv

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

# test_final_state.py
import json
import os
import pathlib
import subprocess

PROJECT_DIR = pathlib.Path("/home/user/ops-pip-debug")
REQUIREMENTS = pathlib.Path("/home/user/ops-pip-debug/requirements.txt")
SERVICE_LOG = pathlib.Path("/home/user/ops-pip-debug/logs/service.log")
ANALYZER = pathlib.Path("/home/user/ops-pip-debug/analyze_logs.py")
SUMMARY_JSON = pathlib.Path("/home/user/ops-pip-debug/logs/summary.json")
REPORT = pathlib.Path("/home/user/ops-pip-debug/env_repair_report.txt")

EXPECTED_REQUIREMENTS = """requests==2.31.0
urllib3==1.26.18
python-dateutil==2.8.2
"""

EXPECTED_SERVICE_LOG = """2024-05-12T08:15:01Z INFO api-gateway boot sequence started
2024-05-12T08:15:03Z INFO api-gateway listening on 0.0.0.0:8080
2024-05-12T08:16:10Z WARNING auth-cache refresh took 1840ms
2024-05-12T08:17:44Z ERROR upstream inventory timeout after 3000ms
2024-05-12T08:18:01Z INFO retry scheduled for inventory request
2024-05-12T08:19:22Z WARNING payment queue depth above threshold
2024-05-12T08:21:09Z ERROR checkout request failed with HTTP 502
2024-05-12T08:22:11Z INFO api-gateway health check passed
"""

EXPECTED_ANALYZER = '''#!/usr/bin/env python3
import json
import pathlib
import sys

try:
    import requests
    import urllib3
except Exception as exc:
    print(f"IMPORT_ERROR: {exc}", file=sys.stderr)
    sys.exit(2)

EXPECTED_REQUESTS = "2.31.0"
EXPECTED_URLLIB3_PREFIX = "1.26."

if requests.__version__ != EXPECTED_REQUESTS:
    print(
        f"ENV_ERROR: requests version {requests.__version__} does not match required {EXPECTED_REQUESTS}",
        file=sys.stderr,
    )
    sys.exit(3)

if not urllib3.__version__.startswith(EXPECTED_URLLIB3_PREFIX):
    print(
        f"ENV_ERROR: urllib3 version {urllib3.__version__} is incompatible; expected prefix {EXPECTED_URLLIB3_PREFIX}",
        file=sys.stderr,
    )
    sys.exit(4)

log_path = pathlib.Path("/home/user/ops-pip-debug/logs/service.log")
summary_path = pathlib.Path("/home/user/ops-pip-debug/logs/summary.json")

lines = [line.rstrip("\\n") for line in log_path.read_text().splitlines()]
errors = [line for line in lines if " ERROR " in line]
warnings = [line for line in lines if " WARNING " in line]

summary = {
    "status": "degraded",
    "total_lines": len(lines),
    "error_count": len(errors),
    "warning_count": len(warnings),
    "requests_version": requests.__version__,
    "urllib3_version": urllib3.__version__,
}

summary_path.write_text(json.dumps(summary, indent=2, sort_keys=True) + "\\n")
print(f"WROTE {summary_path}")
'''

EXPECTED_SUMMARY = {
    "error_count": 2,
    "requests_version": "2.31.0",
    "status": "degraded",
    "total_lines": 8,
    "urllib3_version": "1.26.18",
    "warning_count": 2,
}

def read_text_or_fail(path: pathlib.Path) -> str:
    try:
        return path.read_text()
    except FileNotFoundError:
        raise AssertionError(f"Required file is missing: {path}")

def parse_report():
    assert REPORT.exists(), f"Final repair report is missing: {REPORT}"
    assert REPORT.is_file(), f"Repair report path exists but is not a regular file: {REPORT}"

    raw = read_text_or_fail(REPORT)
    assert raw, f"Repair report is empty: {REPORT}"
    assert raw.endswith("\n"), f"Repair report must end with a single trailing newline: {REPORT}"
    assert not raw.endswith("\n\n"), f"Repair report must not contain extra blank lines at the end: {REPORT}"

    lines = raw.splitlines()
    assert len(lines) == 5, (
        f"{REPORT} must contain exactly five lines, but found {len(lines)} lines: {lines!r}"
    )

    for index, line in enumerate(lines, start=1):
        assert line == line.strip(), (
            f"Line {index} of {REPORT} has leading or trailing whitespace: {line!r}"
        )
        assert line, f"Line {index} of {REPORT} is blank; no blank lines are allowed"

    expected_prefixes = [
        "ENV_REPAIR_STATUS=",
        "PYTHON_EXECUTABLE=",
        "REQUESTS_VERSION=",
        "URLLIB3_VERSION=",
        "SUMMARY_JSON=",
    ]
    for index, (line, prefix) in enumerate(zip(lines, expected_prefixes), start=1):
        assert line.startswith(prefix), (
            f"Line {index} of {REPORT} must start with {prefix!r}, got {line!r}"
        )

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

    return lines, values

def test_original_project_inputs_and_analyzer_were_not_rewritten_to_fake_success():
    assert PROJECT_DIR.exists(), f"Project directory is missing: {PROJECT_DIR}"
    assert PROJECT_DIR.is_dir(), f"Project path is not a directory: {PROJECT_DIR}"

    assert REQUIREMENTS.exists(), f"Requirements file is missing: {REQUIREMENTS}"
    assert REQUIREMENTS.is_file(), f"Requirements path is not a file: {REQUIREMENTS}"
    assert read_text_or_fail(REQUIREMENTS) == EXPECTED_REQUIREMENTS, (
        f"{REQUIREMENTS} was changed. The task is to repair the Python environment, "
        "not rewrite the requirements file."
    )

    assert SERVICE_LOG.exists(), f"Service log is missing: {SERVICE_LOG}"
    assert SERVICE_LOG.is_file(), f"Service log path is not a file: {SERVICE_LOG}"
    assert read_text_or_fail(SERVICE_LOG) == EXPECTED_SERVICE_LOG, (
        f"{SERVICE_LOG} was changed. The summary must be produced from the original log."
    )

    assert ANALYZER.exists(), f"Analyzer script is missing: {ANALYZER}"
    assert ANALYZER.is_file(), f"Analyzer path is not a file: {ANALYZER}"
    assert read_text_or_fail(ANALYZER) == EXPECTED_ANALYZER, (
        f"{ANALYZER} was changed. The required fix is the importable Python environment, "
        "not bypassing the version checks or hand-writing a different analyzer."
    )

def test_env_repair_report_has_exact_required_five_line_format_and_values():
    lines, values = parse_report()

    assert lines[0] == "ENV_REPAIR_STATUS=success", (
        f"Line 1 of {REPORT} must be exactly ENV_REPAIR_STATUS=success"
    )
    assert lines[2] == "REQUESTS_VERSION=2.31.0", (
        f"Line 3 of {REPORT} must be exactly REQUESTS_VERSION=2.31.0"
    )
    assert lines[3] == "URLLIB3_VERSION=1.26.18", (
        f"Line 4 of {REPORT} must be exactly URLLIB3_VERSION=1.26.18"
    )
    assert lines[4] == f"SUMMARY_JSON={SUMMARY_JSON}", (
        f"Line 5 of {REPORT} must be exactly SUMMARY_JSON={SUMMARY_JSON}"
    )

    python_executable = pathlib.Path(values["PYTHON_EXECUTABLE"])
    assert python_executable.is_absolute(), (
        f"PYTHON_EXECUTABLE in {REPORT} must be an absolute path, got: {python_executable}"
    )
    assert python_executable.exists(), (
        f"PYTHON_EXECUTABLE in {REPORT} does not exist: {python_executable}"
    )
    assert python_executable.is_file(), (
        f"PYTHON_EXECUTABLE in {REPORT} is not a regular file: {python_executable}"
    )
    assert os.access(python_executable, os.X_OK), (
        f"PYTHON_EXECUTABLE in {REPORT} is not executable: {python_executable}"
    )

def test_reported_python_imports_exact_required_package_versions():
    _, values = parse_report()
    python_executable = values["PYTHON_EXECUTABLE"]

    probe = (
        "import json, sys\n"
        "import requests, urllib3\n"
        "print(json.dumps({"
        "'executable': sys.executable, "
        "'requests': requests.__version__, "
        "'urllib3': urllib3.__version__"
        "}, sort_keys=True))\n"
    )
    result = subprocess.run(
        [python_executable, "-c", probe],
        cwd=str(PROJECT_DIR),
        text=True,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        timeout=30,
    )

    assert result.returncode == 0, (
        f"Reported PYTHON_EXECUTABLE could not import requests and urllib3 cleanly.\n"
        f"python: {python_executable}\n"
        f"return code: {result.returncode}\n"
        f"stdout:\n{result.stdout}\n"
        f"stderr:\n{result.stderr}"
    )

    try:
        observed = json.loads(result.stdout)
    except json.JSONDecodeError as exc:
        raise AssertionError(
            f"Could not parse import-version probe output from {python_executable} as JSON: {exc}\n"
            f"stdout:\n{result.stdout}\nstderr:\n{result.stderr}"
        )

    assert observed["requests"] == "2.31.0", (
        f"{python_executable} imports requests {observed['requests']!r}, "
        "but the repaired environment must import requests '2.31.0'."
    )
    assert observed["urllib3"] == "1.26.18", (
        f"{python_executable} imports urllib3 {observed['urllib3']!r}, "
        "but the repaired environment must import urllib3 '1.26.18'."
    )

    assert values["REQUESTS_VERSION"] == observed["requests"], (
        f"REQUESTS_VERSION in {REPORT} does not match what the reported Python imports: "
        f"report={values['REQUESTS_VERSION']!r}, actual={observed['requests']!r}"
    )
    assert values["URLLIB3_VERSION"] == observed["urllib3"], (
        f"URLLIB3_VERSION in {REPORT} does not match what the reported Python imports: "
        f"report={values['URLLIB3_VERSION']!r}, actual={observed['urllib3']!r}"
    )

def test_analyzer_runs_successfully_with_reported_python_from_project_directory():
    _, values = parse_report()
    python_executable = values["PYTHON_EXECUTABLE"]

    result = subprocess.run(
        [python_executable, str(ANALYZER)],
        cwd=str(PROJECT_DIR),
        text=True,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        timeout=30,
    )

    assert result.returncode == 0, (
        f"Analyzer does not run successfully with the reported PYTHON_EXECUTABLE.\n"
        f"python: {python_executable}\n"
        f"cwd: {PROJECT_DIR}\n"
        f"return code: {result.returncode}\n"
        f"stdout:\n{result.stdout}\n"
        f"stderr:\n{result.stderr}"
    )
    assert f"WROTE {SUMMARY_JSON}" in result.stdout, (
        f"Analyzer should report that it wrote {SUMMARY_JSON}.\n"
        f"stdout:\n{result.stdout}\nstderr:\n{result.stderr}"
    )

def test_summary_json_exists_is_parseable_and_has_exact_expected_semantic_content():
    assert SUMMARY_JSON.exists(), f"Analyzer summary JSON is missing: {SUMMARY_JSON}"
    assert SUMMARY_JSON.is_file(), f"Summary JSON path exists but is not a regular file: {SUMMARY_JSON}"

    raw = read_text_or_fail(SUMMARY_JSON)
    assert raw.strip(), f"Summary JSON is empty: {SUMMARY_JSON}"

    try:
        summary = json.loads(raw)
    except json.JSONDecodeError as exc:
        raise AssertionError(
            f"{SUMMARY_JSON} is not valid JSON: {exc}\nContents:\n{raw}"
        )

    assert summary == EXPECTED_SUMMARY, (
        f"{SUMMARY_JSON} does not contain the expected analyzer result.\n"
        f"Expected: {EXPECTED_SUMMARY!r}\n"
        f"Actual:   {summary!r}"
    )

def test_report_summary_path_points_to_generated_summary_json():
    _, values = parse_report()

    assert values["SUMMARY_JSON"] == str(SUMMARY_JSON), (
        f"SUMMARY_JSON in {REPORT} must point to the required generated file "
        f"{SUMMARY_JSON}, got {values['SUMMARY_JSON']!r}"
    )
    assert pathlib.Path(values["SUMMARY_JSON"]).exists(), (
        f"SUMMARY_JSON path named in {REPORT} does not exist: {values['SUMMARY_JSON']}"
    )


I’m maintaining a mobile CI pipeline and need a small release-summary artifact generated from an INI file.

    The input file is already present at:

    /home/user/mobile-pipeline.ini

    It contains multiple build profiles. The only profile that matters is the one named by the top-level key active_profile in the [pipeline] section. Do not summarize the first profile in the file unless it is actually the active one.

    Please create this output file:

    /home/user/build/release-summary.tsv

    Create /home/user/build if it does not already exist.

    The output file must contain exactly two lines:

    1. A header line with these tab-separated column names, in this exact order:

    profile	applicationId	versionName	versionCode	track

    2. One tab-separated data line for the active profile only. The fields must be:
    - the active profile name
    - applicationId from that profile’s section
    - versionName from that profile’s section
    - versionCode from that profile’s section
    - track from that profile’s section

    The relevant profile section is named using this format:

    [profile.<active_profile>]

    For example, if active_profile is qa, then the values must come from [profile.qa].

    Important parsing details:
    - Ignore blank lines.
    - Ignore full-line comments beginning with # or ;.
    - Preserve dots and hyphens inside values.
    - Do not include surrounding whitespace around keys or values.
    - Only use values from the active profile section, not from any other profile section.

    Before finishing, verify the file exists and that it has exactly two lines. The automated check will inspect /home/user/build/release-summary.tsv directly, so the exact tab-separated format matters.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_d2cba211"
description = "I\u2019m maintaining a mobile CI pipeline and need a small release-summary artifact generated from an INI file."
authors = [{ name = "Endless Terminals / Jarrod Barnes" }]
keywords = ["agentic-rl", "endless-terminals", "recognition_to_action_coupling", "repeat_loop_after_dead_end", "terminal-bench-2"]

[metadata]
source = "endless-terminals"
corpus = "processrl-core-v1"
generation_mode = "behavior_conditioned_llm_funnel"
behavior_card_id = "repeat_loop_after_dead_end"
capability = "recognition_to_action_coupling"
source_traces = ["pgn-chess-repair-puzzles", "book-portfolio-analysis", "bash-log-processor-fix"]

[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

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

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

    mkdir -p /home/user

    cat > /home/user/mobile-pipeline.ini <<'EOF'
# Mobile release pipeline configuration
# Generated from the shared CI template.

[pipeline]
owner = mobile-build
active_profile = beta
default_track = internal

[profile.alpha]
applicationId = com.example.wallet.alpha
versionName = 3.8.0-alpha.4
versionCode = 38004
track = internal

; The beta profile is the one currently promoted by CI.
[profile.beta]
applicationId = com.example.wallet
versionName = 3.8.0
versionCode = 38017
track = production

[profile.qa]
applicationId = com.example.wallet.qa
versionName = 3.8.0-qa.2
versionCode = 38012
track = beta

[signing]
keystore_alias = ci-release
v1_enabled = true
v2_enabled = true
EOF

    chmod 777 /home/user
    chmod 644 /home/user/mobile-pipeline.ini

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

# test_final_state.py
from pathlib import Path
import os

HOME = Path("/home/user")
INPUT_FILE = Path("/home/user/mobile-pipeline.ini")
BUILD_DIR = Path("/home/user/build")
SUMMARY_FILE = Path("/home/user/build/release-summary.tsv")

EXPECTED_INI = """# Mobile release pipeline configuration
# Generated from the shared CI template.

[pipeline]
owner = mobile-build
active_profile = beta
default_track = internal

[profile.alpha]
applicationId = com.example.wallet.alpha
versionName = 3.8.0-alpha.4
versionCode = 38004
track = internal

; The beta profile is the one currently promoted by CI.
[profile.beta]
applicationId = com.example.wallet
versionName = 3.8.0
versionCode = 38017
track = production

[profile.qa]
applicationId = com.example.wallet.qa
versionName = 3.8.0-qa.2
versionCode = 38012
track = beta

[signing]
keystore_alias = ci-release
v1_enabled = true
v2_enabled = true
"""

EXPECTED_HEADER = "profile\tapplicationId\tversionName\tversionCode\ttrack"
EXPECTED_DATA = "beta\tcom.example.wallet\t3.8.0\t38017\tproduction"
EXPECTED_SUMMARY = EXPECTED_HEADER + "\n" + EXPECTED_DATA + "\n"

def test_input_ini_still_exists_and_matches_truth():
    assert INPUT_FILE.exists(), f"Required input INI file is missing: {INPUT_FILE}"
    assert INPUT_FILE.is_file(), f"Required input path exists but is not a regular file: {INPUT_FILE}"
    assert os.access(INPUT_FILE, os.R_OK), f"Required input INI file is not readable: {INPUT_FILE}"

    actual = INPUT_FILE.read_text(encoding="utf-8")
    assert actual == EXPECTED_INI, (
        f"Input INI file was changed or does not match the expected truth data: {INPUT_FILE}. "
        "The release summary must be generated from active_profile=beta and [profile.beta]."
    )

def test_build_directory_exists_and_is_directory():
    assert BUILD_DIR.exists(), (
        f"Build directory was not created: {BUILD_DIR}. "
        "Create /home/user/build before writing the release summary."
    )
    assert BUILD_DIR.is_dir(), (
        f"Build output path exists but is not a directory: {BUILD_DIR}"
    )

def test_release_summary_file_exists_and_is_regular_file():
    assert SUMMARY_FILE.exists(), (
        f"Release summary file is missing: {SUMMARY_FILE}"
    )
    assert SUMMARY_FILE.is_file(), (
        f"Release summary path exists but is not a regular file: {SUMMARY_FILE}"
    )

def test_release_summary_exact_bytes_and_final_newline():
    actual_bytes = SUMMARY_FILE.read_bytes()
    expected_bytes = EXPECTED_SUMMARY.encode("utf-8")

    assert actual_bytes == expected_bytes, (
        f"Release summary contents are not exactly correct: {SUMMARY_FILE}\n"
        "Expected exact UTF-8 bytes including tabs and final newline:\n"
        f"{expected_bytes!r}\n"
        "Actual bytes:\n"
        f"{actual_bytes!r}"
    )

def test_release_summary_has_exactly_two_lines():
    text = SUMMARY_FILE.read_text(encoding="utf-8")
    lines = text.splitlines()

    assert len(lines) == 2, (
        f"Release summary must contain exactly two lines, but found {len(lines)} line(s): "
        f"{SUMMARY_FILE}. Actual split lines: {lines!r}"
    )

def test_release_summary_header_line_is_exact():
    lines = SUMMARY_FILE.read_text(encoding="utf-8").splitlines()

    assert lines, f"Release summary is empty: {SUMMARY_FILE}"
    assert lines[0] == EXPECTED_HEADER, (
        "Header line is incorrect. It must be exactly tab-separated with columns in this order:\n"
        f"{EXPECTED_HEADER!r}\n"
        f"Actual header:\n{lines[0]!r}"
    )

def test_release_summary_data_line_is_exact_beta_profile_only():
    lines = SUMMARY_FILE.read_text(encoding="utf-8").splitlines()

    assert len(lines) >= 2, (
        f"Release summary is missing the data line for active profile beta: {SUMMARY_FILE}"
    )
    assert lines[1] == EXPECTED_DATA, (
        "Data line is incorrect. It must use values from [profile.beta], the active profile, "
        "not [profile.alpha] or any other section.\n"
        f"Expected:\n{EXPECTED_DATA!r}\n"
        f"Actual:\n{lines[1]!r}"
    )

def test_release_summary_uses_real_tabs_no_extra_columns_or_spaces():
    text = SUMMARY_FILE.read_text(encoding="utf-8")
    lines = text.splitlines()

    assert "\\t" not in text, (
        "Release summary contains literal backslash-t characters instead of real tab separators."
    )

    assert len(lines) == 2, (
        f"Cannot validate columns because summary should have exactly two lines, found {len(lines)}."
    )

    for line_number, line in enumerate(lines, start=1):
        assert not line.startswith(" "), (
            f"Line {line_number} has leading space, which is not allowed: {line!r}"
        )
        assert not line.endswith(" "), (
            f"Line {line_number} has trailing space, which is not allowed: {line!r}"
        )

        columns = line.split("\t")
        assert len(columns) == 5, (
            f"Line {line_number} must have exactly 5 tab-separated columns, "
            f"but found {len(columns)} columns: {columns!r}"
        )

        for column_number, value in enumerate(columns, start=1):
            assert value == value.strip(), (
                f"Line {line_number}, column {column_number} contains surrounding whitespace: {value!r}"
            )

def test_release_summary_did_not_use_alpha_or_qa_profile_values():
    text = SUMMARY_FILE.read_text(encoding="utf-8")

    forbidden_values = [
        "alpha",
        "com.example.wallet.alpha",
        "3.8.0-alpha.4",
        "38004",
        "internal",
        "qa",
        "com.example.wallet.qa",
        "3.8.0-qa.2",
        "38012",
    ]

    present = [value for value in forbidden_values if value in text]
    assert not present, (
        "Release summary appears to include values from a non-active profile. "
        "Only [profile.beta] values are allowed. Unexpected value(s): "
        + ", ".join(repr(value) for value in present)
    )