You are helping with a small DevSecOps policy-as-code data pipeline cleanup in `/home/user/policy-pipeline`.

The repository currently has an old policy exceptions source file and a pipeline script that still reads from the old location. Your job is to migrate the source of truth, update the pipeline to use the new canonical policy endpoint file, retire the stale old path, and verify the final state from the new location.

Final required state:

1. Create the new canonical directory and JSON policy file:
   - Directory: `/home/user/policy-pipeline/config/policy`
   - File: `/home/user/policy-pipeline/config/policy/exceptions.json`
   - The file must be valid JSON.
   - It must preserve all existing exception records from the current legacy exception data, without changing their field names or values.
   - It must contain a top-level object with exactly these keys:
     - `schema_version`
     - `exceptions`
   - `schema_version` must be the string value `2024-ops-policy-v2`.
   - `exceptions` must be an array of exception objects migrated from the legacy file.

2. Update the pipeline script:
   - File: `/home/user/policy-pipeline/bin/render_policy_report.py`
   - It must read exceptions only from `/home/user/policy-pipeline/config/policy/exceptions.json`.
   - It must not read from `/home/user/policy-pipeline/data/legacy_exceptions.json`.
   - It must produce the same policy report semantics as before, using the migrated exceptions.

3. Retire the old source of truth:
   - The file `/home/user/policy-pipeline/data/legacy_exceptions.json` must not remain as an active readable data source.
   - It is acceptable to remove it or replace it with a small human-readable retirement notice, but the pipeline must not depend on it.
   - If you leave a notice file at that path, it must clearly say the canonical source is `/home/user/policy-pipeline/config/policy/exceptions.json`.

4. Run the report pipeline and write the verification log:
   - Run the pipeline from the repository root `/home/user/policy-pipeline`.
   - The pipeline must write its final report to `/home/user/policy-pipeline/output/policy_report.json`.
   - Create `/home/user/policy-pipeline/output/migration_verification.log`.
   - The log file must contain exactly five non-empty lines in this order and format:

```text
old_source_retired=<true_or_false>
new_source_exists=<true_or_false>
pipeline_source=<absolute_path_used_by_pipeline>
report_path=/home/user/policy-pipeline/output/policy_report.json
verified_from_new_source=<true_or_false>
```

For the final answer to the user, briefly state what you changed and confirm that `/home/user/policy-pipeline/output/migration_verification.log` was written. Do not include command transcripts.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_005b2336"
description = "You are helping with a small DevSecOps policy-as-code data pipeline cleanup in `/home/user/policy-pipeline`."
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

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

    mkdir -p /home/user/policy-pipeline/bin
    mkdir -p /home/user/policy-pipeline/data
    mkdir -p /home/user/policy-pipeline/output

    cat > /home/user/policy-pipeline/data/legacy_exceptions.json <<'EOF'
[
  {
    "control_id": "CIS-1.1.1",
    "service": "artifact-registry",
    "environment": "dev",
    "expires": "2026-01-15",
    "reason": "Temporary exception while container signing rollout completes"
  },
  {
    "control_id": "CIS-2.3.4",
    "service": "build-runner",
    "environment": "ci",
    "expires": "2025-12-31",
    "reason": "Pinned legacy runner requires scoped network egress during migration"
  },
  {
    "control_id": "ORG-SEC-7",
    "service": "secrets-sync",
    "environment": "staging",
    "expires": "2025-10-01",
    "reason": "Compensating monitoring enabled until vault namespace split is complete"
  }
]
EOF

    cat > /home/user/policy-pipeline/bin/render_policy_report.py <<'EOF'
#!/usr/bin/env python3
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
EXCEPTIONS_PATH = ROOT / "data" / "legacy_exceptions.json"
REPORT_PATH = ROOT / "output" / "policy_report.json"

def load_exceptions():
    with EXCEPTIONS_PATH.open("r", encoding="utf-8") as fh:
        return json.load(fh)

def main():
    exceptions = load_exceptions()
    report = {
        "pipeline": "policy-exception-render",
        "source": str(EXCEPTIONS_PATH),
        "exception_count": len(exceptions),
        "exceptions_by_environment": {},
        "controls": sorted(item["control_id"] for item in exceptions),
        "expired_count": 0
    }
    for item in exceptions:
        env = item["environment"]
        report["exceptions_by_environment"][env] = report["exceptions_by_environment"].get(env, 0) + 1

    REPORT_PATH.parent.mkdir(parents=True, exist_ok=True)
    with REPORT_PATH.open("w", encoding="utf-8") as fh:
        json.dump(report, fh, indent=2, sort_keys=True)
        fh.write("\n")

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

    chmod 755 /home/user/policy-pipeline/bin/render_policy_report.py
    chmod 664 /home/user/policy-pipeline/data/legacy_exceptions.json

    chown -R user:user /home/user/policy-pipeline
    chmod -R u+rwX,g+rwX /home/user/policy-pipeline

    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 ast
import json
import os
import shutil
import subprocess
import sys
from pathlib import Path

import pytest

ROOT = Path("/home/user/policy-pipeline")
CANONICAL_DIR = Path("/home/user/policy-pipeline/config/policy")
CANONICAL_PATH = Path("/home/user/policy-pipeline/config/policy/exceptions.json")
LEGACY_PATH = Path("/home/user/policy-pipeline/data/legacy_exceptions.json")
SCRIPT_PATH = Path("/home/user/policy-pipeline/bin/render_policy_report.py")
REPORT_PATH = Path("/home/user/policy-pipeline/output/policy_report.json")
LOG_PATH = Path("/home/user/policy-pipeline/output/migration_verification.log")

EXPECTED_SCHEMA_VERSION = "2024-ops-policy-v2"
EXPECTED_EXCEPTIONS = [
    {
        "control_id": "CIS-1.1.1",
        "service": "artifact-registry",
        "environment": "dev",
        "expires": "2026-01-15",
        "reason": "Temporary exception while container signing rollout completes",
    },
    {
        "control_id": "CIS-2.3.4",
        "service": "build-runner",
        "environment": "ci",
        "expires": "2025-12-31",
        "reason": "Pinned legacy runner requires scoped network egress during migration",
    },
    {
        "control_id": "ORG-SEC-7",
        "service": "secrets-sync",
        "environment": "staging",
        "expires": "2025-10-01",
        "reason": "Compensating monitoring enabled until vault namespace split is complete",
    },
]
EXPECTED_EXCEPTION_KEYS = {
    "control_id",
    "service",
    "environment",
    "expires",
    "reason",
}
EXPECTED_REPORT = {
    "pipeline": "policy-exception-render",
    "source": str(CANONICAL_PATH),
    "exception_count": 3,
    "exceptions_by_environment": {"ci": 1, "dev": 1, "staging": 1},
    "controls": ["CIS-1.1.1", "CIS-2.3.4", "ORG-SEC-7"],
    "expired_count": 0,
}
EXPECTED_LOG_TEXT = "\n".join(
    [
        "old_source_retired=true",
        "new_source_exists=true",
        "pipeline_source=/home/user/policy-pipeline/config/policy/exceptions.json",
        "report_path=/home/user/policy-pipeline/output/policy_report.json",
        "verified_from_new_source=true",
    ]
)

def _load_json_file(path: Path):
    assert path.exists(), f"Required JSON file is missing: {path}"
    assert path.is_file(), f"Required JSON path exists but is not a regular file: {path}"
    try:
        return json.loads(path.read_text(encoding="utf-8"))
    except json.JSONDecodeError as exc:
        pytest.fail(f"File is not valid JSON: {path}: {exc}")

def _canonicalize_exception(item):
    assert isinstance(item, dict), f"Exception record is not a JSON object: {item!r}"
    assert set(item.keys()) == EXPECTED_EXCEPTION_KEYS, (
        "Exception record keys were changed. Expected exactly "
        f"{sorted(EXPECTED_EXCEPTION_KEYS)}, got {sorted(item.keys())}: {item!r}"
    )
    return tuple((key, item[key]) for key in sorted(EXPECTED_EXCEPTION_KEYS))

def _assert_exceptions_equal_expected(actual):
    assert isinstance(actual, list), (
        f"'exceptions' must be a JSON array/list, got {type(actual).__name__}"
    )
    assert len(actual) == len(EXPECTED_EXCEPTIONS), (
        f"Expected {len(EXPECTED_EXCEPTIONS)} migrated exceptions, got {len(actual)}"
    )
    actual_set = {_canonicalize_exception(item) for item in actual}
    expected_set = {_canonicalize_exception(item) for item in EXPECTED_EXCEPTIONS}
    assert actual_set == expected_set, (
        "Migrated exceptions do not exactly match the original legacy records. "
        "All field names and values must be preserved with no missing or extra records."
    )

def _run_pipeline():
    assert SCRIPT_PATH.exists(), f"Pipeline script is missing: {SCRIPT_PATH}"
    assert SCRIPT_PATH.is_file(), f"Pipeline script path is not a regular file: {SCRIPT_PATH}"
    result = subprocess.run(
        [sys.executable, str(SCRIPT_PATH)],
        cwd=str(ROOT),
        text=True,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        timeout=15,
    )
    assert result.returncode == 0, (
        "Pipeline failed when run from repository root. "
        f"Command: {sys.executable} {SCRIPT_PATH}\n"
        f"stdout:\n{result.stdout}\n"
        f"stderr:\n{result.stderr}"
    )
    return result

def _looks_like_active_exception_json(value):
    records = None
    if isinstance(value, list):
        records = value
    elif isinstance(value, dict) and isinstance(value.get("exceptions"), list):
        records = value["exceptions"]

    if records is None:
        return False

    return any(
        isinstance(item, dict)
        and {"control_id", "service", "environment", "expires", "reason"}.issubset(item.keys())
        for item in records
    )

def test_canonical_policy_directory_and_json_file_exist_with_required_wrapper_schema():
    assert CANONICAL_DIR.exists(), f"Canonical policy directory is missing: {CANONICAL_DIR}"
    assert CANONICAL_DIR.is_dir(), (
        f"Canonical policy path exists but is not a directory: {CANONICAL_DIR}"
    )
    assert CANONICAL_PATH.exists(), f"Canonical exceptions file is missing: {CANONICAL_PATH}"
    assert CANONICAL_PATH.is_file(), (
        f"Canonical exceptions path exists but is not a regular file: {CANONICAL_PATH}"
    )

    data = _load_json_file(CANONICAL_PATH)
    assert isinstance(data, dict), (
        f"Canonical exceptions JSON must be a top-level object: {CANONICAL_PATH}"
    )
    assert set(data.keys()) == {"schema_version", "exceptions"}, (
        "Canonical exceptions JSON must have exactly the top-level keys "
        "'schema_version' and 'exceptions'; got "
        f"{sorted(data.keys())}"
    )
    assert data["schema_version"] == EXPECTED_SCHEMA_VERSION, (
        f"Canonical schema_version must be {EXPECTED_SCHEMA_VERSION!r}, "
        f"got {data['schema_version']!r}"
    )
    _assert_exceptions_equal_expected(data["exceptions"])

def test_render_policy_report_script_references_canonical_source_and_not_legacy_source():
    assert SCRIPT_PATH.exists(), f"Pipeline script is missing: {SCRIPT_PATH}"
    source = SCRIPT_PATH.read_text(encoding="utf-8")

    assert "config" in source and "policy" in source and "exceptions.json" in source, (
        "Pipeline script should reference the canonical policy file "
        f"{CANONICAL_PATH}, but the expected path components were not found in {SCRIPT_PATH}"
    )
    assert "legacy_exceptions.json" not in source, (
        f"Pipeline script must not reference the retired legacy filename {LEGACY_PATH}"
    )
    assert "/home/user/policy-pipeline/data/legacy_exceptions.json" not in source, (
        f"Pipeline script must not reference the retired legacy path {LEGACY_PATH}"
    )

    try:
        tree = ast.parse(source, filename=str(SCRIPT_PATH))
    except SyntaxError as exc:
        pytest.fail(f"Pipeline script is not valid Python: {SCRIPT_PATH}: {exc}")

    string_literals = [
        node.value
        for node in ast.walk(tree)
        if isinstance(node, ast.Constant) and isinstance(node.value, str)
    ]
    forbidden_literals = [
        literal
        for literal in string_literals
        if "legacy_exceptions.json" in literal
        or "/home/user/policy-pipeline/data/legacy_exceptions.json" in literal
    ]
    assert not forbidden_literals, (
        "Pipeline script still contains string literal(s) referencing the legacy source: "
        f"{forbidden_literals!r}"
    )

def test_pipeline_runs_without_active_legacy_source_and_generates_expected_report(tmp_path):
    backup_path = tmp_path / "legacy_exceptions.json.backup"
    legacy_existed = LEGACY_PATH.exists()

    if legacy_existed:
        assert LEGACY_PATH.is_file(), (
            f"Legacy path exists but is not a regular file, cannot validate retirement: {LEGACY_PATH}"
        )
        shutil.copy2(str(LEGACY_PATH), str(backup_path))
        LEGACY_PATH.unlink()

    try:
        _run_pipeline()
        report = _load_json_file(REPORT_PATH)
    finally:
        if legacy_existed and not LEGACY_PATH.exists():
            shutil.copy2(str(backup_path), str(LEGACY_PATH))

    assert report == EXPECTED_REPORT, (
        "Generated policy report does not match expected semantics from the new canonical "
        f"source {CANONICAL_PATH}. Actual report: {report!r}"
    )

def test_policy_report_exists_and_proves_it_used_the_new_canonical_source():
    assert REPORT_PATH.exists(), f"Policy report was not written: {REPORT_PATH}"
    assert REPORT_PATH.is_file(), f"Policy report path is not a regular file: {REPORT_PATH}"

    report = _load_json_file(REPORT_PATH)
    for key, expected_value in EXPECTED_REPORT.items():
        assert report.get(key) == expected_value, (
            f"Policy report field {key!r} is wrong. Expected {expected_value!r}, "
            f"got {report.get(key)!r}. Report must be generated from {CANONICAL_PATH}."
        )

    assert report.get("source") != str(LEGACY_PATH), (
        f"Policy report still says it used the retired legacy source: {LEGACY_PATH}"
    )

def test_legacy_source_is_retired_or_replaced_by_clear_non_json_notice():
    if not LEGACY_PATH.exists():
        return

    assert LEGACY_PATH.is_file(), (
        f"Retired legacy path exists but is not a regular notice file: {LEGACY_PATH}"
    )

    text = LEGACY_PATH.read_text(encoding="utf-8")
    assert str(CANONICAL_PATH) in text, (
        "Legacy path still exists, so it must clearly say the canonical source is "
        f"{CANONICAL_PATH}. Notice text did not include that exact absolute path."
    )

    try:
        parsed = json.loads(text)
    except json.JSONDecodeError:
        return

    assert not _looks_like_active_exception_json(parsed), (
        f"Legacy path {LEGACY_PATH} still contains parseable active exception JSON. "
        "It must be removed or replaced with a human-readable retirement notice, "
        f"and the canonical source must be {CANONICAL_PATH}."
    )

def test_migration_verification_log_has_exact_required_five_lines():
    assert LOG_PATH.exists(), f"Migration verification log is missing: {LOG_PATH}"
    assert LOG_PATH.is_file(), (
        f"Migration verification log path exists but is not a regular file: {LOG_PATH}"
    )

    raw_text = LOG_PATH.read_text(encoding="utf-8")
    normalized = raw_text[:-1] if raw_text.endswith("\n") else raw_text

    assert normalized == EXPECTED_LOG_TEXT, (
        "Migration verification log contents are wrong. It must contain exactly the "
        "five required non-empty lines in order, with no extra fields or blank lines.\n"
        f"Expected:\n{EXPECTED_LOG_TEXT}\n"
        f"Actual:\n{raw_text}"
    )

    lines = normalized.split("\n")
    assert len(lines) == 5 and all(lines), (
        "Migration verification log must contain exactly five non-empty lines."
    )

#!/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 administer a small static site account directory under `/home/user/site-admin`.

Please clean up the staged user-account export and leave behind a verification artifact. The shell commands you use may produce little or no output, so do not treat silence as proof that the job is complete. Inspect the files and verify the final state before stopping.

Starting data will be under:

- `/home/user/site-admin/incoming/accounts/`
- `/home/user/site-admin/public/users/`

Perform these file-management changes:

1. Ensure the directory `/home/user/site-admin/public/users/archived/` exists.
2. Move the stale account file `/home/user/site-admin/incoming/accounts/samuel.lee.json` into `/home/user/site-admin/public/users/archived/samuel.lee.json`.
3. Move the active account file `/home/user/site-admin/incoming/accounts/maya.chen.json` into `/home/user/site-admin/public/users/maya.chen.json`.
4. Leave `/home/user/site-admin/incoming/accounts/` present, but it should contain no `.json` files after the moves.

After making the changes, create a verification log at exactly:

`/home/user/site-admin/account_migration_check.txt`

The automated check will read this file, so format it exactly as follows:

- It must contain exactly 5 lines.
- Line 1: `account migration check`
- Line 2: `archived_exists: yes` if `/home/user/site-admin/public/users/archived/samuel.lee.json` exists, otherwise `archived_exists: no`
- Line 3: `active_exists: yes` if `/home/user/site-admin/public/users/maya.chen.json` exists, otherwise `active_exists: no`
- Line 4: `incoming_json_count: N` where `N` is the number of `.json` files directly inside `/home/user/site-admin/incoming/accounts/`
- Line 5: `verified: yes`

Before you finish, inspect the resulting directories or otherwise run a targeted check so that the values in `/home/user/site-admin/account_migration_check.txt` reflect the actual final state.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_014b6c9e"
description = "You are helping administer a small static site account directory under `/home/user/site-admin`."
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 -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/*

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

    mkdir -p /home/user/site-admin/incoming/accounts
    mkdir -p /home/user/site-admin/public/users

    printf '%s\n' '{"username":"samuel.lee","full_name":"Samuel Lee","status":"stale","role":"editor"}' > /home/user/site-admin/incoming/accounts/samuel.lee.json
    printf '%s\n' '{"username":"maya.chen","full_name":"Maya Chen","status":"active","role":"publisher"}' > /home/user/site-admin/incoming/accounts/maya.chen.json
    printf '%s\n' 'Drop staged account JSON exports here before publication.' > /home/user/site-admin/incoming/accounts/README.txt

    rm -rf /home/user/site-admin/public/users/archived
    rm -f /home/user/site-admin/public/users/maya.chen.json
    rm -f /home/user/site-admin/account_migration_check.txt

    chown -R user:user /home/user/site-admin
    chmod -R u+rwX,go+rX /home/user/site-admin
    chmod -R u+w /home/user/site-admin

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

# test_final_state.py
from pathlib import Path

BASE = Path("/home/user/site-admin")
ACCOUNTS = Path("/home/user/site-admin/incoming/accounts")
USERS = Path("/home/user/site-admin/public/users")
ARCHIVED_DIR = Path("/home/user/site-admin/public/users/archived")

ARCHIVED_SAMUEL = Path("/home/user/site-admin/public/users/archived/samuel.lee.json")
ACTIVE_MAYA = Path("/home/user/site-admin/public/users/maya.chen.json")
ORIGINAL_SAMUEL = Path("/home/user/site-admin/incoming/accounts/samuel.lee.json")
ORIGINAL_MAYA = Path("/home/user/site-admin/incoming/accounts/maya.chen.json")
README = Path("/home/user/site-admin/incoming/accounts/README.txt")
VERIFICATION_LOG = Path("/home/user/site-admin/account_migration_check.txt")

EXPECTED_SAMUEL = (
    '{"username":"samuel.lee","full_name":"Samuel Lee","status":"stale","role":"editor"}\n'
)
EXPECTED_MAYA = (
    '{"username":"maya.chen","full_name":"Maya Chen","status":"active","role":"publisher"}\n'
)
EXPECTED_README = "Drop staged account JSON exports here before publication.\n"
EXPECTED_LOG = (
    "account migration check\n"
    "archived_exists: yes\n"
    "active_exists: yes\n"
    "incoming_json_count: 0\n"
    "verified: yes\n"
)

def read_text_exact(path: Path) -> str:
    try:
        return path.read_text(encoding="utf-8")
    except UnicodeDecodeError as exc:
        raise AssertionError(f"File is not valid UTF-8 text: {path}") from exc

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

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

def assert_exact_file_content(path: Path, expected: str, description: str) -> None:
    assert_file(path, description)
    actual = read_text_exact(path)
    assert actual == expected, (
        f"{description} has incorrect contents: {path}\n"
        f"Expected exactly: {expected!r}\n"
        f"Actual: {actual!r}"
    )

def test_archived_directory_exists_at_required_absolute_path():
    assert_directory(
        ARCHIVED_DIR,
        "Archived users directory /home/user/site-admin/public/users/archived/",
    )

def test_account_files_were_moved_to_required_destinations():
    assert_file(
        ARCHIVED_SAMUEL,
        "Stale Samuel Lee account file at archived destination",
    )
    assert_file(
        ACTIVE_MAYA,
        "Active Maya Chen account file at public users destination",
    )

    assert not ORIGINAL_SAMUEL.exists(), (
        "Stale Samuel Lee account file still exists in incoming accounts; "
        f"it should have been moved away from: {ORIGINAL_SAMUEL}"
    )
    assert not ORIGINAL_MAYA.exists(), (
        "Active Maya Chen account file still exists in incoming accounts; "
        f"it should have been moved away from: {ORIGINAL_MAYA}"
    )

def test_incoming_accounts_directory_remains_but_contains_no_direct_json_files():
    assert_directory(
        ACCOUNTS,
        "Incoming accounts directory /home/user/site-admin/incoming/accounts/",
    )

    json_files = sorted(path.name for path in ACCOUNTS.glob("*.json"))
    assert json_files == [], (
        "Incoming accounts directory should contain zero direct .json files after migration. "
        f"Found: {json_files}"
    )

def test_moved_account_file_contents_are_preserved_exactly():
    assert_exact_file_content(
        ARCHIVED_SAMUEL,
        EXPECTED_SAMUEL,
        "Archived Samuel Lee account file",
    )
    assert_exact_file_content(
        ACTIVE_MAYA,
        EXPECTED_MAYA,
        "Active Maya Chen account file",
    )

def test_readme_remains_in_incoming_accounts_with_original_contents():
    assert_exact_file_content(
        README,
        EXPECTED_README,
        "Incoming accounts README.txt",
    )

def test_verification_log_exists_with_exact_required_five_lines_and_trailing_newline():
    assert_exact_file_content(
        VERIFICATION_LOG,
        EXPECTED_LOG,
        "Verification artifact /home/user/site-admin/account_migration_check.txt",
    )

    log_lines = read_text_exact(VERIFICATION_LOG).splitlines()
    assert len(log_lines) == 5, (
        "Verification artifact must contain exactly 5 lines. "
        f"Found {len(log_lines)} lines: {log_lines!r}"
    )

def test_verification_log_values_match_actual_final_filesystem_state():
    assert_file(
        VERIFICATION_LOG,
        "Verification artifact /home/user/site-admin/account_migration_check.txt",
    )

    actual_archived_exists = "yes" if ARCHIVED_SAMUEL.exists() else "no"
    actual_active_exists = "yes" if ACTIVE_MAYA.exists() else "no"
    actual_incoming_json_count = len(list(ACCOUNTS.glob("*.json"))) if ACCOUNTS.exists() else None

    expected_lines_from_actual_state = [
        "account migration check",
        f"archived_exists: {actual_archived_exists}",
        f"active_exists: {actual_active_exists}",
        f"incoming_json_count: {actual_incoming_json_count}",
        "verified: yes",
    ]

    actual_lines = read_text_exact(VERIFICATION_LOG).splitlines()
    assert actual_lines == expected_lines_from_actual_state, (
        "Verification artifact does not reflect the actual final filesystem state.\n"
        f"Expected lines from actual state: {expected_lines_from_actual_state!r}\n"
        f"Actual log lines: {actual_lines!r}"
    )


You are helping with a small capacity-planning check in a Linux container. The input data is already available at `/home/user/capacity/input/resource_samples.csv`, and you have write access to `/home/user/capacity/output/`.

Create exactly one report file at:

`/home/user/capacity/output/capacity_plan.txt`

The report must be generated from the CSV data and must follow the exact format below so an automated checker can parse it.

Input CSV columns are:

`timestamp,service,cpu_pct,mem_mb,requests_per_min`

Your report must contain exactly 7 non-empty lines, in this exact order:

1. `CAPACITY PLAN`
2. `total_samples=<N>`
3. `highest_avg_cpu_service=<service>:<avg_cpu_pct>`
4. `highest_peak_mem_service=<service>:<peak_mem_mb>`
5. `bottleneck_service=<service>`
6. `recommendation=<text>`
7. `verified=true`

Formatting rules:
- `<N>` is the total number of data rows in the CSV, excluding the header.
- `<avg_cpu_pct>` must be rounded to exactly one decimal place.
- `<peak_mem_mb>` must be an integer with no decimal point.
- `highest_avg_cpu_service` is the service with the highest average `cpu_pct` across all its samples.
- `highest_peak_mem_service` is the service with the highest single observed `mem_mb` value.
- `bottleneck_service` must be the same service as `highest_avg_cpu_service`.
- `recommendation` must be:
  - `scale-cpu` if the bottleneck service average CPU is at least 75.0
  - otherwise `monitor`
- Do not include extra spaces around `=`, `:`, or line ends.
- Do not include any extra lines before or after the 7 required lines.
- After creating the report, verify that the file exists and that its contents match the required structure before you finish.

This should be a lightweight terminal task suitable for a capacity planner analyzing resource usage. A concise shell, awk, Python, or similar one-command solution is acceptable, but the final deliverable is only the report file at `/home/user/capacity/output/capacity_plan.txt`.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_03cb0bf1"
description = "You are helping with a small capacity-planning check in a Linux container. The input data is already available at `/home/user/capacity/input/resource_samples.csv`, and you have write access to `/home/user/capacity/output/`."
authors = [{ name = "Endless Terminals / Jarrod Barnes" }]
keywords = ["agentic-rl", "endless-terminals", "long_horizon_progress_ledger", "partial_progress_stall", "terminal-bench-2"]

[metadata]
source = "endless-terminals"
corpus = "processrl-core-v1"
generation_mode = "behavior_conditioned_llm_funnel"
behavior_card_id = "partial_progress_stall"
capability = "long_horizon_progress_ledger"
source_traces = ["security-incident-log-analysis", "security-breach-incident-respons", "bash-log-processor-fix", "server-log-analysis"]

[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 \
        ca-certificates

    pip3 install --no-cache-dir pytest

    mkdir -p /home/user/capacity/input
    mkdir -p /home/user/capacity/output

    cat > /home/user/capacity/input/resource_samples.csv <<'EOF'
timestamp,service,cpu_pct,mem_mb,requests_per_min
2026-03-14T10:00:00Z,api,61.0,740,1200
2026-03-14T10:01:00Z,api,64.0,760,1250
2026-03-14T10:02:00Z,api,67.0,755,1280
2026-03-14T10:03:00Z,api,65.0,770,1300
2026-03-14T10:00:00Z,worker,72.0,910,410
2026-03-14T10:01:00Z,worker,78.0,930,420
2026-03-14T10:02:00Z,worker,81.0,940,430
2026-03-14T10:03:00Z,worker,79.0,925,440
2026-03-14T10:00:00Z,cache,22.0,1380,2200
2026-03-14T10:01:00Z,cache,24.0,1410,2250
2026-03-14T10:02:00Z,cache,23.0,1505,2230
2026-03-14T10:03:00Z,cache,25.0,1495,2260
EOF

    chmod 777 /home/user
    chmod -R 777 /home/user/capacity
    chmod 666 /home/user/capacity/input/resource_samples.csv

    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
from pathlib import Path

REPORT_FILE = Path("/home/user/capacity/output/capacity_plan.txt")

EXPECTED_LINES = [
    "CAPACITY PLAN",
    "total_samples=12",
    "highest_avg_cpu_service=worker:77.5",
    "highest_peak_mem_service=cache:1505",
    "bottleneck_service=worker",
    "recommendation=scale-cpu",
    "verified=true",
]

EXPECTED_CONTENT = "\n".join(EXPECTED_LINES) + "\n"

def _read_report_text() -> str:
    assert REPORT_FILE.exists(), (
        f"Required final report file is missing: {REPORT_FILE}. "
        "Create exactly one report at this absolute path."
    )
    assert REPORT_FILE.is_file(), (
        f"Required final report path exists but is not a regular file: {REPORT_FILE}"
    )
    return REPORT_FILE.read_text(encoding="utf-8")

def test_capacity_plan_report_exists_at_exact_path():
    assert REPORT_FILE.exists(), (
        f"Required final report file is missing: {REPORT_FILE}. "
        "The deliverable must be created at this exact absolute path."
    )
    assert REPORT_FILE.is_file(), (
        f"Required final report path exists but is not a regular file: {REPORT_FILE}"
    )

def test_capacity_plan_report_has_exact_expected_contents():
    actual = _read_report_text()
    assert actual == EXPECTED_CONTENT, (
        f"Report contents do not exactly match the required final capacity plan at {REPORT_FILE}.\n"
        "Expected exactly these 7 lines, with this order, punctuation, spacing, and a single final newline:\n"
        f"{EXPECTED_CONTENT!r}\n"
        f"Actual contents were:\n{actual!r}"
    )

def test_capacity_plan_report_has_exactly_seven_non_empty_lines_and_no_extra_content():
    actual = _read_report_text()
    lines = actual.splitlines()

    assert len(lines) == 7, (
        f"Report must contain exactly 7 lines and no line 8 or trailing blank content; "
        f"found {len(lines)} line(s) in {REPORT_FILE}: {lines!r}"
    )

    empty_line_numbers = [index for index, line in enumerate(lines, start=1) if line == ""]
    assert not empty_line_numbers, (
        f"Report must contain exactly 7 non-empty lines; "
        f"blank line(s) found at line number(s): {empty_line_numbers}"
    )

    assert actual in ("\n".join(lines), "\n".join(lines) + "\n"), (
        f"Report contains unexpected trailing or embedded line-ending content beyond the 7 required lines: "
        f"{actual!r}"
    )

def test_capacity_plan_report_line_1_title_is_exact():
    actual_lines = _read_report_text().splitlines()
    assert len(actual_lines) >= 1, f"Report is empty; expected line 1 to be {EXPECTED_LINES[0]!r}"
    assert actual_lines[0] == EXPECTED_LINES[0], (
        f"Line 1 is wrong. Expected {EXPECTED_LINES[0]!r}; got {actual_lines[0]!r}."
    )

def test_capacity_plan_report_line_2_total_samples_excludes_header():
    actual_lines = _read_report_text().splitlines()
    assert len(actual_lines) >= 2, f"Report is missing line 2; expected {EXPECTED_LINES[1]!r}"
    assert actual_lines[1] == EXPECTED_LINES[1], (
        f"Line 2 is wrong. Expected {EXPECTED_LINES[1]!r}. "
        "The total_samples value must count only the 12 CSV data rows and must exclude the header; "
        f"got {actual_lines[1]!r}."
    )

def test_capacity_plan_report_line_3_highest_average_cpu_service_is_exact():
    actual_lines = _read_report_text().splitlines()
    assert len(actual_lines) >= 3, f"Report is missing line 3; expected {EXPECTED_LINES[2]!r}"
    assert actual_lines[2] == EXPECTED_LINES[2], (
        f"Line 3 is wrong. Expected {EXPECTED_LINES[2]!r}. "
        "The highest average CPU service must be worker with average CPU formatted to exactly one decimal place; "
        f"got {actual_lines[2]!r}."
    )

def test_capacity_plan_report_line_4_highest_peak_memory_service_is_independently_computed():
    actual_lines = _read_report_text().splitlines()
    assert len(actual_lines) >= 4, f"Report is missing line 4; expected {EXPECTED_LINES[3]!r}"
    assert actual_lines[3] == EXPECTED_LINES[3], (
        f"Line 4 is wrong. Expected {EXPECTED_LINES[3]!r}. "
        "The highest_peak_mem_service must be the service with the highest single observed mem_mb value, "
        "which is cache at 1505; it must not be inferred from the CPU bottleneck service. "
        f"Got {actual_lines[3]!r}."
    )

def test_capacity_plan_report_line_5_bottleneck_matches_highest_average_cpu_service():
    actual_lines = _read_report_text().splitlines()
    assert len(actual_lines) >= 5, f"Report is missing line 5; expected {EXPECTED_LINES[4]!r}"
    assert actual_lines[4] == EXPECTED_LINES[4], (
        f"Line 5 is wrong. Expected {EXPECTED_LINES[4]!r}. "
        "The bottleneck_service must be the same service as highest_avg_cpu_service, worker; "
        f"got {actual_lines[4]!r}."
    )

def test_capacity_plan_report_line_6_recommendation_is_exact():
    actual_lines = _read_report_text().splitlines()
    assert len(actual_lines) >= 6, f"Report is missing line 6; expected {EXPECTED_LINES[5]!r}"
    assert actual_lines[5] == EXPECTED_LINES[5], (
        f"Line 6 is wrong. Expected {EXPECTED_LINES[5]!r}. "
        "Because worker average CPU is 77.5, which is at least 75.0, recommendation must be scale-cpu; "
        f"got {actual_lines[5]!r}."
    )

def test_capacity_plan_report_line_7_verified_true_is_exact_and_final_line():
    actual_lines = _read_report_text().splitlines()
    assert len(actual_lines) >= 7, f"Report is missing line 7; expected {EXPECTED_LINES[6]!r}"
    assert actual_lines[6] == EXPECTED_LINES[6], (
        f"Line 7 is wrong. Expected {EXPECTED_LINES[6]!r}; got {actual_lines[6]!r}."
    )
    assert len(actual_lines) == 7, (
        f"Report must end after line 7 with no line 8 or trailing blank lines; "
        f"found {len(actual_lines)} line(s): {actual_lines!r}"
    )


You are helping a machine learning engineer prepare a reproducible training-data manifest from a Git working tree.

The repository is located at `/home/user/ml-data-repo`. It is already initialized as a Git repository and contains JSONL training shards under `/home/user/ml-data-repo/data/raw/`. Your job is to create a manifest that describes only the JSONL shard files that are tracked by Git in the current checkout.

Create the file:

`/home/user/ml-data-repo/training_data_manifest.tsv`

The manifest must be a tab-separated text file with exactly one header row followed by one row per eligible shard. The required header is exactly:

`git_path	record_count	split`

Eligibility rules:

1. Include only files tracked by Git in the current checkout.
2. Include only files whose Git path starts with `data/raw/`.
3. Include only files whose name ends with `.jsonl`.
4. Exclude untracked files, ignored files, temporary files, and any files outside `data/raw/`.
5. Do not rely on a pre-existing helper script unless you verify that its output satisfies all rules.

For each included shard:

- `git_path` must be the repository-relative Git path, using forward slashes.
- `record_count` must be the number of non-empty lines in that file.
- `split` must be the immediate directory name under `data/raw/`; for example, a file at `data/raw/train/example.jsonl` has split `train`.

Rows must be sorted lexicographically by `git_path`.

Also create a verification log at:

`/home/user/ml-data-repo/training_data_manifest.verify.log`

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

1. `artifact=training_data_manifest.tsv`
2. `tracked_jsonl_files=<N>`
3. `manifest_rows=<N>`
4. `all_rows_have_three_columns=yes`
5. `status=verified`

Replace `<N>` with the number of eligible tracked JSONL shard files. The two `<N>` values must match. Do not include extra lines or trailing commentary in the verification log.

Before finishing, inspect the generated manifest and make sure it satisfies the eligibility, sorting, and counting rules above. A command or script exiting successfully is not enough; the actual artifact contents must be correct.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_051e87a8"
description = "You are helping a machine learning engineer prepare a reproducible training-data manifest from a Git working tree."
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 -eux

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

    REPO=/home/user/ml-data-repo

    rm -rf "$REPO"
    mkdir -p \
        "$REPO/data/raw/train" \
        "$REPO/data/raw/validation" \
        "$REPO/data/raw/test" \
        "$REPO/data/notes" \
        "$REPO/scripts" \
        "$REPO/tmp"

    cat > "$REPO/README.md" <<'EOF'
# ML Data Repository

This repository contains JSONL training-data shards for a manifest generation task.
EOF

    cat > "$REPO/.gitignore" <<'EOF'
tmp/
*.tmp
.cache.jsonl
EOF

    cat > "$REPO/data/raw/train/shard-000.jsonl" <<'EOF'
{"id":"tr-000-001","text":"warm start sample","label":"keep"}
{"id":"tr-000-002","text":"gradient checkpoint note","label":"keep"}
{"id":"tr-000-003","text":"bad OCR span removed","label":"drop"}
EOF

    cat > "$REPO/data/raw/train/shard-001.jsonl" <<'EOF'
{"id":"tr-001-001","text":"tokenizer regression example","label":"keep"}
{"id":"tr-001-002","text":"long context packing case","label":"keep"}
EOF

    cat > "$REPO/data/raw/validation/shard-000.jsonl" <<'EOF'
{"id":"va-000-001","text":"heldout factuality prompt","label":"keep"}
{"id":"va-000-002","text":"heldout math prompt","label":"keep"}
{"id":"va-000-003","text":"heldout code prompt","label":"keep"}
{"id":"va-000-004","text":"heldout safety prompt","label":"drop"}
EOF

    cat > "$REPO/data/raw/test/shard-000.jsonl" <<'EOF'
{"id":"te-000-001","text":"final benchmark item","label":"keep"}
EOF

    cat > "$REPO/data/raw/test/shard-001.jsonl" <<'EOF'
{"id":"te-001-001","text":"adversarial paraphrase one","label":"keep"}
{"id":"te-001-002","text":"adversarial paraphrase two","label":"keep"}
{"id":"te-001-003","text":"adversarial paraphrase three","label":"drop"}
{"id":"te-001-004","text":"adversarial paraphrase four","label":"keep"}
{"id":"te-001-005","text":"adversarial paraphrase five","label":"keep"}
EOF

    cat > "$REPO/data/notes/schema.md" <<'EOF'
# Data schema

Each JSONL row is a training example with id, text, and label fields.
EOF

    cat > "$REPO/scripts/make_manifest.py" <<'EOF'
#!/usr/bin/env python3
"""
Misleading helper script for the task.

This script intentionally uses filesystem discovery rather than Git tracking
information, labels validation as val, and does not create the verification log.
It exits successfully while producing a semantically incorrect manifest.
"""
from pathlib import Path

repo = Path(__file__).resolve().parents[1]
out = repo / "training_data_manifest.tsv"

rows = []
for path in sorted((repo / "data" / "raw").rglob("*.jsonl")):
    rel = path.relative_to(repo).as_posix()
    split = path.relative_to(repo / "data" / "raw").parts[0]
    if split == "validation":
        split = "val"
    count = sum(1 for line in path.read_text(encoding="utf-8").splitlines() if line.strip())
    rows.append((rel, count, split))

with out.open("w", encoding="utf-8") as fh:
    fh.write("git_path\trecord_count\tsplit\n")
    for rel, count, split in rows:
        fh.write(f"{rel}\t{count}\t{split}\n")
EOF
    chmod 755 "$REPO/scripts/make_manifest.py"

    chown -R user:user /home/user

    cd "$REPO"
    runuser -u user -- git init -b main
    runuser -u user -- git config --local user.name "Task User"
    runuser -u user -- git config --local user.email "task.user@example.com"
    runuser -u user -- git add \
        README.md \
        .gitignore \
        data/raw/train/shard-000.jsonl \
        data/raw/train/shard-001.jsonl \
        data/raw/validation/shard-000.jsonl \
        data/raw/test/shard-000.jsonl \
        data/raw/test/shard-001.jsonl \
        data/notes/schema.md \
        scripts/make_manifest.py
    runuser -u user -- git commit -m "Initial tracked training data shards"

    cat > "$REPO/data/raw/train/debug-sample.jsonl" <<'EOF'
{"id":"dbg-001","text":"debug one","label":"keep"}
{"id":"dbg-002","text":"debug two","label":"keep"}
{"id":"dbg-003","text":"debug three","label":"keep"}
{"id":"dbg-004","text":"debug four","label":"keep"}
{"id":"dbg-005","text":"debug five","label":"keep"}
{"id":"dbg-006","text":"debug six","label":"keep"}
EOF

    cat > "$REPO/data/raw/validation/local-copy.jsonl" <<'EOF'
{"id":"local-001","text":"local validation copy one","label":"keep"}
{"id":"local-002","text":"local validation copy two","label":"keep"}
EOF

    cat > "$REPO/tmp/generated_manifest.tsv" <<'EOF'
git_path	record_count	split
data/raw/train/debug-sample.jsonl	6	train
EOF

    cat > "$REPO/data/raw/train/.cache.jsonl" <<'EOF'
{"id":"cache-001","text":"cache one","label":"keep"}
{"id":"cache-002","text":"cache two","label":"keep"}
{"id":"cache-003","text":"cache three","label":"keep"}
{"id":"cache-004","text":"cache four","label":"keep"}
{"id":"cache-005","text":"cache five","label":"keep"}
{"id":"cache-006","text":"cache six","label":"keep"}
{"id":"cache-007","text":"cache seven","label":"keep"}
{"id":"cache-008","text":"cache eight","label":"keep"}
{"id":"cache-009","text":"cache nine","label":"keep"}
EOF

    cat > "$REPO/data/raw/test/shard-999.tmp" <<'EOF'
temporary ignored shard placeholder
EOF

    chown -R user:user /home/user
    chmod -R u+rwX,go+rX /home/user
    chmod 755 /home/user
    chmod 755 "$REPO"

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

# test_final_state.py
import subprocess
from pathlib import Path

import pytest

REPO = Path("/home/user/ml-data-repo")
MANIFEST = Path("/home/user/ml-data-repo/training_data_manifest.tsv")
VERIFY_LOG = Path("/home/user/ml-data-repo/training_data_manifest.verify.log")

EXPECTED_MANIFEST_LINES = [
    "git_path\trecord_count\tsplit",
    "data/raw/test/shard-000.jsonl\t1\ttest",
    "data/raw/test/shard-001.jsonl\t5\ttest",
    "data/raw/train/shard-000.jsonl\t3\ttrain",
    "data/raw/train/shard-001.jsonl\t2\ttrain",
    "data/raw/validation/shard-000.jsonl\t4\tvalidation",
]

EXPECTED_VERIFY_LOG_LINES = [
    "artifact=training_data_manifest.tsv",
    "tracked_jsonl_files=5",
    "manifest_rows=5",
    "all_rows_have_three_columns=yes",
    "status=verified",
]

EXPECTED_ELIGIBLE_PATHS = [
    "data/raw/test/shard-000.jsonl",
    "data/raw/test/shard-001.jsonl",
    "data/raw/train/shard-000.jsonl",
    "data/raw/train/shard-001.jsonl",
    "data/raw/validation/shard-000.jsonl",
]

EXPECTED_COUNTS = {
    "data/raw/test/shard-000.jsonl": 1,
    "data/raw/test/shard-001.jsonl": 5,
    "data/raw/train/shard-000.jsonl": 3,
    "data/raw/train/shard-001.jsonl": 2,
    "data/raw/validation/shard-000.jsonl": 4,
}

EXPECTED_SPLITS = {
    "data/raw/test/shard-000.jsonl": "test",
    "data/raw/test/shard-001.jsonl": "test",
    "data/raw/train/shard-000.jsonl": "train",
    "data/raw/train/shard-001.jsonl": "train",
    "data/raw/validation/shard-000.jsonl": "validation",
}

FORBIDDEN_PATHS = {
    "data/raw/train/debug-sample.jsonl",
    "data/raw/validation/local-copy.jsonl",
    "data/raw/train/.cache.jsonl",
    "data/raw/test/shard-999.tmp",
    "tmp/generated_manifest.tsv",
}

def run_git(*args: str) -> subprocess.CompletedProcess:
    return subprocess.run(
        ["git", *args],
        cwd=str(REPO),
        text=True,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        check=False,
    )

def read_text_exact(path: Path) -> str:
    return path.read_text(encoding="utf-8")

def read_lines_exact(path: Path):
    return read_text_exact(path).splitlines()

def non_empty_line_count(path: Path) -> int:
    return sum(1 for line in path.read_text(encoding="utf-8").splitlines() if line.strip())

def parse_manifest_rows():
    lines = read_lines_exact(MANIFEST)
    rows = []
    for line_number, line in enumerate(lines[1:], start=2):
        columns = line.split("\t")
        assert len(columns) == 3, (
            f"Manifest row {line_number} must have exactly three tab-separated columns, "
            f"but got {len(columns)} columns: {line!r}"
        )
        git_path, record_count, split = columns
        rows.append(
            {
                "line_number": line_number,
                "git_path": git_path,
                "record_count": record_count,
                "split": split,
            }
        )
    return rows

def test_manifest_file_exists_at_required_absolute_path():
    assert MANIFEST.exists(), (
        "Missing required manifest file at absolute path "
        "/home/user/ml-data-repo/training_data_manifest.tsv"
    )
    assert MANIFEST.is_file(), (
        "Required manifest path exists but is not a regular file: "
        "/home/user/ml-data-repo/training_data_manifest.tsv"
    )

def test_manifest_content_matches_required_final_artifact_exactly():
    assert MANIFEST.exists(), (
        "Cannot inspect manifest because it is missing at "
        "/home/user/ml-data-repo/training_data_manifest.tsv"
    )

    actual_text = read_text_exact(MANIFEST)
    expected_text = "\n".join(EXPECTED_MANIFEST_LINES) + "\n"

    assert actual_text == expected_text, (
        "Manifest content is not exactly the required final content. "
        "It must contain only the header and the five eligible Git-tracked JSONL shards, "
        "sorted by git_path, with tab separators and correct non-empty record counts.\n"
        f"Expected:\n{expected_text!r}\n"
        f"Got:\n{actual_text!r}"
    )

def test_manifest_header_line_count_and_column_format_are_correct():
    lines = read_lines_exact(MANIFEST)

    assert lines, "Manifest is empty; it must start with header 'git_path\\trecord_count\\tsplit'"
    assert lines[0] == "git_path\trecord_count\tsplit", (
        f"Manifest header is wrong. Expected exactly "
        f"'git_path\\trecord_count\\tsplit', got {lines[0]!r}"
    )
    assert len(lines) == 6, (
        f"Manifest must have exactly 6 lines: one header plus five eligible shard rows. "
        f"Got {len(lines)} lines."
    )

    for line_number, line in enumerate(lines, start=1):
        columns = line.split("\t")
        assert len(columns) == 3, (
            f"Manifest line {line_number} must have exactly three tab-separated columns, "
            f"but got {len(columns)} columns: {line!r}"
        )

def test_manifest_rows_are_exactly_git_tracked_eligible_jsonl_paths():
    result = run_git("ls-files")
    assert result.returncode == 0, (
        "Could not query Git tracked files with 'git ls-files' in "
        f"/home/user/ml-data-repo: {result.stderr}"
    )
    tracked = set(result.stdout.splitlines())

    expected_from_git = sorted(
        path for path in tracked
        if path.startswith("data/raw/") and path.endswith(".jsonl")
    )
    assert expected_from_git == EXPECTED_ELIGIBLE_PATHS, (
        "The current Git-tracked eligible shard set does not match the expected task truth. "
        f"Expected {EXPECTED_ELIGIBLE_PATHS!r}, got {expected_from_git!r}"
    )

    rows = parse_manifest_rows()
    manifest_paths = [row["git_path"] for row in rows]

    assert manifest_paths == EXPECTED_ELIGIBLE_PATHS, (
        "Manifest includes the wrong shard paths. It must include exactly the eligible "
        "Git-tracked JSONL files under data/raw/ and exclude untracked, ignored, temporary, "
        f"and out-of-scope files. Expected {EXPECTED_ELIGIBLE_PATHS!r}, got {manifest_paths!r}"
    )

    unexpected_forbidden = sorted(FORBIDDEN_PATHS.intersection(manifest_paths))
    assert not unexpected_forbidden, (
        "Manifest incorrectly includes files that must be excluded because they are untracked, "
        "ignored, temporary, or outside the eligible shard set: "
        + ", ".join(unexpected_forbidden)
    )

    untracked_or_unlisted = sorted(path for path in manifest_paths if path not in tracked)
    assert not untracked_or_unlisted, (
        "Manifest contains paths that are not tracked by Git in the current checkout: "
        + ", ".join(untracked_or_unlisted)
    )

def test_manifest_rows_are_sorted_lexicographically_by_git_path():
    rows = parse_manifest_rows()
    manifest_paths = [row["git_path"] for row in rows]

    assert manifest_paths == sorted(manifest_paths), (
        "Manifest rows are not sorted lexicographically by git_path. "
        f"Got order {manifest_paths!r}; expected {sorted(manifest_paths)!r}"
    )

def test_manifest_record_counts_and_split_names_are_semantically_correct():
    rows = parse_manifest_rows()

    for row in rows:
        git_path = row["git_path"]
        full_path = Path("/home/user/ml-data-repo") / git_path

        assert git_path in EXPECTED_COUNTS, (
            f"Unexpected manifest path {git_path!r}; only tracked eligible JSONL shards "
            "under data/raw/ may appear."
        )

        assert full_path.exists(), (
            f"Manifest references {git_path!r}, but the corresponding absolute path "
            f"{full_path} does not exist."
        )
        assert full_path.is_file(), (
            f"Manifest references {git_path!r}, but the corresponding absolute path "
            f"{full_path} is not a regular file."
        )

        assert row["record_count"].isdigit(), (
            f"record_count for {git_path!r} must be a decimal integer, "
            f"got {row['record_count']!r}"
        )
        actual_count_from_file = non_empty_line_count(full_path)
        expected_count = EXPECTED_COUNTS[git_path]

        assert int(row["record_count"]) == expected_count, (
            f"record_count for {git_path!r} is wrong. Expected {expected_count} "
            f"non-empty lines, got manifest value {row['record_count']!r}."
        )
        assert actual_count_from_file == expected_count, (
            f"The source shard {full_path} no longer has the expected non-empty line count. "
            f"Expected {expected_count}, got {actual_count_from_file}."
        )

        expected_split = EXPECTED_SPLITS[git_path]
        assert row["split"] == expected_split, (
            f"split for {git_path!r} is wrong. Expected immediate directory name "
            f"under data/raw/ to be {expected_split!r}, got {row['split']!r}."
        )

def test_verification_log_exists_at_required_absolute_path():
    assert VERIFY_LOG.exists(), (
        "Missing required verification log at absolute path "
        "/home/user/ml-data-repo/training_data_manifest.verify.log"
    )
    assert VERIFY_LOG.is_file(), (
        "Required verification log path exists but is not a regular file: "
        "/home/user/ml-data-repo/training_data_manifest.verify.log"
    )

def test_verification_log_content_matches_required_five_lines_exactly():
    assert VERIFY_LOG.exists(), (
        "Cannot inspect verification log because it is missing at "
        "/home/user/ml-data-repo/training_data_manifest.verify.log"
    )

    actual_text = read_text_exact(VERIFY_LOG)
    expected_text = "\n".join(EXPECTED_VERIFY_LOG_LINES) + "\n"

    assert actual_text == expected_text, (
        "Verification log content is not exactly correct. It must contain exactly the five "
        "required lines, in order, with both counts equal to the number of eligible tracked "
        "JSONL shard files and no extra commentary.\n"
        f"Expected:\n{expected_text!r}\n"
        f"Got:\n{actual_text!r}"
    )

def test_manifest_and_verification_log_counts_agree():
    rows = parse_manifest_rows()
    manifest_row_count = len(rows)

    log_lines = read_lines_exact(VERIFY_LOG)
    assert len(log_lines) == 5, (
        f"Verification log must contain exactly five lines, got {len(log_lines)} lines."
    )

    tracked_line = log_lines[1]
    manifest_line = log_lines[2]

    assert tracked_line == f"tracked_jsonl_files={len(EXPECTED_ELIGIBLE_PATHS)}", (
        "Verification log tracked_jsonl_files line is wrong. "
        f"Expected 'tracked_jsonl_files={len(EXPECTED_ELIGIBLE_PATHS)}', got {tracked_line!r}"
    )
    assert manifest_line == f"manifest_rows={manifest_row_count}", (
        "Verification log manifest_rows line does not match the actual number of manifest "
        f"data rows. Expected 'manifest_rows={manifest_row_count}', got {manifest_line!r}"
    )
    assert manifest_row_count == len(EXPECTED_ELIGIBLE_PATHS), (
        f"Manifest should have {len(EXPECTED_ELIGIBLE_PATHS)} data rows, got {manifest_row_count}."
    )


You’re helping a data analyst finish a small CSV encoding cleanup in `/home/user/encoding_task`.

The source file is `/home/user/encoding_task/raw/customers_latin1.csv`. It is a semicolon-delimited CSV exported from an older system and encoded as ISO-8859-1 / Latin-1. It contains customer names and cities with accented characters. Please convert it to a UTF-8 CSV for downstream tools.

Create the final output file at:

`/home/user/encoding_task/processed/customers_utf8.csv`

Requirements for `/home/user/encoding_task/processed/customers_utf8.csv`:

1. It must be UTF-8 encoded text.
2. It must use commas as delimiters, not semicolons.
3. It must contain exactly one header row followed by exactly six data rows.
4. The header must be exactly:
   `id,name,city,segment`
5. Preserve the original field values exactly except for the delimiter and encoding conversion.
6. The accented characters must display correctly in UTF-8, not as replacement characters, escape sequences, or mojibake.
7. The final file must end with a single newline.

Also create a verification log at:

`/home/user/encoding_task/processed/verification.log`

The verification log must be plain UTF-8 text with exactly these four lines, in this order, using `PASS` or `FAIL` as appropriate:

`utf8_valid: PASS|FAIL`
`comma_delimited: PASS|FAIL`
`row_count: PASS|FAIL`
`accented_text_preserved: PASS|FAIL`

Before you stop, inspect the produced CSV itself and make sure the log reflects the actual file contents. Do not treat a command exiting successfully as sufficient; the deliverable is only complete if the CSV content is valid and the verification log records all four checks as `PASS`.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_29c27adb"
description = "You\u2019re helping a data analyst finish a small CSV encoding cleanup in `/home/user/encoding_task`."
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 -eux

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

    mkdir -p /home/user/encoding_task/raw
    mkdir -p /home/user/encoding_task/processed

    python3 - <<'PY'
from pathlib import Path

text = (
    "id;name;city;segment\n"
    "1;André Martin;Montréal;retail\n"
    "2;Björk Gudmundsdóttir;Reykjavík;music\n"
    "3;François Dupont;Québec;enterprise\n"
    "4;Marta Peña;Bogotá;smb\n"
    "5;Jürgen Müller;Zürich;enterprise\n"
    "6;Chloë Dubois;Genève;retail\n"
)

path = Path("/home/user/encoding_task/raw/customers_latin1.csv")
path.write_bytes(text.encode("iso-8859-1"))
PY

    chmod 755 /home/user
    chmod 755 /home/user/encoding_task
    chmod 755 /home/user/encoding_task/raw
    chmod 644 /home/user/encoding_task/raw/customers_latin1.csv
    chmod 777 /home/user/encoding_task/processed

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

# test_final_state.py
from pathlib import Path
import csv
import io

CSV_PATH = Path("/home/user/encoding_task/processed/customers_utf8.csv")
LOG_PATH = Path("/home/user/encoding_task/processed/verification.log")

EXPECTED_CSV_TEXT = (
    "id,name,city,segment\n"
    "1,André Martin,Montréal,retail\n"
    "2,Björk Gudmundsdóttir,Reykjavík,music\n"
    "3,François Dupont,Québec,enterprise\n"
    "4,Marta Peña,Bogotá,smb\n"
    "5,Jürgen Müller,Zürich,enterprise\n"
    "6,Chloë Dubois,Genève,retail\n"
)

EXPECTED_LOG_TEXT = (
    "utf8_valid: PASS\n"
    "comma_delimited: PASS\n"
    "row_count: PASS\n"
    "accented_text_preserved: PASS\n"
)

EXPECTED_ROWS = [
    ["id", "name", "city", "segment"],
    ["1", "André Martin", "Montréal", "retail"],
    ["2", "Björk Gudmundsdóttir", "Reykjavík", "music"],
    ["3", "François Dupont", "Québec", "enterprise"],
    ["4", "Marta Peña", "Bogotá", "smb"],
    ["5", "Jürgen Müller", "Zürich", "enterprise"],
    ["6", "Chloë Dubois", "Genève", "retail"],
]

MOJIBAKE_STRINGS = [
    "AndrÃ©",
    "MontrÃ©al",
    "BjÃ¶rk",
    "ReykjavÃk",
    "FranÃ§ois",
    "QuÃ©bec",
    "PeÃ±a",
    "BogotÃ¡",
    "JÃ¼rgen",
    "MÃ¼ller",
    "ZÃ¼rich",
    "ChloÃ«",
    "GenÃ¨ve",
]

def _read_utf8_text(path: Path) -> str:
    data = path.read_bytes()
    try:
        return data.decode("utf-8")
    except UnicodeDecodeError as exc:
        raise AssertionError(
            f"{path} is not valid UTF-8 text: decode failed at byte "
            f"{exc.start}: {exc.reason}."
        ) from exc

def test_required_output_files_exist_at_exact_paths():
    assert CSV_PATH.exists(), f"Missing required final CSV file: {CSV_PATH}"
    assert CSV_PATH.is_file(), f"Final CSV path exists but is not a regular file: {CSV_PATH}"

    assert LOG_PATH.exists(), f"Missing required verification log: {LOG_PATH}"
    assert LOG_PATH.is_file(), f"Verification log path exists but is not a regular file: {LOG_PATH}"

def test_customers_csv_is_valid_utf8_and_exact_expected_bytes():
    assert CSV_PATH.exists(), f"Missing required final CSV file: {CSV_PATH}"

    actual_bytes = CSV_PATH.read_bytes()
    expected_bytes = EXPECTED_CSV_TEXT.encode("utf-8")

    try:
        actual_text = actual_bytes.decode("utf-8")
    except UnicodeDecodeError as exc:
        raise AssertionError(
            f"{CSV_PATH} is not valid UTF-8. It must be converted from Latin-1 "
            f"to UTF-8; decode failed at byte {exc.start}: {exc.reason}."
        ) from exc

    assert actual_bytes == expected_bytes, (
        f"{CSV_PATH} does not match the exact expected UTF-8 comma-delimited "
        "content. The file must preserve all field values and accents exactly, "
        "replace semicolon delimiters with commas, contain exactly one header "
        "and six data rows, and end with one newline.\n"
        f"Actual decoded text was:\n{actual_text!r}"
    )

def test_customers_csv_uses_commas_not_semicolons():
    text = _read_utf8_text(CSV_PATH)

    assert ";" not in text, (
        f"{CSV_PATH} still contains semicolons. Encoding conversion alone is "
        "not sufficient; the CSV delimiter must be changed from semicolon to comma."
    )

    lines = text.splitlines()
    missing_commas = [line for line in lines if "," not in line]
    assert not missing_commas, (
        f"{CSV_PATH} has row(s) without comma delimiters: {missing_commas!r}"
    )

    parsed_rows = list(csv.reader(io.StringIO(text), delimiter=","))
    assert parsed_rows == EXPECTED_ROWS, (
        f"{CSV_PATH} is not parsed as the expected comma-delimited CSV rows. "
        f"Parsed rows were: {parsed_rows!r}"
    )

def test_customers_csv_has_exact_header_row_count_and_newline_termination():
    data = CSV_PATH.read_bytes()
    text = _read_utf8_text(CSV_PATH)

    assert data.endswith(b"\n"), f"{CSV_PATH} must end with a newline byte."
    assert not data.endswith(b"\n\n"), (
        f"{CSV_PATH} must end with exactly one trailing newline, not extra blank lines."
    )

    assert text.count("\n") == 7, (
        f"{CSV_PATH} must contain exactly seven newline-terminated records "
        f"(one header and six data rows); found {text.count(chr(10))} newline characters."
    )

    lines = text.splitlines()
    assert len(lines) == 7, (
        f"{CSV_PATH} must contain exactly one header row and six data rows; "
        f"found {len(lines)} rows."
    )
    assert lines[0] == "id,name,city,segment", (
        f"{CSV_PATH} has the wrong header. Expected "
        "'id,name,city,segment' but found {lines[0]!r}."
    )

def test_customers_csv_accents_are_preserved_without_replacement_or_mojibake():
    text = _read_utf8_text(CSV_PATH)

    assert "\ufffd" not in text, (
        f"{CSV_PATH} contains the Unicode replacement character '�', which "
        "means accented text was not decoded or preserved correctly."
    )

    present_mojibake = [bad for bad in MOJIBAKE_STRINGS if bad in text]
    assert not present_mojibake, (
        f"{CSV_PATH} contains mojibake text {present_mojibake!r}. The Latin-1 "
        "source must be decoded correctly before writing UTF-8."
    )

    expected_accented_values = [
        "André Martin",
        "Montréal",
        "Björk Gudmundsdóttir",
        "Reykjavík",
        "François Dupont",
        "Québec",
        "Marta Peña",
        "Bogotá",
        "Jürgen Müller",
        "Zürich",
        "Chloë Dubois",
        "Genève",
    ]
    missing_values = [value for value in expected_accented_values if value not in text]
    assert not missing_values, (
        f"{CSV_PATH} is missing expected accented field value(s): {missing_values!r}"
    )

def test_verification_log_is_valid_utf8_and_exactly_four_pass_lines():
    assert LOG_PATH.exists(), f"Missing required verification log: {LOG_PATH}"

    actual_text = _read_utf8_text(LOG_PATH)

    assert actual_text == EXPECTED_LOG_TEXT, (
        f"{LOG_PATH} must contain exactly the four required verification lines, "
        "all marked PASS and in the required order.\n"
        f"Expected:\n{EXPECTED_LOG_TEXT!r}\n"
        f"Actual:\n{actual_text!r}"
    )

def test_verification_log_reflects_actual_csv_success_state():
    csv_text = _read_utf8_text(CSV_PATH)
    log_text = _read_utf8_text(LOG_PATH)

    actual_checks = {
        "utf8_valid": True,
        "comma_delimited": ";" not in csv_text
        and all("," in line for line in csv_text.splitlines()),
        "row_count": csv_text.endswith("\n")
        and not csv_text.endswith("\n\n")
        and len(csv_text.splitlines()) == 7
        and csv_text.splitlines()[0] == "id,name,city,segment",
        "accented_text_preserved": (
            "\ufffd" not in csv_text
            and not any(bad in csv_text for bad in MOJIBAKE_STRINGS)
            and csv_text == EXPECTED_CSV_TEXT
        ),
    }

    failing_actual_checks = [
        name for name, passed in actual_checks.items() if not passed
    ]
    assert not failing_actual_checks, (
        "The produced CSV does not actually satisfy these verification "
        f"check(s), so the log cannot truthfully be all PASS: {failing_actual_checks!r}"
    )

    expected_lines = [f"{name}: PASS" for name in actual_checks]
    actual_lines = log_text.splitlines()
    assert actual_lines == expected_lines, (
        f"{LOG_PATH} does not truthfully record all four required checks as "
        f"PASS in order. Expected lines {expected_lines!r}, found {actual_lines!r}."
    )


You are helping a release manager prepare a deployment shell environment for a small service. Please update the deployment environment file and write a verification ledger so another teammate can confirm the work without re-running your commands.

Work only under `/home/user/release-prep`. The file `/home/user/release-prep/deploy.env` already exists and contains draft settings. Modify that file so that it is a valid shell-style environment file with exactly these public requirements:

1. Keep the existing variable names and make sure the final file contains exactly one assignment line for each of these variables, in this order:
   - `APP_NAME`
   - `DEPLOY_ENV`
   - `RELEASE_CHANNEL`
   - `REGION`
   - `CANARY_PERCENT`
   - `FEATURE_FLAGS`
2. Set the deployment environment for a production rollout:
   - `DEPLOY_ENV` must be `production`
   - `RELEASE_CHANNEL` must be `stable`
   - `REGION` must be `us-east-2`
   - `CANARY_PERCENT` must be `10`
3. Preserve the existing application name already present in the file.
4. The `FEATURE_FLAGS` value must be a comma-separated list with no spaces. It must include `audit_logging`, `metrics_v2`, and `safe_shutdown`, and it must not include duplicate flags.
5. The final `/home/user/release-prep/deploy.env` file must contain only the six assignment lines listed above: no comments, no blank lines, and no extra variables.

After editing the environment file, create `/home/user/release-prep/release_ledger.log`. This ledger is part of the deliverable and must have exactly seven lines in this format:

```text
CHECK 1 app_name_preserved=YES
CHECK 2 deploy_env_production=YES
CHECK 3 release_channel_stable=YES
CHECK 4 region_us_east_2=YES
CHECK 5 canary_percent_10=YES
CHECK 6 feature_flags_valid=YES
READY production_deployment_env=YES
```

Do not add any extra text before or after those seven lines. Before you finish, verify for yourself that both files meet the requirements exactly.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_2d8f7eba"
description = "You are helping a release manager prepare a deployment shell environment for a small service. Please update the deployment environment file and write a verification ledger so another teammate can confirm the work without re-running your com"
authors = [{ name = "Endless Terminals / Jarrod Barnes" }]
keywords = ["agentic-rl", "endless-terminals", "long_horizon_progress_ledger", "partial_progress_stall", "terminal-bench-2"]

[metadata]
source = "endless-terminals"
corpus = "processrl-core-v1"
generation_mode = "behavior_conditioned_llm_funnel"
behavior_card_id = "partial_progress_stall"
capability = "long_horizon_progress_ledger"
source_traces = ["security-incident-log-analysis", "security-breach-incident-respons", "bash-log-processor-fix", "server-log-analysis"]

[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 \
        passwd \
        ca-certificates
    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/release-prep

    cat > /home/user/release-prep/deploy.env <<'EOF'
# Draft deployment environment for release manager
APP_NAME=inventory-api
DEPLOY_ENV=staging
RELEASE_CHANNEL=beta
REGION=us-west-1
CANARY_PERCENT=5
FEATURE_FLAGS=audit_logging,metrics_v2
DEBUG_MODE=false
EOF

    rm -f /home/user/release-prep/release_ledger.log

    chown -R user:user /home/user
    chmod 755 /home/user
    chmod 755 /home/user/release-prep
    chmod 644 /home/user/release-prep/deploy.env

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

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

import pytest

BASE_DIR = Path("/home/user/release-prep")
DEPLOY_ENV = Path("/home/user/release-prep/deploy.env")
RELEASE_LEDGER = Path("/home/user/release-prep/release_ledger.log")

EXPECTED_DEPLOY_LINES = [
    "APP_NAME=inventory-api",
    "DEPLOY_ENV=production",
    "RELEASE_CHANNEL=stable",
    "REGION=us-east-2",
    "CANARY_PERCENT=10",
    "FEATURE_FLAGS=audit_logging,metrics_v2,safe_shutdown",
]

EXPECTED_LEDGER_LINES = [
    "CHECK 1 app_name_preserved=YES",
    "CHECK 2 deploy_env_production=YES",
    "CHECK 3 release_channel_stable=YES",
    "CHECK 4 region_us_east_2=YES",
    "CHECK 5 canary_percent_10=YES",
    "CHECK 6 feature_flags_valid=YES",
    "READY production_deployment_env=YES",
]

EXPECTED_DEPLOY_CONTENT = "\n".join(EXPECTED_DEPLOY_LINES) + "\n"
EXPECTED_LEDGER_CONTENT = "\n".join(EXPECTED_LEDGER_LINES) + "\n"

REQUIRED_VARIABLE_ORDER = [
    "APP_NAME",
    "DEPLOY_ENV",
    "RELEASE_CHANNEL",
    "REGION",
    "CANARY_PERCENT",
    "FEATURE_FLAGS",
]

def _user_uid_gid(username: str = "user") -> tuple[int, int]:
    try:
        entry = pwd.getpwnam(username)
    except KeyError:
        pytest.fail(f"Required OS user {username!r} does not exist")
    return entry.pw_uid, entry.pw_gid

def _user_group_ids(username: str = "user") -> set[int]:
    uid, gid = _user_uid_gid(username)
    groups = {gid}
    try:
        groups.update(os.getgrouplist(username, gid))
    except OSError as exc:
        pytest.fail(f"Could not determine group membership for user {username!r}: {exc}")
    return groups

def _is_readable_by_user(path: Path, username: str = "user") -> bool:
    uid, _gid = _user_uid_gid(username)
    groups = _user_group_ids(username)
    stat_result = path.stat()
    mode = stat_result.st_mode

    if stat_result.st_uid == uid and mode & 0o400:
        return True
    if stat_result.st_gid in groups and mode & 0o040:
        return True
    if mode & 0o004:
        return True
    return False

def _is_writable_by_user(path: Path, username: str = "user") -> bool:
    uid, _gid = _user_uid_gid(username)
    groups = _user_group_ids(username)
    stat_result = path.stat()
    mode = stat_result.st_mode

    if stat_result.st_uid == uid and mode & 0o200:
        return True
    if stat_result.st_gid in groups and mode & 0o020:
        return True
    if mode & 0o002:
        return True
    return False

def _read_text(path: Path) -> str:
    try:
        return path.read_text(encoding="utf-8")
    except UnicodeDecodeError as exc:
        pytest.fail(f"File is not valid UTF-8 text: {path}: {exc}")
    except OSError as exc:
        pytest.fail(f"Could not read required file {path}: {exc}")

def _split_lines_allow_single_trailing_newline(text: str) -> list[str]:
    if text.endswith("\n"):
        text = text[:-1]
    return text.split("\n") if text else []

def _assert_exact_text_allow_single_trailing_newline(path: Path, expected: str) -> None:
    actual = _read_text(path)
    normalized_actual = actual[:-1] if actual.endswith("\n") else actual
    normalized_expected = expected[:-1] if expected.endswith("\n") else expected

    assert normalized_actual == normalized_expected, (
        f"{path} does not match the required final content exactly "
        "(except that one trailing newline at EOF is allowed).\n"
        f"Expected content:\n{expected!r}\n"
        f"Actual content:\n{actual!r}"
    )

def _parse_assignment_lines(lines: list[str]) -> dict[str, str]:
    parsed = {}
    for line_number, line in enumerate(lines, start=1):
        assert "=" in line, (
            f"{DEPLOY_ENV} line {line_number} is not a shell-style assignment line: {line!r}"
        )
        name, value = line.split("=", 1)
        parsed[name] = value
    return parsed

def test_release_prep_directory_still_exists():
    assert BASE_DIR.exists(), f"Required directory is missing: {BASE_DIR}"
    assert BASE_DIR.is_dir(), f"Required path exists but is not a directory: {BASE_DIR}"

def test_deploy_env_exists_regular_file_and_user_read_write():
    assert DEPLOY_ENV.exists(), f"Required final file is missing: {DEPLOY_ENV}"
    assert DEPLOY_ENV.is_file(), f"Required path exists but is not a regular file: {DEPLOY_ENV}"
    assert _is_readable_by_user(
        DEPLOY_ENV, "user"
    ), f"{DEPLOY_ENV} must be readable by the /home/user account"
    assert _is_writable_by_user(
        DEPLOY_ENV, "user"
    ), f"{DEPLOY_ENV} must be writable by the /home/user account"

def test_deploy_env_has_no_comments_blank_lines_or_extra_variables():
    content = _read_text(DEPLOY_ENV)
    lines = _split_lines_allow_single_trailing_newline(content)

    assert len(lines) == 6, (
        f"{DEPLOY_ENV} must contain exactly six assignment lines and no extra text; "
        f"found {len(lines)} lines: {lines!r}"
    )

    for line_number, line in enumerate(lines, start=1):
        assert line, f"{DEPLOY_ENV} contains a blank line at line {line_number}; remove it"
        assert not line.lstrip().startswith("#"), (
            f"{DEPLOY_ENV} contains a comment at line {line_number}: {line!r}; "
            "comments are not allowed in the final file"
        )
        assert "=" in line, (
            f"{DEPLOY_ENV} line {line_number} is not an assignment line: {line!r}"
        )
        name, _value = line.split("=", 1)
        assert name in REQUIRED_VARIABLE_ORDER, (
            f"{DEPLOY_ENV} contains an extra or invalid variable {name!r} at line "
            f"{line_number}; allowed variables are exactly {REQUIRED_VARIABLE_ORDER!r}"
        )

def test_deploy_env_required_variables_appear_once_and_in_order():
    lines = _split_lines_allow_single_trailing_newline(_read_text(DEPLOY_ENV))
    actual_names = [line.split("=", 1)[0] if "=" in line else line for line in lines]

    assert actual_names == REQUIRED_VARIABLE_ORDER, (
        f"{DEPLOY_ENV} must contain the six required variable names exactly once and "
        "in the required order.\n"
        f"Expected order: {REQUIRED_VARIABLE_ORDER!r}\n"
        f"Actual order:   {actual_names!r}"
    )

def test_app_name_is_preserved_exactly():
    lines = _split_lines_allow_single_trailing_newline(_read_text(DEPLOY_ENV))
    assignments = _parse_assignment_lines(lines)

    assert assignments.get("APP_NAME") == "inventory-api", (
        f"APP_NAME must preserve the original value 'inventory-api'; "
        f"found {assignments.get('APP_NAME')!r}"
    )

def test_production_rollout_settings_are_exact():
    lines = _split_lines_allow_single_trailing_newline(_read_text(DEPLOY_ENV))
    assignments = _parse_assignment_lines(lines)

    expected_values = {
        "DEPLOY_ENV": "production",
        "RELEASE_CHANNEL": "stable",
        "REGION": "us-east-2",
        "CANARY_PERCENT": "10",
    }

    for name, expected_value in expected_values.items():
        actual_value = assignments.get(name)
        assert actual_value == expected_value, (
            f"{name} must be {expected_value!r} for the production rollout; "
            f"found {actual_value!r}"
        )

def test_feature_flags_are_canonical_complete_no_spaces_or_duplicates():
    lines = _split_lines_allow_single_trailing_newline(_read_text(DEPLOY_ENV))
    assignments = _parse_assignment_lines(lines)
    actual = assignments.get("FEATURE_FLAGS")

    assert actual == "audit_logging,metrics_v2,safe_shutdown", (
        "FEATURE_FLAGS must be the canonical comma-separated value "
        "'audit_logging,metrics_v2,safe_shutdown'; "
        f"found {actual!r}"
    )
    assert " " not in actual, f"FEATURE_FLAGS must not contain spaces; found {actual!r}"

    flags = actual.split(",")
    assert len(flags) == len(set(flags)), (
        f"FEATURE_FLAGS must not contain duplicate flags; found {flags!r}"
    )
    for required_flag in ["audit_logging", "metrics_v2", "safe_shutdown"]:
        assert required_flag in flags, (
            f"FEATURE_FLAGS is missing required flag {required_flag!r}; found {flags!r}"
        )

def test_release_ledger_exists_and_is_regular_file():
    assert RELEASE_LEDGER.exists(), f"Required ledger file is missing: {RELEASE_LEDGER}"
    assert RELEASE_LEDGER.is_file(), (
        f"Required ledger path exists but is not a regular file: {RELEASE_LEDGER}"
    )

def test_release_ledger_has_exact_seven_required_lines_only():
    content = _read_text(RELEASE_LEDGER)
    lines = _split_lines_allow_single_trailing_newline(content)

    assert lines == EXPECTED_LEDGER_LINES, (
        f"{RELEASE_LEDGER} must contain exactly the seven required ledger lines, "
        "in order, with no extra explanatory text.\n"
        f"Expected lines: {EXPECTED_LEDGER_LINES!r}\n"
        f"Actual lines:   {lines!r}"
    )

def test_deploy_env_final_content_matches_exact_ground_truth():
    _assert_exact_text_allow_single_trailing_newline(DEPLOY_ENV, EXPECTED_DEPLOY_CONTENT)

def test_release_ledger_final_content_matches_exact_ground_truth():
    _assert_exact_text_allow_single_trailing_newline(RELEASE_LEDGER, EXPECTED_LEDGER_CONTENT)

def test_stop_condition_both_files_match_exact_final_state():
    deploy_actual = _read_text(DEPLOY_ENV)
    ledger_actual = _read_text(RELEASE_LEDGER)

    deploy_normalized = deploy_actual[:-1] if deploy_actual.endswith("\n") else deploy_actual
    ledger_normalized = ledger_actual[:-1] if ledger_actual.endswith("\n") else ledger_actual
    expected_deploy_normalized = EXPECTED_DEPLOY_CONTENT[:-1]
    expected_ledger_normalized = EXPECTED_LEDGER_CONTENT[:-1]

    assert deploy_normalized == expected_deploy_normalized and ledger_normalized == expected_ledger_normalized, (
        "Final stop condition not met: both deliverable files must match the exact "
        "ground-truth final state, allowing only a single trailing newline at EOF.\n"
        f"Expected {DEPLOY_ENV}: {EXPECTED_DEPLOY_CONTENT!r}\n"
        f"Actual   {DEPLOY_ENV}: {deploy_actual!r}\n"
        f"Expected {RELEASE_LEDGER}: {EXPECTED_LEDGER_CONTENT!r}\n"
        f"Actual   {RELEASE_LEDGER}: {ledger_actual!r}"
    )


You are helping a monitoring specialist prepare alert-window text that will be consumed by an older pager integration. Work in the existing writable project directory `/home/user/monitoring`.

The source data is already present at `/home/user/monitoring/data/alert_windows.csv`. It contains UTC alert start times. Your job is to configure and run the rendering job so that the final artifact uses the operations team’s required time zone and locale.

Required final artifact:

* Create or overwrite `/home/user/monitoring/out/alert_windows.log`.
* The file must be plain UTF-8 text.
* It must contain exactly 4 non-empty lines.
* Line 1 must be exactly:

```text
ALERT_WINDOWS tz=America/New_York locale=C.UTF-8
```

* Lines 2 through 4 must be sorted by the original UTC timestamp ascending.
* Each alert line must use this exact pipe-delimited format:

```text
<service>|<weekday>|<local_timestamp>|severity=<severity>
```

Where:

* `<service>` and `<severity>` come from `/home/user/monitoring/data/alert_windows.csv`.
* `<weekday>` is the English abbreviated weekday name produced for the converted local time, such as `Mon`, `Tue`, etc.
* `<local_timestamp>` must be the UTC timestamp converted to the `America/New_York` time zone and formatted exactly as:

```text
YYYY-MM-DD HH:MM EST
```

For this dataset, all rendered local timestamps should use the `EST` abbreviation.

Important verification requirement: do not treat a successful command exit as sufficient. The existing renderer may run cleanly while producing an artifact in the wrong time zone or locale. Before finishing, inspect `/home/user/monitoring/out/alert_windows.log` and make sure the header and every rendered timestamp match the required time zone, locale, sort order, and format above.

You may update files under `/home/user/monitoring` as needed, including the renderer or its environment/configuration files, but do not use root-level system time zone or locale changes. Stop when the final log file exists and its contents satisfy the specification exactly.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_2f084179"
description = "You are helping a monitoring specialist prepare alert-window text that will be consumed by an older pager integration. Work in the existing writable project directory `/home/user/monitoring`."
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 -eux

    apt-get update
    DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
        python3 \
        python3-pip \
        python3-pytest \
        tzdata \
        ca-certificates
    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/monitoring/data
    mkdir -p /home/user/monitoring/out

    cat > /home/user/monitoring/data/alert_windows.csv <<'EOF'
service,utc_start,severity
checkout-api,2026-01-12T14:30:00Z,page
billing-worker,2026-01-12T16:00:00Z,ticket
search-indexer,2026-01-13T02:15:00Z,page
EOF

    cat > /home/user/monitoring/alert_env.conf <<'EOF'
ALERT_TZ=UTC
ALERT_LOCALE=C
EOF

    cat > /home/user/monitoring/render_alerts.py <<'EOF'
#!/usr/bin/env python3
import csv
import os
from datetime import datetime
from pathlib import Path
from zoneinfo import ZoneInfo
import locale

BASE = Path("/home/user/monitoring")
DATA = BASE / "data" / "alert_windows.csv"
OUT = BASE / "out" / "alert_windows.log"
CONF = BASE / "alert_env.conf"

def load_conf(path):
    values = {}
    if path.exists():
        for raw in path.read_text().splitlines():
            raw = raw.strip()
            if not raw or raw.startswith("#") or "=" not in raw:
                continue
            k, v = raw.split("=", 1)
            values[k.strip()] = v.strip()
    return values

def main():
    conf = load_conf(CONF)

    # Intentional trap: the config file uses ALERT_TZ / ALERT_LOCALE,
    # but this renderer initially looks for TZ_NAME / LC_TIME_NAME.
    tz_name = conf.get("TZ_NAME", "UTC")
    loc_name = conf.get("LC_TIME_NAME", "C")

    try:
        locale.setlocale(locale.LC_TIME, loc_name)
    except locale.Error:
        locale.setlocale(locale.LC_TIME, "C")

    tz = ZoneInfo(tz_name)

    rows = []
    with DATA.open(newline="") as f:
        reader = csv.DictReader(f)
        for row in reader:
            dt_utc = datetime.strptime(row["utc_start"], "%Y-%m-%dT%H:%M:%SZ").replace(tzinfo=ZoneInfo("UTC"))
            local_dt = dt_utc.astimezone(tz)
            rows.append((dt_utc, row["service"], local_dt, row["severity"]))

    rows.sort(key=lambda item: item[0])

    OUT.parent.mkdir(parents=True, exist_ok=True)
    with OUT.open("w", encoding="utf-8") as f:
        f.write(f"ALERT_WINDOWS tz={tz_name} locale={loc_name}\n")
        for _, service, local_dt, severity in rows:
            weekday = local_dt.strftime("%a")
            stamp = local_dt.strftime("%Y-%m-%d %H:%M %Z")
            f.write(f"{service}|{weekday}|{stamp}|severity={severity}\n")

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

    chown -R user:user /home/user/monitoring
    chmod -R u+rwX,go+rX /home/user/monitoring
    chmod +x /home/user/monitoring/render_alerts.py

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

# test_final_state.py
import csv
import re
from datetime import datetime
from pathlib import Path
from zoneinfo import ZoneInfo

import pytest

BASE = Path("/home/user/monitoring")
CSV_PATH = Path("/home/user/monitoring/data/alert_windows.csv")
OUT_PATH = Path("/home/user/monitoring/out/alert_windows.log")

EXPECTED_BYTES = (
    b"ALERT_WINDOWS tz=America/New_York locale=C.UTF-8\n"
    b"checkout-api|Mon|2026-01-12 09:30 EST|severity=page\n"
    b"billing-worker|Mon|2026-01-12 11:00 EST|severity=ticket\n"
    b"search-indexer|Mon|2026-01-12 21:15 EST|severity=page\n"
)

EXPECTED_TEXT = EXPECTED_BYTES.decode("utf-8")
EXPECTED_LINES = EXPECTED_TEXT.splitlines()

HEADER = "ALERT_WINDOWS tz=America/New_York locale=C.UTF-8"
ALERT_LINE_RE = re.compile(
    r"^(?P<service>[^|]+)\|"
    r"(?P<weekday>Mon|Tue|Wed|Thu|Fri|Sat|Sun)\|"
    r"(?P<stamp>\d{4}-\d{2}-\d{2} \d{2}:\d{2} EST)\|"
    r"severity=(?P<severity>[^|]+)$"
)

def _read_output_bytes() -> bytes:
    assert OUT_PATH.exists(), (
        f"Required final artifact is missing: {OUT_PATH}. "
        "Run/fix the renderer so it creates this file."
    )
    assert OUT_PATH.is_file(), f"Required final artifact is not a regular file: {OUT_PATH}"
    return OUT_PATH.read_bytes()

def _read_output_text() -> str:
    data = _read_output_bytes()
    try:
        return data.decode("utf-8")
    except UnicodeDecodeError as exc:
        pytest.fail(f"{OUT_PATH} must be plain UTF-8 text, but decoding failed: {exc}")

def _source_rows_sorted_by_utc():
    assert CSV_PATH.exists(), f"Source CSV is missing: {CSV_PATH}"
    assert CSV_PATH.is_file(), f"Source CSV path is not a regular file: {CSV_PATH}"

    with CSV_PATH.open(newline="", encoding="utf-8") as f:
        rows = list(csv.DictReader(f))

    required_columns = {"service", "utc_start", "severity"}
    assert rows, f"{CSV_PATH} must contain the source alert rows"
    for index, row in enumerate(rows, start=2):
        missing = required_columns - set(row)
        assert not missing, (
            f"{CSV_PATH} row {index} is missing required column(s): {sorted(missing)}"
        )
        assert row["service"], f"{CSV_PATH} row {index} has an empty service"
        assert row["utc_start"], f"{CSV_PATH} row {index} has an empty utc_start"
        assert row["severity"], f"{CSV_PATH} row {index} has an empty severity"

    def parse_utc(row):
        return datetime.strptime(row["utc_start"], "%Y-%m-%dT%H:%M:%SZ").replace(
            tzinfo=ZoneInfo("UTC")
        )

    return sorted(((parse_utc(row), row) for row in rows), key=lambda item: item[0])

def _expected_lines_from_source():
    lines = [HEADER]
    ny_tz = ZoneInfo("America/New_York")
    for dt_utc, row in _source_rows_sorted_by_utc():
        local_dt = dt_utc.astimezone(ny_tz)
        weekday = local_dt.strftime("%a")
        stamp = local_dt.strftime("%Y-%m-%d %H:%M %Z")
        lines.append(f"{row['service']}|{weekday}|{stamp}|severity={row['severity']}")
    return lines

def test_final_artifact_exists_and_is_utf8_text() -> None:
    text = _read_output_text()
    assert text, f"{OUT_PATH} exists but is empty"

def test_final_artifact_has_exact_required_bytes_including_single_trailing_newline() -> None:
    actual = _read_output_bytes()
    assert actual == EXPECTED_BYTES, (
        f"{OUT_PATH} does not match the required final artifact byte-for-byte.\n"
        "It must contain exactly:\n"
        f"{EXPECTED_TEXT!r}\n"
        "Common wrong states include UTC output, locale=C header, missing final newline, "
        "extra blank lines, or incorrectly converted New York timestamps."
    )

def test_final_artifact_line_count_header_and_blank_lines_are_correct() -> None:
    text = _read_output_text()

    assert text.endswith("\n"), f"{OUT_PATH} must end with a single trailing newline"
    assert not text.endswith("\n\n"), f"{OUT_PATH} must not contain blank lines after the last line"

    lines = text.split("\n")
    assert lines[-1] == "", (
        f"{OUT_PATH} must have exactly one trailing newline after the last required line"
    )
    content_lines = lines[:-1]

    assert len(content_lines) == 4, (
        f"{OUT_PATH} must contain exactly 4 non-empty content lines; "
        f"found {len(content_lines)} content line(s): {content_lines!r}"
    )

    empty_line_numbers = [
        line_number for line_number, line in enumerate(content_lines, start=1) if line == ""
    ]
    assert not empty_line_numbers, (
        f"{OUT_PATH} must not contain blank lines before or between required lines; "
        f"blank content line(s): {empty_line_numbers}"
    )

    assert content_lines[0] == HEADER, (
        f"Line 1 of {OUT_PATH} is wrong. Expected exactly {HEADER!r}, "
        f"found {content_lines[0]!r}. The artifact must use tz=America/New_York "
        "and locale=C.UTF-8."
    )

def test_alert_lines_have_required_pipe_delimited_format() -> None:
    lines = _read_output_text().splitlines()
    assert len(lines) >= 4, (
        f"{OUT_PATH} must have header plus 3 alert lines before format can be checked"
    )

    for line_number, line in enumerate(lines[1:], start=2):
        match = ALERT_LINE_RE.match(line)
        assert match is not None, (
            f"Line {line_number} of {OUT_PATH} has the wrong format: {line!r}. "
            "Expected '<service>|<weekday>|YYYY-MM-DD HH:MM EST|severity=<severity>' "
            "with English abbreviated weekday and EST timezone abbreviation."
        )

def test_alert_lines_are_sorted_by_original_utc_and_semantically_correct() -> None:
    actual_lines = _read_output_text().splitlines()
    expected_lines = _expected_lines_from_source()

    assert actual_lines == expected_lines, (
        f"{OUT_PATH} does not correctly render the source CSV sorted by original UTC "
        "timestamp and converted to America/New_York with EST timestamps.\n"
        f"Expected lines: {expected_lines!r}\n"
        f"Actual lines:   {actual_lines!r}"
    )

def test_no_utc_or_wrong_locale_false_success_remains_in_artifact() -> None:
    text = _read_output_text()

    assert "tz=UTC" not in text, (
        f"{OUT_PATH} still appears to contain the initial false-success UTC header/output"
    )
    assert "locale=C\n" not in text and "locale=C\r\n" not in text, (
        f"{OUT_PATH} still appears to contain the wrong locale=C header; "
        "it must be locale=C.UTF-8"
    )
    assert " UTC" not in text, (
        f"{OUT_PATH} still contains UTC timestamps; all rendered timestamps must be "
        "converted to America/New_York and end in EST"
    )
    assert "search-indexer|Tue|" not in text, (
        f"{OUT_PATH} still contains the UTC weekday for search-indexer. "
        "After conversion to America/New_York it must be Monday."
    )