You are helping as a build engineer triage a release staging area. All files are under `/home/user/artifact_triage`, and you have write permission there. The staging area contains several candidate build directories under `/home/user/artifact_triage/candidates/`, plus policy/reference files under `/home/user/artifact_triage/policy/`.

Your goal is to identify the single candidate artifact set that is eligible for promotion, then produce two small text outputs with a disciplined evidence trail. This is intentionally a diagnosis task: several candidates look plausible, but each one should be eliminated or retained using concrete evidence from the files. Please avoid guessing from filenames alone.

Inputs available to inspect:

- `/home/user/artifact_triage/policy/release_policy.txt`
- `/home/user/artifact_triage/policy/expected_components.tsv`
- `/home/user/artifact_triage/candidates/*/manifest.txt`
- `/home/user/artifact_triage/candidates/*/checksums.sha256`
- `/home/user/artifact_triage/candidates/*/build.log`

A candidate is eligible only if all of the following are true:

1. Its `manifest.txt` contains `channel=stable`.
2. Its `manifest.txt` contains `signed=yes`.
3. Its `manifest.txt` contains `qa_status=pass`.
4. Its `manifest.txt` contains `schema_version=3`.
5. Its `manifest.txt` contains a `commit=` value that matches the allowed release commit specified in `/home/user/artifact_triage/policy/release_policy.txt`.
6. The component names and versions in its `manifest.txt` exactly match `/home/user/artifact_triage/policy/expected_components.tsv`.
   - In the manifest, component lines use the format `component=<name>\t<version>`.
   - In the expected file, component lines use the format `<name>\t<version>`.
   - Compare the set of name/version pairs, not comments or ordering.
7. Every component listed in `manifest.txt` has a corresponding checksum entry in `checksums.sha256`.
8. Its `build.log` must not contain any error, fatal, panic, or traceback message, case-insensitively.
9. Its `build.log` must contain a line indicating that packaging completed successfully.

Create exactly these two files:

1. `/home/user/artifact_triage/promotion_decision.txt`

This file must contain exactly four lines, in this format:

```text
selected_candidate=<candidate-directory-name>
artifact_id=<artifact id from selected manifest>
commit=<commit from selected manifest>
component_count=<number of selected components>
```

The candidate directory name is the final path component under `/home/user/artifact_triage/candidates/`, for example `build-abc123`. Do not include extra spaces, quotes, comments, or blank lines.

2. `/home/user/artifact_triage/triage_progress.log`

This file must be a compact evidence log showing that you converged by eliminating candidates rather than trying unrelated checks. It must contain one line per candidate directory, sorted lexicographically by candidate directory name, followed by one final verification line.

Each candidate line must use exactly this pipe-delimited format:

```text
candidate=<candidate-directory-name>|status=<SELECTED or REJECTED>|reason=<short reason>
```

Rules for the reason field:

- For the selected candidate, use `reason=all policy checks passed`.
- For rejected candidates, use the first failing reason from this ordered list:
  1. `wrong channel`
  2. `unsigned manifest`
  3. `qa failed`
  4. `schema mismatch`
  5. `commit not allowed`
  6. `component mismatch`
  7. `missing checksum`
  8. `build log contains failure`
  9. `packaging completion missing`

The final line of `/home/user/artifact_triage/triage_progress.log` must be exactly:

```text
verification=promotion_decision_matches_selected_candidate
```

After writing the files, verify them yourself by reading them back and checking the selected candidate against the policy files. Stop once the two output files are correct.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_ec9e3257"
description = "You are helping as a build engineer triage a release staging area. All files are under `/home/user/artifact_triage`, and you have write permission there. The staging area contains several candidate build directories under `/home/user/artifa"
authors = [{ name = "Endless Terminals / Jarrod Barnes" }]
keywords = ["agentic-rl", "bounded_search_discipline", "endless-terminals", "terminal-bench-2", "wander_loop_without_convergence"]

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

[verifier]
timeout_sec = 300.0
user = "root"

[agent]
timeout_sec = 900.0
user = "user"

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

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

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

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

    mkdir -p /home/user/artifact_triage/policy
    mkdir -p /home/user/artifact_triage/candidates/build-2024.11.08-a1
    mkdir -p /home/user/artifact_triage/candidates/build-2024.11.08-b2
    mkdir -p /home/user/artifact_triage/candidates/build-2024.11.08-c3
    mkdir -p /home/user/artifact_triage/candidates/build-2024.11.08-d4
    mkdir -p /home/user/artifact_triage/candidates/build-2024.11.08-e5
    mkdir -p /home/user/artifact_triage/candidates/build-2024.11.08-f6

    cat > /home/user/artifact_triage/policy/release_policy.txt <<'EOF'
release_train=2024.11
allowed_channel=stable
allowed_commit=8f14e45fceea167a5a36dedd4bea2543
required_schema_version=3
require_signed=yes
require_qa_status=pass
EOF

    cat > /home/user/artifact_triage/policy/expected_components.tsv <<'EOF'
api-gateway	2.8.1
auth-service	5.4.0
billing-worker	1.19.7
web-console	3.12.2
EOF

    cat > /home/user/artifact_triage/candidates/build-2024.11.08-a1/manifest.txt <<'EOF'
artifact_id=rel-2024.11-a1
channel=stable
signed=yes
qa_status=pass
schema_version=3
commit=8f14e45fceea167a5a36dedd4bea2543
component=api-gateway	2.8.1
component=auth-service	5.4.0
component=billing-worker	1.19.7
component=web-console	3.12.2
EOF

    cat > /home/user/artifact_triage/candidates/build-2024.11.08-b2/manifest.txt <<'EOF'
artifact_id=rel-2024.11-b2
channel=stable
signed=yes
qa_status=pass
schema_version=3
commit=8f14e45fceea167a5a36dedd4bea2543
component=api-gateway	2.8.1
component=auth-service	5.4.0
component=billing-worker	1.19.8
component=web-console	3.12.2
EOF

    cat > /home/user/artifact_triage/candidates/build-2024.11.08-c3/manifest.txt <<'EOF'
artifact_id=rel-2024.11-c3
channel=stable
signed=yes
qa_status=pass
schema_version=3
commit=0cc175b9c0f1b6a831c399e269772661
component=api-gateway	2.8.1
component=auth-service	5.4.0
component=billing-worker	1.19.7
component=web-console	3.12.2
EOF

    cat > /home/user/artifact_triage/candidates/build-2024.11.08-d4/manifest.txt <<'EOF'
artifact_id=rel-2024.11-d4
channel=stable
signed=yes
qa_status=pass
schema_version=3
commit=8f14e45fceea167a5a36dedd4bea2543
component=api-gateway	2.8.1
component=auth-service	5.4.0
component=billing-worker	1.19.7
component=web-console	3.12.2
EOF

    cat > /home/user/artifact_triage/candidates/build-2024.11.08-e5/manifest.txt <<'EOF'
artifact_id=rel-2024.11-e5
channel=beta
signed=yes
qa_status=pass
schema_version=3
commit=8f14e45fceea167a5a36dedd4bea2543
component=api-gateway	2.8.1
component=auth-service	5.4.0
component=billing-worker	1.19.7
component=web-console	3.12.2
EOF

    cat > /home/user/artifact_triage/candidates/build-2024.11.08-f6/manifest.txt <<'EOF'
artifact_id=rel-2024.11-f6
channel=stable
signed=no
qa_status=pass
schema_version=3
commit=8f14e45fceea167a5a36dedd4bea2543
component=api-gateway	2.8.1
component=auth-service	5.4.0
component=billing-worker	1.19.7
component=web-console	3.12.2
EOF

    cat > /home/user/artifact_triage/candidates/build-2024.11.08-a1/checksums.sha256 <<'EOF'
1111111111111111111111111111111111111111111111111111111111111111  api-gateway-2.8.1.tar.gz
2222222222222222222222222222222222222222222222222222222222222222  auth-service-5.4.0.tar.gz
3333333333333333333333333333333333333333333333333333333333333333  billing-worker-1.19.7.tar.gz
4444444444444444444444444444444444444444444444444444444444444444  web-console-3.12.2.tar.gz
EOF

    cat > /home/user/artifact_triage/candidates/build-2024.11.08-b2/checksums.sha256 <<'EOF'
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa  api-gateway-2.8.1.tar.gz
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb  auth-service-5.4.0.tar.gz
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc  billing-worker-1.19.8.tar.gz
dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd  web-console-3.12.2.tar.gz
EOF

    cat > /home/user/artifact_triage/candidates/build-2024.11.08-c3/checksums.sha256 <<'EOF'
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee  api-gateway-2.8.1.tar.gz
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff  auth-service-5.4.0.tar.gz
1212121212121212121212121212121212121212121212121212121212121212  billing-worker-1.19.7.tar.gz
3434343434343434343434343434343434343434343434343434343434343434  web-console-3.12.2.tar.gz
EOF

    cat > /home/user/artifact_triage/candidates/build-2024.11.08-d4/checksums.sha256 <<'EOF'
5555555555555555555555555555555555555555555555555555555555555555  api-gateway-2.8.1.tar.gz
6666666666666666666666666666666666666666666666666666666666666666  auth-service-5.4.0.tar.gz
7777777777777777777777777777777777777777777777777777777777777777  billing-worker-1.19.7.tar.gz
EOF

    cat > /home/user/artifact_triage/candidates/build-2024.11.08-e5/checksums.sha256 <<'EOF'
8888888888888888888888888888888888888888888888888888888888888888  api-gateway-2.8.1.tar.gz
9999999999999999999999999999999999999999999999999999999999999999  auth-service-5.4.0.tar.gz
abababababababababababababababababababababababababababababababab  billing-worker-1.19.7.tar.gz
bcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbc  web-console-3.12.2.tar.gz
EOF

    cat > /home/user/artifact_triage/candidates/build-2024.11.08-f6/checksums.sha256 <<'EOF'
cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd  api-gateway-2.8.1.tar.gz
dededededededededededededededededededededededededededededededede  auth-service-5.4.0.tar.gz
efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef  billing-worker-1.19.7.tar.gz
fafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafa  web-console-3.12.2.tar.gz
EOF

    cat > /home/user/artifact_triage/candidates/build-2024.11.08-a1/build.log <<'EOF'
2024-11-08T10:14:01Z INFO starting release build
2024-11-08T10:16:22Z INFO tests completed
2024-11-08T10:18:45Z INFO packaging completed successfully
2024-11-08T10:18:49Z INFO uploaded artifacts to staging
EOF

    cat > /home/user/artifact_triage/candidates/build-2024.11.08-b2/build.log <<'EOF'
2024-11-08T10:21:01Z INFO starting release build
2024-11-08T10:23:17Z INFO tests completed
2024-11-08T10:25:03Z INFO packaging completed successfully
EOF

    cat > /home/user/artifact_triage/candidates/build-2024.11.08-c3/build.log <<'EOF'
2024-11-08T10:31:09Z INFO starting release build
2024-11-08T10:35:44Z INFO tests completed
2024-11-08T10:38:11Z INFO packaging completed successfully
EOF

    cat > /home/user/artifact_triage/candidates/build-2024.11.08-d4/build.log <<'EOF'
2024-11-08T10:41:02Z INFO starting release build
2024-11-08T10:44:29Z INFO tests completed
2024-11-08T10:47:53Z INFO packaging completed successfully
EOF

    cat > /home/user/artifact_triage/candidates/build-2024.11.08-e5/build.log <<'EOF'
2024-11-08T10:51:07Z INFO starting release build
2024-11-08T10:54:26Z INFO tests completed
2024-11-08T10:57:39Z INFO packaging completed successfully
EOF

    cat > /home/user/artifact_triage/candidates/build-2024.11.08-f6/build.log <<'EOF'
2024-11-08T11:01:07Z INFO starting release build
2024-11-08T11:04:26Z INFO tests completed
2024-11-08T11:07:39Z INFO packaging completed successfully
EOF

    chown -R user:user /home/user/artifact_triage
    chmod -R u+rwX,go+rX /home/user/artifact_triage
    find /home/user/artifact_triage -type d -exec chmod 755 {} \;
    find /home/user/artifact_triage -type f -exec chmod 644 {} \;

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

# test_final_state.py
from pathlib import Path
import re

ROOT = Path("/home/user/artifact_triage")
POLICY = Path("/home/user/artifact_triage/policy")
CANDIDATES = Path("/home/user/artifact_triage/candidates")
PROMOTION_DECISION = Path("/home/user/artifact_triage/promotion_decision.txt")
TRIAGE_PROGRESS = Path("/home/user/artifact_triage/triage_progress.log")

EXPECTED_PROMOTION_DECISION = (
    "selected_candidate=build-2024.11.08-a1\n"
    "artifact_id=rel-2024.11-a1\n"
    "commit=8f14e45fceea167a5a36dedd4bea2543\n"
    "component_count=4\n"
)

EXPECTED_TRIAGE_PROGRESS = (
    "candidate=build-2024.11.08-a1|status=SELECTED|reason=all policy checks passed\n"
    "candidate=build-2024.11.08-b2|status=REJECTED|reason=component mismatch\n"
    "candidate=build-2024.11.08-c3|status=REJECTED|reason=commit not allowed\n"
    "candidate=build-2024.11.08-d4|status=REJECTED|reason=missing checksum\n"
    "candidate=build-2024.11.08-e5|status=REJECTED|reason=wrong channel\n"
    "candidate=build-2024.11.08-f6|status=REJECTED|reason=unsigned manifest\n"
    "verification=promotion_decision_matches_selected_candidate\n"
)

EXPECTED_CANDIDATES = [
    "build-2024.11.08-a1",
    "build-2024.11.08-b2",
    "build-2024.11.08-c3",
    "build-2024.11.08-d4",
    "build-2024.11.08-e5",
    "build-2024.11.08-f6",
]

EXPECTED_COMPONENTS = {
    ("api-gateway", "2.8.1"),
    ("auth-service", "5.4.0"),
    ("billing-worker", "1.19.7"),
    ("web-console", "3.12.2"),
}

ALLOWED_COMMIT = "8f14e45fceea167a5a36dedd4bea2543"

def _read_text(path: Path) -> str:
    assert path.exists(), f"Required output file is missing: {path}"
    assert path.is_file(), f"Required output path is not a regular file: {path}"
    return path.read_text(encoding="utf-8")

def _parse_key_value_lines(text: str, path: Path) -> dict:
    result = {}
    for line_number, line in enumerate(text.splitlines(), start=1):
        assert "=" in line, f"{path} line {line_number} is not a key=value line: {line!r}"
        key, value = line.split("=", 1)
        assert key, f"{path} line {line_number} has an empty key"
        assert key not in result, f"{path} repeats key {key!r}"
        result[key] = value
    return result

def _parse_manifest(candidate_name: str) -> tuple[dict, set[tuple[str, str]]]:
    manifest_path = CANDIDATES / candidate_name / "manifest.txt"
    assert manifest_path.exists(), f"Selected candidate manifest is missing: {manifest_path}"
    lines = manifest_path.read_text(encoding="utf-8").splitlines()

    fields = {}
    components = set()
    for line in lines:
        if line.startswith("component="):
            component_value = line[len("component="):]
            assert "\t" in component_value, (
                f"Manifest component line in {manifest_path} is not tab-delimited: {line!r}"
            )
            name, version = component_value.split("\t", 1)
            components.add((name, version))
        else:
            assert "=" in line, f"Manifest line in {manifest_path} is not key=value: {line!r}"
            key, value = line.split("=", 1)
            fields[key] = value
    return fields, components

def _checksum_filenames(candidate_name: str) -> set[str]:
    checksum_path = CANDIDATES / candidate_name / "checksums.sha256"
    assert checksum_path.exists(), f"Checksum file is missing: {checksum_path}"
    filenames = set()
    for line_number, line in enumerate(checksum_path.read_text(encoding="utf-8").splitlines(), start=1):
        parts = line.split()
        assert len(parts) >= 2, f"Malformed checksum line {line_number} in {checksum_path}: {line!r}"
        filenames.add(parts[-1])
    return filenames

def test_required_output_files_exist_and_are_exact():
    promotion_text = _read_text(PROMOTION_DECISION)
    triage_text = _read_text(TRIAGE_PROGRESS)

    assert promotion_text == EXPECTED_PROMOTION_DECISION, (
        f"{PROMOTION_DECISION} does not exactly match the required final contents.\n"
        f"Expected:\n{EXPECTED_PROMOTION_DECISION!r}\n"
        f"Actual:\n{promotion_text!r}"
    )
    assert triage_text == EXPECTED_TRIAGE_PROGRESS, (
        f"{TRIAGE_PROGRESS} does not exactly match the required final contents, including "
        f"candidate order, first-failure rejection reasons, and final verification line.\n"
        f"Expected:\n{EXPECTED_TRIAGE_PROGRESS!r}\n"
        f"Actual:\n{triage_text!r}"
    )

def test_promotion_decision_has_exact_four_lines_no_extra_content():
    text = _read_text(PROMOTION_DECISION)
    lines = text.splitlines()

    assert text.endswith("\n"), f"{PROMOTION_DECISION} must end after the fourth line with a newline"
    assert len(lines) == 4, (
        f"{PROMOTION_DECISION} must contain exactly four lines and no extra content; "
        f"found {len(lines)} lines: {lines!r}"
    )
    assert all(line.strip() == line and line for line in lines), (
        f"{PROMOTION_DECISION} must not contain blank lines or leading/trailing spaces: {lines!r}"
    )

    expected_keys = ["selected_candidate", "artifact_id", "commit", "component_count"]
    actual_keys = [line.split("=", 1)[0] if "=" in line else line for line in lines]
    assert actual_keys == expected_keys, (
        f"{PROMOTION_DECISION} keys must be exactly {expected_keys} in order; found {actual_keys}"
    )

def test_triage_progress_has_exact_candidate_lines_sorted_and_verification_line():
    text = _read_text(TRIAGE_PROGRESS)
    lines = text.splitlines()

    assert text.endswith("\n"), f"{TRIAGE_PROGRESS} must end after the verification line with a newline"
    assert len(lines) == 7, (
        f"{TRIAGE_PROGRESS} must contain exactly six candidate lines plus one verification line; "
        f"found {len(lines)} lines: {lines!r}"
    )
    assert all(line.strip() == line and line for line in lines), (
        f"{TRIAGE_PROGRESS} must not contain blank lines or leading/trailing spaces: {lines!r}"
    )
    assert lines[-1] == "verification=promotion_decision_matches_selected_candidate", (
        f"The final line of {TRIAGE_PROGRESS} is wrong: {lines[-1]!r}"
    )

    candidate_pattern = re.compile(
        r"^candidate=([^|]+)\|status=(SELECTED|REJECTED)\|reason=(.+)$"
    )
    parsed_names = []
    selected_names = []

    for index, line in enumerate(lines[:-1], start=1):
        match = candidate_pattern.fullmatch(line)
        assert match, (
            f"{TRIAGE_PROGRESS} line {index} does not use the exact required "
            f"pipe-delimited candidate format: {line!r}"
        )
        name, status, reason = match.groups()
        parsed_names.append(name)
        if status == "SELECTED":
            selected_names.append(name)
            assert reason == "all policy checks passed", (
                f"Selected candidate {name} must use reason='all policy checks passed', "
                f"but used {reason!r}"
            )

    assert parsed_names == sorted(parsed_names), (
        f"Candidate lines in {TRIAGE_PROGRESS} must be sorted lexicographically by candidate name; "
        f"found order {parsed_names}"
    )
    assert parsed_names == EXPECTED_CANDIDATES, (
        f"{TRIAGE_PROGRESS} must contain exactly the expected candidate directories and no extras; "
        f"expected {EXPECTED_CANDIDATES}, found {parsed_names}"
    )
    assert selected_names == ["build-2024.11.08-a1"], (
        f"Exactly build-2024.11.08-a1 must be selected; selected candidates found: {selected_names}"
    )

def test_selected_candidate_decision_matches_manifest_policy_components_and_checksums():
    decision = _parse_key_value_lines(_read_text(PROMOTION_DECISION), PROMOTION_DECISION)

    selected = decision.get("selected_candidate")
    assert selected == "build-2024.11.08-a1", (
        f"Wrong selected candidate in {PROMOTION_DECISION}: expected build-2024.11.08-a1, "
        f"found {selected!r}"
    )

    selected_dir = CANDIDATES / selected
    assert selected_dir.exists(), f"Selected candidate directory does not exist: {selected_dir}"
    assert selected_dir.is_dir(), f"Selected candidate path is not a directory: {selected_dir}"

    fields, components = _parse_manifest(selected)

    assert decision.get("artifact_id") == fields.get("artifact_id") == "rel-2024.11-a1", (
        f"artifact_id in {PROMOTION_DECISION} must match selected manifest artifact_id "
        f"rel-2024.11-a1; decision={decision.get('artifact_id')!r}, "
        f"manifest={fields.get('artifact_id')!r}"
    )
    assert decision.get("commit") == fields.get("commit") == ALLOWED_COMMIT, (
        f"commit in {PROMOTION_DECISION} must match selected manifest and allowed policy commit "
        f"{ALLOWED_COMMIT}; decision={decision.get('commit')!r}, manifest={fields.get('commit')!r}"
    )
    assert decision.get("component_count") == "4", (
        f"component_count in {PROMOTION_DECISION} must be 4; found {decision.get('component_count')!r}"
    )

    assert fields.get("channel") == "stable", f"Selected manifest still has wrong channel: {fields.get('channel')!r}"
    assert fields.get("signed") == "yes", f"Selected manifest is not signed: {fields.get('signed')!r}"
    assert fields.get("qa_status") == "pass", f"Selected manifest QA status is not pass: {fields.get('qa_status')!r}"
    assert fields.get("schema_version") == "3", (
        f"Selected manifest schema_version is not 3: {fields.get('schema_version')!r}"
    )
    assert components == EXPECTED_COMPONENTS, (
        f"Selected manifest components do not match policy expected components; "
        f"expected {sorted(EXPECTED_COMPONENTS)}, found {sorted(components)}"
    )

    checksum_names = _checksum_filenames(selected)
    expected_artifact_names = {f"{name}-{version}.tar.gz" for name, version in components}
    missing = expected_artifact_names - checksum_names
    assert not missing, (
        f"Selected candidate {selected} is missing checksum entries for component artifacts: "
        f"{sorted(missing)}"
    )

    build_log_path = CANDIDATES / selected / "build.log"
    build_log = build_log_path.read_text(encoding="utf-8")
    lowered = build_log.lower()
    forbidden_terms = ["error", "fatal", "panic", "traceback"]
    present_forbidden = [term for term in forbidden_terms if term in lowered]
    assert not present_forbidden, (
        f"Selected candidate build log {build_log_path} contains forbidden failure terms: "
        f"{present_forbidden}"
    )
    assert any("packaging completed successfully" in line.lower() for line in build_log.splitlines()), (
        f"Selected candidate build log {build_log_path} lacks packaging completion success line"
    )

def test_policy_files_still_support_the_recorded_decision():
    release_policy_path = POLICY / "release_policy.txt"
    expected_components_path = POLICY / "expected_components.tsv"

    assert release_policy_path.exists(), f"Policy file is missing: {release_policy_path}"
    assert expected_components_path.exists(), f"Expected components file is missing: {expected_components_path}"

    policy = _parse_key_value_lines(release_policy_path.read_text(encoding="utf-8"), release_policy_path)
    assert policy.get("allowed_commit") == ALLOWED_COMMIT, (
        f"{release_policy_path} allowed_commit should be {ALLOWED_COMMIT}, "
        f"found {policy.get('allowed_commit')!r}"
    )
    assert policy.get("allowed_channel") == "stable", (
        f"{release_policy_path} allowed_channel should be stable, found {policy.get('allowed_channel')!r}"
    )
    assert policy.get("required_schema_version") == "3", (
        f"{release_policy_path} required_schema_version should be 3, "
        f"found {policy.get('required_schema_version')!r}"
    )
    assert policy.get("require_signed") == "yes", (
        f"{release_policy_path} require_signed should be yes, found {policy.get('require_signed')!r}"
    )
    assert policy.get("require_qa_status") == "pass", (
        f"{release_policy_path} require_qa_status should be pass, "
        f"found {policy.get('require_qa_status')!r}"
    )

    actual_components = set()
    for line_number, line in enumerate(expected_components_path.read_text(encoding="utf-8").splitlines(), start=1):
        assert "\t" in line, (
            f"{expected_components_path} line {line_number} must be tab-delimited name/version: {line!r}"
        )
        name, version = line.split("\t", 1)
        actual_components.add((name, version))

    assert actual_components == EXPECTED_COMPONENTS, (
        f"{expected_components_path} no longer contains the expected component set; "
        f"expected {sorted(EXPECTED_COMPONENTS)}, found {sorted(actual_components)}"
    )

def test_no_extra_top_level_deliverables_were_created():
    allowed_top_level_names = {
        "policy",
        "candidates",
        "promotion_decision.txt",
        "triage_progress.log",
    }
    assert ROOT.exists(), f"Required task root is missing: {ROOT}"
    actual_top_level_names = {path.name for path in ROOT.iterdir()}
    unexpected = sorted(actual_top_level_names - allowed_top_level_names)
    assert not unexpected, (
        f"Unexpected extra top-level deliverables exist under {ROOT}: {unexpected}. "
        f"The task requires only promotion_decision.txt and triage_progress.log."
    )


You are helping a deployment engineer prepare a small rollout manifest from a tab-separated deployment plan.

The input file already exists at:

`/home/user/deploy/rollout_plan.tsv`

It is a TSV file with a header row and these columns in this exact order:

`ticket`, `service`, `version`, `region`, `canary_percent`, `owner`

Create a deployment manifest at:

`/home/user/deploy/manifest.tsv`

The manifest must be a tab-separated file containing exactly these three columns, in this exact order:

`service`, `region`, `version`

Requirements:

1. The output file `/home/user/deploy/manifest.tsv` must include a header row exactly equal to:
   `service<TAB>region<TAB>version`

2. The data rows must be copied from `/home/user/deploy/rollout_plan.tsv`.

3. Preserve the original row order from the input file.

4. Do not include the `ticket`, `canary_percent`, or `owner` columns.

5. Because this manifest will be consumed by an automated deploy step, verify the artifact before finishing:
   - Confirm the file exists.
   - Confirm it has the same number of lines as the input file.
   - Confirm the header is exactly `service<TAB>region<TAB>version`.
   - Confirm every data row has exactly 3 tab-separated fields.

6. Write a verification log at:

`/home/user/deploy/manifest_check.log`

The log must contain exactly four lines, in this exact format:

`exists: yes`
`line_count_matches: yes`
`header_ok: yes`
`field_count_ok: yes`

Only finish once both `/home/user/deploy/manifest.tsv` and `/home/user/deploy/manifest_check.log` meet the requirements above.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_eedaab53"
description = "You are helping a deployment engineer prepare a small rollout manifest from a tab-separated deployment plan."
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 \
        coreutils \
        gawk \
        sed \
        grep

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

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

    cat > /home/user/deploy/rollout_plan.tsv <<'EOF'
ticket	service	version	region	canary_percent	owner
DEP-1042	auth-api	2024.11.7	us-east-1	10	alina
DEP-1043	billing-worker	2024.11.3	eu-west-1	25	marco
DEP-1044	catalog-web	2024.12.1	ap-southeast-2	15	jules
DEP-1045	search-api	2024.10.9	us-west-2	20	renee
EOF

    rm -f /home/user/deploy/manifest.tsv /home/user/deploy/manifest_check.log

    chown -R user:user /home/user
    chmod 755 /home/user
    chmod 755 /home/user/deploy
    chmod 644 /home/user/deploy/rollout_plan.tsv

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

# test_final_state.py
from pathlib import Path

DEPLOY_DIR = Path("/home/user/deploy")
ROLLOUT_PLAN = Path("/home/user/deploy/rollout_plan.tsv")
MANIFEST = Path("/home/user/deploy/manifest.tsv")
MANIFEST_LOG = Path("/home/user/deploy/manifest_check.log")

EXPECTED_ROLLOUT_PLAN = (
    "ticket\tservice\tversion\tregion\tcanary_percent\towner\n"
    "DEP-1042\tauth-api\t2024.11.7\tus-east-1\t10\talina\n"
    "DEP-1043\tbilling-worker\t2024.11.3\teu-west-1\t25\tmarco\n"
    "DEP-1044\tcatalog-web\t2024.12.1\tap-southeast-2\t15\tjules\n"
    "DEP-1045\tsearch-api\t2024.10.9\tus-west-2\t20\trenee\n"
)

EXPECTED_MANIFEST = (
    "service\tregion\tversion\n"
    "auth-api\tus-east-1\t2024.11.7\n"
    "billing-worker\teu-west-1\t2024.11.3\n"
    "catalog-web\tap-southeast-2\t2024.12.1\n"
    "search-api\tus-west-2\t2024.10.9\n"
)

EXPECTED_LOG = (
    "exists: yes\n"
    "line_count_matches: yes\n"
    "header_ok: yes\n"
    "field_count_ok: yes\n"
)

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

def test_required_paths_exist_and_are_files():
    assert DEPLOY_DIR.exists(), f"Missing required directory: {DEPLOY_DIR}"
    assert DEPLOY_DIR.is_dir(), f"Required path is not a directory: {DEPLOY_DIR}"

    assert ROLLOUT_PLAN.exists(), f"Missing input file needed for verification: {ROLLOUT_PLAN}"
    assert ROLLOUT_PLAN.is_file(), f"Input path exists but is not a file: {ROLLOUT_PLAN}"

    assert MANIFEST.exists(), f"Manifest was not created at required path: {MANIFEST}"
    assert MANIFEST.is_file(), f"Manifest path exists but is not a file: {MANIFEST}"

    assert MANIFEST_LOG.exists(), f"Verification log was not created at required path: {MANIFEST_LOG}"
    assert MANIFEST_LOG.is_file(), f"Verification log path exists but is not a file: {MANIFEST_LOG}"

def test_input_rollout_plan_remains_expected():
    actual = _read_text(ROLLOUT_PLAN)
    assert actual == EXPECTED_ROLLOUT_PLAN, (
        f"The input rollout plan at {ROLLOUT_PLAN} no longer matches the expected source data. "
        "The manifest should be generated from the given input without altering it."
    )

def test_manifest_exact_byte_for_byte_contents():
    actual = _read_text(MANIFEST)
    assert actual == EXPECTED_MANIFEST, (
        f"{MANIFEST} does not exactly match the required manifest contents. "
        "It must contain only service, region, and version columns in that order, "
        "preserve input row order, use tabs as separators, and have no extra or missing lines."
    )

def test_manifest_header_is_exact_and_columns_are_reordered_correctly():
    lines = _read_text(MANIFEST).splitlines()
    assert lines, f"{MANIFEST} is empty; it must include a header and data rows."

    expected_header = "service\tregion\tversion"
    assert lines[0] == expected_header, (
        f"Manifest header is wrong. Expected exactly {expected_header!r}, got {lines[0]!r}. "
        "A common mistake is producing service/version/region instead of service/region/version."
    )

    expected_rows = [
        ["auth-api", "us-east-1", "2024.11.7"],
        ["billing-worker", "eu-west-1", "2024.11.3"],
        ["catalog-web", "ap-southeast-2", "2024.12.1"],
        ["search-api", "us-west-2", "2024.10.9"],
    ]
    actual_rows = [line.split("\t") for line in lines[1:]]
    assert actual_rows == expected_rows, (
        f"Manifest data rows are not the expected service, region, version values in original order. "
        f"Expected {expected_rows!r}, got {actual_rows!r}."
    )

def test_manifest_line_count_matches_input_line_count():
    input_lines = _read_text(ROLLOUT_PLAN).splitlines()
    manifest_lines = _read_text(MANIFEST).splitlines()

    assert len(manifest_lines) == len(input_lines), (
        f"{MANIFEST} should have the same number of lines as {ROLLOUT_PLAN}. "
        f"Expected {len(input_lines)} lines, found {len(manifest_lines)}."
    )
    assert len(manifest_lines) == 5, (
        f"{MANIFEST} should contain exactly 5 lines including the header, "
        f"but found {len(manifest_lines)}."
    )

def test_manifest_every_line_has_exactly_three_tab_separated_fields():
    lines = _read_text(MANIFEST).splitlines()

    for line_number, line in enumerate(lines, start=1):
        fields = line.split("\t")
        assert len(fields) == 3, (
            f"Line {line_number} of {MANIFEST} should have exactly 3 tab-separated fields, "
            f"but found {len(fields)} fields in {line!r}."
        )
        assert all(field != "" for field in fields), (
            f"Line {line_number} of {MANIFEST} contains an empty field: {line!r}."
        )

def test_manifest_contains_tabs_not_space_separated_columns():
    lines = _read_text(MANIFEST).splitlines()

    for line_number, line in enumerate(lines, start=1):
        assert "\t" in line, (
            f"Line {line_number} of {MANIFEST} does not contain tab separators: {line!r}."
        )

    assert "service region version" not in _read_text(MANIFEST), (
        f"{MANIFEST} appears to contain spaces instead of tabs in the header."
    )

def test_manifest_check_log_exact_contents():
    actual = _read_text(MANIFEST_LOG)
    assert actual == EXPECTED_LOG, (
        f"{MANIFEST_LOG} does not exactly match the required verification log. "
        "It must contain exactly four lines, all marked 'yes', in the required order."
    )

def test_manifest_check_log_shape_and_no_extra_lines():
    lines = _read_text(MANIFEST_LOG).splitlines()
    expected_lines = [
        "exists: yes",
        "line_count_matches: yes",
        "header_ok: yes",
        "field_count_ok: yes",
    ]

    assert lines == expected_lines, (
        f"Verification log lines are incorrect. Expected exactly {expected_lines!r}, got {lines!r}."
    )
    assert len(lines) == 4, (
        f"{MANIFEST_LOG} should contain exactly 4 lines, but found {len(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 acting as a build engineer cleaning up a local artifact handoff area. The project currently has build artifacts under an old staging path, but the canonical artifact location has changed. Please perform the migration using terminal file operations appropriate for batch artifact handling, ideally using `find` and `xargs`.

Initial public paths:

- Old artifact source directory: `/home/user/build_staging/legacy_artifacts`
- New canonical artifact directory: `/home/user/build_staging/release_artifacts`
- Verification log to create: `/home/user/build_staging/artifact_migration.log`

What needs to be done:

1. Move every regular file whose filename ends in `.tar.gz` from `/home/user/build_staging/legacy_artifacts` into `/home/user/build_staging/release_artifacts`.
   - Preserve each artifact filename exactly.
   - Do not move non-`.tar.gz` files.
   - Do not copy the artifacts; the old artifact path must no longer contain those `.tar.gz` files after the migration.
   - The new canonical directory must contain the migrated artifacts.

2. After the migration, create `/home/user/build_staging/artifact_migration.log`.
   - This log must reflect the final state of the new canonical artifact directory, not the old legacy directory.
   - The automated checker will verify the log format exactly.

The log file must contain exactly these three lines:

```text
SOURCE_RETIRED=<number>
DESTINATION_COUNT=<number>
DESTINATION_FILES=<comma-separated filenames>
```

Formatting requirements:

- `SOURCE_RETIRED` must be `yes` if `/home/user/build_staging/legacy_artifacts` contains zero `.tar.gz` files after migration; otherwise it must be `no`.
- `DESTINATION_COUNT` must be the number of `.tar.gz` files present directly inside `/home/user/build_staging/release_artifacts` after migration.
- `DESTINATION_FILES` must list the `.tar.gz` filenames present directly inside `/home/user/build_staging/release_artifacts` after migration.
- The filenames in `DESTINATION_FILES` must be sorted in bytewise/alphabetical order.
- The filenames must be separated by commas with no spaces.
- If there are no destination `.tar.gz` files, `DESTINATION_FILES` must be empty after the equals sign.
- The log must not include extra blank lines or extra text.

Before you finish, verify the final state from `/home/user/build_staging/release_artifacts`, not from `/home/user/build_staging/legacy_artifacts`.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_f39ed43d"
description = "You are acting as a build engineer cleaning up a local artifact handoff area. The project currently has build artifacts under an old staging path, but the canonical artifact location has changed. Please perform the migration using terminal "
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 \
        findutils \
        coreutils \
        passwd \
        ca-certificates

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

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

    mkdir -p /home/user/build_staging/legacy_artifacts
    mkdir -p /home/user/build_staging/release_artifacts
    mkdir -p /home/user/build_staging/tmp

    printf 'artifact api-server 1.4.2 linux amd64\n' > /home/user/build_staging/legacy_artifacts/api-server-1.4.2-linux-amd64.tar.gz
    printf 'artifact api-server 1.4.2 linux arm64\n' > /home/user/build_staging/legacy_artifacts/api-server-1.4.2-linux-arm64.tar.gz
    printf 'artifact worker 1.4.2 linux amd64\n' > /home/user/build_staging/legacy_artifacts/worker-1.4.2-linux-amd64.tar.gz
    printf 'artifact worker 1.4.2 linux arm64\n' > /home/user/build_staging/legacy_artifacts/worker-1.4.2-linux-arm64.tar.gz
    printf 'legacy checksum file - do not migrate\n' > /home/user/build_staging/legacy_artifacts/checksums.txt
    printf '# Build notes\nThese notes stay in the legacy directory.\n' > /home/user/build_staging/legacy_artifacts/build-notes.md

    chown -R user:user /home/user/build_staging
    chmod -R u+rwX,go+rX /home/user/build_staging
    chmod u+w /home/user/build_staging /home/user/build_staging/legacy_artifacts /home/user/build_staging/release_artifacts /home/user/build_staging/tmp

    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

BASE = Path("/home/user/build_staging")
LEGACY = Path("/home/user/build_staging/legacy_artifacts")
RELEASE = Path("/home/user/build_staging/release_artifacts")
LOG = Path("/home/user/build_staging/artifact_migration.log")

EXPECTED_ARTIFACTS = {
    "api-server-1.4.2-linux-amd64.tar.gz": "artifact api-server 1.4.2 linux amd64\n",
    "api-server-1.4.2-linux-arm64.tar.gz": "artifact api-server 1.4.2 linux arm64\n",
    "worker-1.4.2-linux-amd64.tar.gz": "artifact worker 1.4.2 linux amd64\n",
    "worker-1.4.2-linux-arm64.tar.gz": "artifact worker 1.4.2 linux arm64\n",
}

EXPECTED_LEGACY_NON_ARTIFACTS = {
    "checksums.txt": "legacy checksum file - do not migrate\n",
    "build-notes.md": "# Build notes\nThese notes stay in the legacy directory.\n",
}

EXPECTED_DESTINATION_FILES = sorted(EXPECTED_ARTIFACTS)
EXPECTED_LOG_LINES = [
    "SOURCE_RETIRED=yes",
    "DESTINATION_COUNT=4",
    "DESTINATION_FILES="
    + ",".join(EXPECTED_DESTINATION_FILES),
]

def _direct_regular_files(directory: Path):
    assert directory.exists(), f"Required directory is missing: {directory}"
    assert directory.is_dir(), f"Required path is not a directory: {directory}"
    return [path for path in directory.iterdir() if path.is_file()]

def _direct_tar_gz_files(directory: Path):
    return sorted(
        path for path in _direct_regular_files(directory)
        if path.name.endswith(".tar.gz")
    )

def test_legacy_source_is_retired_and_contains_no_direct_tar_gz_files():
    legacy_tarballs = [path.name for path in _direct_tar_gz_files(LEGACY)]

    assert legacy_tarballs == [], (
        "The old legacy artifact directory must no longer contain any direct "
        f"*.tar.gz files after migration. Remaining files in {LEGACY}: "
        f"{legacy_tarballs!r}. This usually means artifacts were copied instead "
        "of moved, or the source was not fully retired."
    )

def test_release_directory_contains_exact_expected_migrated_artifact_filenames():
    release_tarballs = sorted(path.name for path in _direct_tar_gz_files(RELEASE))

    assert release_tarballs == EXPECTED_DESTINATION_FILES, (
        "The new canonical artifact directory must contain exactly the four "
        "expected migrated .tar.gz files directly inside it, with filenames "
        "preserved exactly. "
        f"Expected in {RELEASE}: {EXPECTED_DESTINATION_FILES!r}; "
        f"found: {release_tarballs!r}."
    )

def test_release_artifact_contents_are_preserved_exactly():
    for filename, expected_content in EXPECTED_ARTIFACTS.items():
        artifact_path = RELEASE / filename

        assert artifact_path.exists(), (
            f"Expected migrated artifact is missing from canonical directory: "
            f"{artifact_path}"
        )
        assert artifact_path.is_file(), (
            f"Expected migrated artifact path is not a regular file: "
            f"{artifact_path}"
        )

        actual_content = artifact_path.read_text()
        assert actual_content == expected_content, (
            f"Migrated artifact content mismatch for {artifact_path}. "
            f"Expected {expected_content!r}, got {actual_content!r}."
        )

def test_legacy_non_artifact_files_remain_with_exact_contents():
    for filename, expected_content in EXPECTED_LEGACY_NON_ARTIFACTS.items():
        legacy_path = LEGACY / filename

        assert legacy_path.exists(), (
            f"Non-artifact file should have remained in the legacy directory "
            f"but is missing: {legacy_path}"
        )
        assert legacy_path.is_file(), (
            f"Legacy non-artifact path should be a regular file: {legacy_path}"
        )

        actual_content = legacy_path.read_text()
        assert actual_content == expected_content, (
            f"Legacy non-artifact file content changed unexpectedly for "
            f"{legacy_path}. Expected {expected_content!r}, got "
            f"{actual_content!r}."
        )

def test_release_directory_has_no_unexpected_direct_regular_files():
    actual_regular_names = sorted(path.name for path in _direct_regular_files(RELEASE))

    assert actual_regular_names == EXPECTED_DESTINATION_FILES, (
        "The canonical artifact directory should contain only the expected "
        "direct regular artifact files. "
        f"Expected files in {RELEASE}: {EXPECTED_DESTINATION_FILES!r}; "
        f"found: {actual_regular_names!r}."
    )

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

    raw_log = LOG.read_text()

    assert not raw_log.endswith("\n\n"), (
        f"Verification log {LOG} has an extra trailing blank line. The log may "
        "end with one final newline or no final newline, but must not contain "
        "additional blank lines."
    )

    normalized_log = raw_log[:-1] if raw_log.endswith("\n") else raw_log
    actual_lines = normalized_log.split("\n")

    assert actual_lines == EXPECTED_LOG_LINES, (
        "Verification log content is incorrect. It must reflect the final state "
        f"of the canonical destination directory {RELEASE}, not a stale listing "
        f"from {LEGACY}. "
        f"Expected exact lines: {EXPECTED_LOG_LINES!r}; got: {actual_lines!r}."
    )

def test_log_destination_count_and_files_match_actual_release_directory_state():
    """
    Redundant consistency check with a focused failure message: the log must be
    derived from /home/user/build_staging/release_artifacts after migration.
    """
    assert LOG.exists(), f"Verification log was not created: {LOG}"

    raw_log = LOG.read_text()
    normalized_log = raw_log[:-1] if raw_log.endswith("\n") else raw_log
    lines = normalized_log.split("\n")

    assert len(lines) == 3, (
        f"Verification log must contain exactly three lines and no extra text. "
        f"Got {len(lines)} lines: {lines!r}."
    )

    log_map = {}
    for line in lines:
        assert "=" in line, f"Malformed log line missing '=': {line!r}"
        key, value = line.split("=", 1)
        log_map[key] = value

    actual_destination_files = sorted(
        path.name for path in _direct_tar_gz_files(RELEASE)
    )
    actual_destination_files_csv = ",".join(actual_destination_files)

    assert log_map.get("SOURCE_RETIRED") == "yes", (
        "SOURCE_RETIRED must be 'yes' because the legacy directory contains "
        f"zero direct .tar.gz files. Got: {log_map.get('SOURCE_RETIRED')!r}."
    )
    assert log_map.get("DESTINATION_COUNT") == str(len(actual_destination_files)), (
        "DESTINATION_COUNT must equal the number of direct .tar.gz files in "
        f"{RELEASE}. Expected {len(actual_destination_files)!r}, got "
        f"{log_map.get('DESTINATION_COUNT')!r}."
    )
    assert log_map.get("DESTINATION_FILES") == actual_destination_files_csv, (
        "DESTINATION_FILES must be the sorted comma-separated filenames of "
        f"direct .tar.gz files in {RELEASE}. Expected "
        f"{actual_destination_files_csv!r}, got "
        f"{log_map.get('DESTINATION_FILES')!r}."
    )


You are acting as the on-call site reliability engineer for a small internal service. A local HTTP API will already be running inside the container on `http://127.0.0.1:8097`. Your job is to probe the API with `curl`, summarize uptime status, and leave behind a machine-checkable incident report.

Work only under `/home/user/sre-uptime-check`. The directory will already exist and be writable. The API exposes these endpoints:

- `GET http://127.0.0.1:8097/health`
- `GET http://127.0.0.1:8097/ready`
- `GET http://127.0.0.1:8097/version`
- `GET http://127.0.0.1:8097/metrics`
- `GET http://127.0.0.1:8097/incidents/recent`

Create the final report file at:

`/home/user/sre-uptime-check/uptime_report.json`

The report must be valid JSON and must contain exactly these top-level keys:

```json
{
  "service": "catalog-api",
  "base_url": "http://127.0.0.1:8097",
  "overall_status": "...",
  "checked_endpoints": [],
  "version": {},
  "metrics": {},
  "recent_incidents": [],
  "verification": {}
}
```

Populate the fields as follows:

1. `service` must be exactly `"catalog-api"`.
2. `base_url` must be exactly `"http://127.0.0.1:8097"`.
3. `checked_endpoints` must be an array with exactly two objects, one for `/health` and one for `/ready`.
   - Each object must contain exactly:
     - `path`
     - `http_status`
     - `api_status`
     - `latency_ms`
   - `path` must be the endpoint path, such as `"/health"`.
   - `http_status` must be the HTTP response status code returned by curl.
   - `api_status` must come from the JSON body returned by the endpoint, not from the curl exit code.
   - `latency_ms` must be a number, computed from curl timing data in milliseconds. It may be rounded to an integer.
4. `version` must be the parsed JSON body from `/version`.
5. `metrics` must be based on `/metrics`.
   - The `/metrics` endpoint returns Prometheus-style text, not JSON.
   - Extract at least these numeric values:
     - `uptime_seconds`
     - `request_success_total`
     - `request_error_total`
   - Store them as JSON numbers, not strings.
6. `recent_incidents` must be the parsed JSON array from `/incidents/recent`.
7. `overall_status` must be:
   - `"ok"` only when both `/health` and `/ready` return HTTP 200 and their JSON body status fields are healthy/ready respectively, and `request_error_total` is zero.
   - `"degraded"` otherwise.
8. `verification` must contain exactly:
   - `checked_with_curl`: `true`
   - `artifact_valid_json`: `true`
   - `semantic_checks_passed`: `true`
   - `notes`: a short string saying that HTTP status codes and response bodies were both checked.

Also create a plain text verification log at:

`/home/user/sre-uptime-check/verification.log`

The log must contain exactly four lines, in this order:

1. `curl probes completed`
2. `report file created`
3. `json syntax verified`
4. `semantic status verified`

Important: do not stop just because every `curl` command exits with status code 0. You must inspect the HTTP status codes and the response bodies, then ensure that `/home/user/sre-uptime-check/uptime_report.json` actually satisfies the format and semantic rules above before writing the final verification log. A clean command run with a missing, invalid, or semantically wrong report is not complete.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_f3c8f023"
description = "You are acting as the on-call site reliability engineer for a small internal service. A local HTTP API will already be running inside the container on `http://127.0.0.1:8097`. Your job is to probe the API with `curl`, summarize uptime statu"
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 \
        ca-certificates \
        curl \
        jq \
        gawk \
        sed \
        python3 \
        python3-pip \
        python3-pytest \
        netcat-openbsd \
        procps

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

    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/sre-uptime-check
    chown -R user:user /home/user
    chmod 755 /home/user
    chmod 777 /home/user/sre-uptime-check

    cat > /usr/local/bin/catalog_api_server.py <<'PY'
#!/usr/bin/env python3
import json
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer

HOST = "127.0.0.1"
PORT = 8097

HEALTH = {
    "status": "healthy",
    "component": "catalog-api",
    "checks": {"database": "pass", "cache": "pass"},
}

READY = {
    "status": "not_ready",
    "component": "catalog-api",
    "reason": "search-index-lag",
    "checks": {"database": "pass", "cache": "pass", "search_index": "fail"},
}

VERSION = {
    "name": "catalog-api",
    "version": "2.7.4",
    "git_sha": "9f4c1b8",
    "build_time": "2025-02-14T11:06:22Z",
}

METRICS = (
    "# HELP uptime_seconds Process uptime in seconds\n"
    "# TYPE uptime_seconds gauge\n"
    "uptime_seconds 86442\n"
    "# HELP request_success_total Total successful API requests\n"
    "# TYPE request_success_total counter\n"
    "request_success_total 128903\n"
    "# HELP request_error_total Total failed API requests\n"
    "# TYPE request_error_total counter\n"
    "request_error_total 7\n"
)

INCIDENTS = [
    {
        "id": "INC-1042",
        "severity": "minor",
        "summary": "search index lag above threshold",
        "opened_at": "2025-02-14T10:58:03Z",
        "resolved": False,
    }
]

class Handler(BaseHTTPRequestHandler):
    server_version = "CatalogAPITest/1.0"

    def log_message(self, fmt, *args):
        return

    def _send_json(self, status_code, payload):
        body = json.dumps(payload, separators=(",", ":")).encode("utf-8")
        self.send_response(status_code)
        self.send_header("Content-Type", "application/json")
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        self.wfile.write(body)

    def _send_text(self, status_code, text):
        body = text.encode("utf-8")
        self.send_response(status_code)
        self.send_header("Content-Type", "text/plain; version=0.0.4")
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        self.wfile.write(body)

    def do_GET(self):
        if self.path == "/health":
            self._send_json(200, HEALTH)
        elif self.path == "/ready":
            self._send_json(503, READY)
        elif self.path == "/version":
            self._send_json(200, VERSION)
        elif self.path == "/metrics":
            self._send_text(200, METRICS)
        elif self.path == "/incidents/recent":
            self._send_json(200, INCIDENTS)
        else:
            self._send_json(404, {"error": "not found"})

def main():
    httpd = ThreadingHTTPServer((HOST, PORT), Handler)
    httpd.serve_forever()

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

    chmod 755 /usr/local/bin/catalog_api_server.py

    cat > /usr/local/bin/start_catalog_api_if_needed.sh <<'SH'
#!/bin/sh
set -eu

if nc -z 127.0.0.1 8097 >/dev/null 2>&1; then
    exit 0
fi

/usr/local/bin/catalog_api_server.py >/tmp/catalog_api_server.log 2>&1 &

i=0
while [ "$i" -lt 50 ]; do
    if nc -z 127.0.0.1 8097 >/dev/null 2>&1; then
        exit 0
    fi
    i=$((i + 1))
    sleep 0.1
done

echo "catalog API server did not start on 127.0.0.1:8097" >&2
exit 1
SH

    chmod 755 /usr/local/bin/start_catalog_api_if_needed.sh

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

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

import pytest

REPORT_PATH = Path("/home/user/sre-uptime-check/uptime_report.json")
LOG_PATH = Path("/home/user/sre-uptime-check/verification.log")

EXPECTED_TOP_LEVEL_KEYS = {
    "service",
    "base_url",
    "overall_status",
    "checked_endpoints",
    "version",
    "metrics",
    "recent_incidents",
    "verification",
}

EXPECTED_VERSION = {
    "name": "catalog-api",
    "version": "2.7.4",
    "git_sha": "9f4c1b8",
    "build_time": "2025-02-14T11:06:22Z",
}

EXPECTED_RECENT_INCIDENTS = [
    {
        "id": "INC-1042",
        "severity": "minor",
        "summary": "search index lag above threshold",
        "opened_at": "2025-02-14T10:58:03Z",
        "resolved": False,
    }
]

EXPECTED_LOG_TEXT = (
    "curl probes completed\n"
    "report file created\n"
    "json syntax verified\n"
    "semantic status verified\n"
)

def _load_report():
    assert REPORT_PATH.exists(), (
        "Missing final report file: /home/user/sre-uptime-check/uptime_report.json"
    )
    assert REPORT_PATH.is_file(), (
        "Expected /home/user/sre-uptime-check/uptime_report.json to be a regular file"
    )

    raw = REPORT_PATH.read_text(encoding="utf-8")
    try:
        report = json.loads(raw)
    except json.JSONDecodeError as exc:
        pytest.fail(
            "Final report /home/user/sre-uptime-check/uptime_report.json is not valid JSON: "
            f"{exc}"
        )
    return report

def _assert_exact_keys(obj, expected_keys, context):
    assert isinstance(obj, dict), f"{context} must be a JSON object, got {type(obj).__name__}"
    actual_keys = set(obj.keys())
    missing = expected_keys - actual_keys
    extra = actual_keys - expected_keys
    assert actual_keys == expected_keys, (
        f"{context} has incorrect keys. "
        f"Missing keys: {sorted(missing)}; extra keys: {sorted(extra)}; "
        f"actual keys: {sorted(actual_keys)}"
    )

def _assert_json_number(value, context):
    assert isinstance(value, (int, float)) and not isinstance(value, bool), (
        f"{context} must be a JSON number, not {type(value).__name__}: {value!r}"
    )
    if isinstance(value, float):
        assert math.isfinite(value), f"{context} must be finite, got {value!r}"

def test_uptime_report_exists_is_valid_json_object_and_has_exact_top_level_keys():
    report = _load_report()
    _assert_exact_keys(report, EXPECTED_TOP_LEVEL_KEYS, "uptime_report.json top-level object")

def test_uptime_report_required_scalar_values_indicate_degraded_catalog_api():
    report = _load_report()

    assert report["service"] == "catalog-api", (
        "report.service must be exactly 'catalog-api'"
    )
    assert report["base_url"] == "http://127.0.0.1:8097", (
        "report.base_url must be exactly 'http://127.0.0.1:8097'"
    )
    assert report["overall_status"] == "degraded", (
        "report.overall_status must be 'degraded' because /ready returned HTTP 503 "
        "with api_status 'not_ready' and request_error_total is 7"
    )

def test_checked_endpoints_exactly_capture_health_and_ready_http_and_body_statuses():
    report = _load_report()
    checked = report["checked_endpoints"]

    assert isinstance(checked, list), "report.checked_endpoints must be a JSON array"
    assert len(checked) == 2, (
        f"report.checked_endpoints must contain exactly two entries, got {len(checked)}"
    )

    by_path = {}
    for index, entry in enumerate(checked):
        _assert_exact_keys(
            entry,
            {"path", "http_status", "api_status", "latency_ms"},
            f"checked_endpoints[{index}]",
        )

        path = entry["path"]
        assert path in {"/health", "/ready"}, (
            f"checked_endpoints[{index}].path must be either '/health' or '/ready', got {path!r}"
        )
        assert path not in by_path, (
            f"checked_endpoints contains duplicate entry for path {path!r}"
        )
        by_path[path] = entry

        assert isinstance(entry["http_status"], int) and not isinstance(entry["http_status"], bool), (
            f"checked endpoint {path} http_status must be an integer HTTP status code"
        )
        assert isinstance(entry["api_status"], str), (
            f"checked endpoint {path} api_status must be a string parsed from the JSON body"
        )
        _assert_json_number(entry["latency_ms"], f"checked endpoint {path} latency_ms")
        assert entry["latency_ms"] >= 0, (
            f"checked endpoint {path} latency_ms must be greater than or equal to 0"
        )

    assert set(by_path) == {"/health", "/ready"}, (
        f"checked_endpoints must contain exactly /health and /ready, got {sorted(by_path)}"
    )

    assert by_path["/health"]["http_status"] == 200, (
        "/health http_status must be 200 as returned by curl/HTTP response"
    )
    assert by_path["/health"]["api_status"] == "healthy", (
        "/health api_status must be 'healthy' from the JSON response body"
    )

    assert by_path["/ready"]["http_status"] == 503, (
        "/ready http_status must be 503; do not treat curl exit code 0 as HTTP success"
    )
    assert by_path["/ready"]["api_status"] == "not_ready", (
        "/ready api_status must be 'not_ready' from the JSON response body"
    )

def test_version_and_recent_incidents_match_api_ground_truth_exactly():
    report = _load_report()

    assert report["version"] == EXPECTED_VERSION, (
        "report.version must exactly match the parsed JSON body from /version"
    )
    assert report["recent_incidents"] == EXPECTED_RECENT_INCIDENTS, (
        "report.recent_incidents must exactly match the parsed JSON array from /incidents/recent"
    )

def test_metrics_contain_required_numeric_prometheus_values():
    report = _load_report()
    metrics = report["metrics"]

    assert isinstance(metrics, dict), "report.metrics must be a JSON object"

    required = {
        "uptime_seconds": 86442,
        "request_success_total": 128903,
        "request_error_total": 7,
    }
    for key, expected_value in required.items():
        assert key in metrics, f"report.metrics is missing required key {key!r}"
        _assert_json_number(metrics[key], f"report.metrics.{key}")
        assert metrics[key] == expected_value, (
            f"report.metrics.{key} must be numeric value {expected_value}, got {metrics[key]!r}"
        )

    assert metrics["request_error_total"] == 7, (
        "request_error_total must be 7, which is a semantic reason overall_status is degraded"
    )

def test_verification_object_has_exact_keys_and_required_truth_values():
    report = _load_report()
    verification = report["verification"]

    _assert_exact_keys(
        verification,
        {"checked_with_curl", "artifact_valid_json", "semantic_checks_passed", "notes"},
        "report.verification",
    )

    assert verification["checked_with_curl"] is True, (
        "report.verification.checked_with_curl must be true"
    )
    assert verification["artifact_valid_json"] is True, (
        "report.verification.artifact_valid_json must be true"
    )
    assert verification["semantic_checks_passed"] is True, (
        "report.verification.semantic_checks_passed must be true"
    )

    notes = verification["notes"]
    assert isinstance(notes, str) and notes.strip(), (
        "report.verification.notes must be a nonempty string"
    )
    assert "HTTP status" in notes, (
        "report.verification.notes must mention 'HTTP status'"
    )
    assert "response bodies" in notes, (
        "report.verification.notes must mention 'response bodies'"
    )

def test_verification_log_exists_and_contains_exactly_four_required_lines():
    assert LOG_PATH.exists(), (
        "Missing verification log: /home/user/sre-uptime-check/verification.log"
    )
    assert LOG_PATH.is_file(), (
        "Expected /home/user/sre-uptime-check/verification.log to be a regular file"
    )

    actual = LOG_PATH.read_text(encoding="utf-8")
    assert actual == EXPECTED_LOG_TEXT, (
        "verification.log must contain exactly four required lines with no extra or missing lines:\n"
        f"{EXPECTED_LOG_TEXT!r}\n"
        f"Actual content was:\n{actual!r}"
    )


You are acting as a backup operator testing a small SQLite restore workflow.

The working directory is `/home/user/restore_test`. It already contains a restored SQLite database file at:

`/home/user/restore_test/restored_register.sqlite`

Your job is to produce a verification report from that database and save it as:

`/home/user/restore_test/restore_report.txt`

Use the SQLite command-line client to inspect the restored database. Do not modify the database.

The restored database contains a table named `backup_items` with these columns:

- `id`
- `label`
- `backup_status`
- `restored`
- `size_bytes`

Create `/home/user/restore_test/restore_report.txt` with exactly four lines, in this exact order and format:

1. `RESTORE_REPORT`
2. `total_items=<number>`
3. `restored_ok=<number>`
4. `restore_complete=<YES-or-NO>`

Definitions:

- `total_items` is the total number of rows in `backup_items`.
- `restored_ok` is the number of rows where `restored` is exactly `1`.
- `restore_complete` must be `YES` only if every row in `backup_items` has `restored = 1`; otherwise it must be `NO`.

Be careful: a command can finish successfully and still produce the wrong report if you count only rows with `backup_status = 'OK'`. The report must be based on the `restored` column, because this is a restore verification, not a backup verification.

Before you finish, verify the contents of `/home/user/restore_test/restore_report.txt` yourself and make sure it matches the required four-line format exactly.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_fcd53522"
description = "You are acting as a backup operator testing a small SQLite restore workflow."
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

    export DEBIAN_FRONTEND=noninteractive

    apt-get update
    apt-get install -y --no-install-recommends \
        sqlite3 \
        python3 \
        python3-pip \
        python3-pytest \
        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/restore_test

    rm -f /home/user/restore_test/restored_register.sqlite
    sqlite3 /home/user/restore_test/restored_register.sqlite <<'SQL'
CREATE TABLE backup_items (
    id INTEGER PRIMARY KEY,
    label TEXT NOT NULL,
    backup_status TEXT NOT NULL,
    restored INTEGER NOT NULL CHECK (restored IN (0,1)),
    size_bytes INTEGER NOT NULL
);
INSERT INTO backup_items (id, label, backup_status, restored, size_bytes) VALUES
(1, 'etc-config.tar',      'OK',      1, 18432),
(2, 'home-documents.tar',  'OK',      1, 92810),
(3, 'mail-spool.tar',      'OK',      0, 44712),
(4, 'project-alpha.tar',   'OK',      1, 136500),
(5, 'project-beta.tar',    'FAILED',  0, 0),
(6, 'photos-index.tar',    'OK',      1, 31209);
SQL

    chown -R user:user /home/user/restore_test
    chmod 0755 /home/user
    chmod 0755 /home/user/restore_test
    chmod 0664 /home/user/restore_test/restored_register.sqlite

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

# test_final_state.py
import re
import shutil
import sqlite3
import subprocess
from pathlib import Path

import pytest

RESTORE_DIR = Path("/home/user/restore_test")
DB_PATH = Path("/home/user/restore_test/restored_register.sqlite")
REPORT_PATH = Path("/home/user/restore_test/restore_report.txt")

EXPECTED_DB_ROWS = [
    (1, "etc-config.tar", "OK", 1, 18432),
    (2, "home-documents.tar", "OK", 1, 92810),
    (3, "mail-spool.tar", "OK", 0, 44712),
    (4, "project-alpha.tar", "OK", 1, 136500),
    (5, "project-beta.tar", "FAILED", 0, 0),
    (6, "photos-index.tar", "OK", 1, 31209),
]

EXPECTED_REPORT_LINES = [
    "RESTORE_REPORT",
    "total_items=6",
    "restored_ok=4",
    "restore_complete=NO",
]

EXPECTED_REPORT_TEXT = "\n".join(EXPECTED_REPORT_LINES)

def _read_report_text() -> str:
    assert REPORT_PATH.exists(), (
        f"Required final report is missing: {REPORT_PATH}. "
        "Create this file from the restored SQLite database."
    )
    assert REPORT_PATH.is_file(), (
        f"Required final report path exists but is not a regular file: {REPORT_PATH}"
    )
    try:
        return REPORT_PATH.read_text(encoding="utf-8")
    except UnicodeDecodeError as exc:
        pytest.fail(f"Report file {REPORT_PATH} is not valid UTF-8 text: {exc}")

def _connect_readonly():
    return sqlite3.connect(f"file:{DB_PATH}?mode=ro", uri=True)

def test_sqlite_cli_can_inspect_restored_database_read_only():
    sqlite_cli = shutil.which("sqlite3")
    assert sqlite_cli is not None, (
        "SQLite command-line client 'sqlite3' is not available on PATH; "
        "the restore workflow requires using the SQLite CLI."
    )

    assert DB_PATH.exists(), f"Restored SQLite database is missing: {DB_PATH}"
    assert DB_PATH.is_file(), f"Restored SQLite database path is not a file: {DB_PATH}"

    result = subprocess.run(
        [
            sqlite_cli,
            f"file:{DB_PATH}?mode=ro",
            "SELECT COUNT(*) FROM backup_items;",
        ],
        text=True,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        timeout=10,
    )

    assert result.returncode == 0, (
        "SQLite CLI could not inspect the restored database in read-only mode. "
        f"stderr={result.stderr.strip()!r}"
    )
    assert result.stdout.strip() == "6", (
        "SQLite CLI opened the database, but the backup_items row count was not 6. "
        f"stdout={result.stdout!r}, stderr={result.stderr!r}"
    )

def test_database_was_not_modified_and_still_contains_expected_backup_items():
    assert DB_PATH.exists(), f"Restored SQLite database is missing: {DB_PATH}"

    with _connect_readonly() as conn:
        tables = conn.execute(
            """
            SELECT name
            FROM sqlite_master
            WHERE type = 'table'
              AND name NOT LIKE 'sqlite_%'
            ORDER BY name
            """
        ).fetchall()
        table_info = conn.execute("PRAGMA table_info(backup_items)").fetchall()
        rows = conn.execute(
            """
            SELECT id, label, backup_status, restored, size_bytes
            FROM backup_items
            ORDER BY id
            """
        ).fetchall()

    table_names = [row[0] for row in tables]
    assert table_names == ["backup_items"], (
        "Database should still contain exactly one non-internal table named "
        f"'backup_items'. Found: {table_names!r}. The task required inspecting, "
        "not modifying, the database."
    )

    expected_columns = [
        (0, "id", "INTEGER", 0, None, 1),
        (1, "label", "TEXT", 1, None, 0),
        (2, "backup_status", "TEXT", 1, None, 0),
        (3, "restored", "INTEGER", 1, None, 0),
        (4, "size_bytes", "INTEGER", 1, None, 0),
    ]
    assert table_info == expected_columns, (
        "Table 'backup_items' schema changed or is incorrect. "
        f"Expected PRAGMA table_info: {expected_columns!r}. Found: {table_info!r}"
    )

    assert rows == EXPECTED_DB_ROWS, (
        "Rows in table 'backup_items' changed or do not match the expected restored "
        "database contents. The database should not be modified. "
        f"Expected: {EXPECTED_DB_ROWS!r}. Found: {rows!r}"
    )

def test_restore_report_exists_and_has_exact_four_line_format():
    text = _read_report_text()

    assert text in (EXPECTED_REPORT_TEXT, EXPECTED_REPORT_TEXT + "\n"), (
        "Report contents must exactly match the required four lines, with only an "
        "optional single trailing newline. "
        f"Expected {EXPECTED_REPORT_TEXT!r} optionally followed by '\\n'. "
        f"Found {text!r}."
    )

    lines = text.splitlines()
    assert lines == EXPECTED_REPORT_LINES, (
        "Report must contain exactly these four non-empty lines in order: "
        f"{EXPECTED_REPORT_LINES!r}. Found: {lines!r}"
    )

    assert all(line.strip() == line and line for line in lines), (
        "Report lines must be non-empty and must not contain leading or trailing spaces. "
        f"Found lines: {lines!r}"
    )

    assert lines[0] == "RESTORE_REPORT", (
        f"Line 1 must be exactly 'RESTORE_REPORT'. Found: {lines[0]!r}"
    )
    assert re.fullmatch(r"total_items=\d+", lines[1]), (
        f"Line 2 must match 'total_items=<integer>'. Found: {lines[1]!r}"
    )
    assert re.fullmatch(r"restored_ok=\d+", lines[2]), (
        f"Line 3 must match 'restored_ok=<integer>'. Found: {lines[2]!r}"
    )
    assert re.fullmatch(r"restore_complete=(YES|NO)", lines[3]), (
        "Line 4 must match 'restore_complete=YES' or 'restore_complete=NO'. "
        f"Found: {lines[3]!r}"
    )

def test_restore_report_semantics_are_based_on_restored_column_not_backup_status():
    text = _read_report_text()
    lines = text.splitlines()

    assert len(lines) == 4, (
        f"Report must have exactly four lines. Found {len(lines)} lines: {lines!r}"
    )

    parsed = {}
    for line in lines[1:]:
        key, sep, value = line.partition("=")
        assert sep == "=", f"Report line is missing '=' separator: {line!r}"
        parsed[key] = value

    with _connect_readonly() as conn:
        total_items = conn.execute("SELECT COUNT(*) FROM backup_items").fetchone()[0]
        restored_ok = conn.execute(
            "SELECT COUNT(*) FROM backup_items WHERE restored = 1"
        ).fetchone()[0]
        backup_status_ok = conn.execute(
            "SELECT COUNT(*) FROM backup_items WHERE backup_status = 'OK'"
        ).fetchone()[0]
        not_restored = conn.execute(
            "SELECT COUNT(*) FROM backup_items WHERE restored <> 1"
        ).fetchone()[0]

    expected_complete = "YES" if not_restored == 0 else "NO"

    assert parsed.get("total_items") == str(total_items), (
        "Incorrect total_items value in report. It must be the total number of rows "
        f"in backup_items. Expected {total_items}, found {parsed.get('total_items')!r}."
    )

    assert parsed.get("restored_ok") == str(restored_ok), (
        "Incorrect restored_ok value in report. It must count rows where restored = 1, "
        "not rows where backup_status = 'OK'. "
        f"Expected restored_ok={restored_ok}; found restored_ok={parsed.get('restored_ok')!r}. "
        f"For comparison, backup_status='OK' count is {backup_status_ok}, which is the "
        "misleading wrong value."
    )

    assert parsed.get("restore_complete") == expected_complete, (
        "Incorrect restore_complete value in report. It must be YES only if every row "
        f"has restored = 1. Expected {expected_complete} because {not_restored} row(s) "
        f"are not restored; found {parsed.get('restore_complete')!r}."
    )

    assert parsed.get("restored_ok") != str(backup_status_ok), (
        "Report appears to use backup_status = 'OK' instead of restored = 1: "
        f"backup_status OK count is {backup_status_ok}, but restored_ok must be {restored_ok}."
    )
    assert parsed.get("restore_complete") == "NO", (
        "restore_complete must be NO because not all backup_items rows have restored = 1."
    )


You are helping a database administrator prepare a short optimization report from a PostgreSQL slow-query capture. The input file is already present at `/home/user/dba_review/slow_queries.log`, and you may write output files under `/home/user/dba_review/`.

Create exactly one deliverable file:

`/home/user/dba_review/top_query_fingerprints.tsv`

The file must be a tab-separated text file with these exact columns and header line:

`fingerprint	count	total_ms	avg_ms`

Use the query records in `/home/user/dba_review/slow_queries.log` to compute the report. Each query record is a single line that starts with a duration in milliseconds, followed by whitespace, then a SQL statement. Blank lines and comment lines beginning with `#` are not query records and must be ignored.

For each query record:

1. Use only the SQL statement portion after the duration.
2. Normalize the SQL statement into a fingerprint:
   - Convert all letters to lowercase.
   - Replace every single-quoted string literal with `?`.
   - Replace every standalone integer number with `?`.
   - Collapse repeated whitespace to a single space.
   - Remove leading and trailing whitespace.
   - Remove one trailing semicolon if present.
3. Group records by identical normalized fingerprint.
4. For each fingerprint, calculate:
   - `count`: number of records in that group.
   - `total_ms`: sum of durations for that group, formatted with exactly one digit after the decimal point.
   - `avg_ms`: average duration for that group, formatted with exactly one digit after the decimal point.

Sort the data rows by `total_ms` descending. If two rows have the same `total_ms`, sort those rows by `fingerprint` ascending. The header must remain the first line.

Important verification requirement: do not stop just because your command exits successfully. After creating the file, inspect `/home/user/dba_review/top_query_fingerprints.tsv` and make sure the grouping is semantically correct: literals that differ only by integer IDs or quoted strings should be grouped together, and the output should contain one row per normalized query fingerprint, not one row per raw query line.

When finished, also create a verification log at:

`/home/user/dba_review/verification.log`

The verification log must contain exactly three lines in this format:

`artifact_exists=<yes-or-no>`
`data_rows=<number-of-data-rows-in-top_query_fingerprints.tsv>`
`verified=<yes-or-no>`

Use `verified=yes` only if you inspected the generated TSV and confirmed that it follows the required format and grouping rules above.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_feeb525e"
description = "You are helping a database administrator prepare a short optimization report from a PostgreSQL slow-query capture. The input file is already present at `/home/user/dba_review/slow_queries.log`, and you may write output files under `/home/us"
authors = [{ name = "Endless Terminals / Jarrod Barnes" }]
keywords = ["agentic-rl", "endless-terminals", "exit_code_false_success", "terminal-bench-2", "verification_directed_action"]

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

[verifier]
timeout_sec = 300.0
user = "root"

[agent]
timeout_sec = 900.0
user = "user"

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

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

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

    cat > /home/user/dba_review/slow_queries.log <<'EOF'
# PostgreSQL slow query sample for weekly DBA review
124.8 SELECT * FROM orders WHERE customer_id = 101 AND status = 'pending';
88.4 SELECT * FROM orders WHERE customer_id = 205 AND status = 'pending';
310.0 SELECT * FROM orders WHERE customer_id = 101 AND status = 'shipped';
55.0 UPDATE inventory SET quantity = quantity - 1 WHERE product_id = 5001;
60.0 UPDATE inventory SET quantity = quantity - 1 WHERE product_id = 5002;
42.5 SELECT name FROM customers WHERE id = 101;
41.5 SELECT name FROM customers WHERE id = 205;
500.0 SELECT * FROM orders WHERE customer_id = 305 AND status = 'pending';
# The following line is intentionally blank

275.0 DELETE FROM sessions WHERE user_id = 101;
275.0 DELETE FROM sessions WHERE user_id = 205;
EOF

    chown -R user:user /home/user
    chmod 755 /home/user
    chmod 775 /home/user/dba_review
    chmod 664 /home/user/dba_review/slow_queries.log

    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
import csv
import re

REVIEW_DIR = Path("/home/user/dba_review")
TOP_TSV = Path("/home/user/dba_review/top_query_fingerprints.tsv")
VERIFICATION_LOG = Path("/home/user/dba_review/verification.log")

EXPECTED_TOP_TSV = (
    "fingerprint\tcount\ttotal_ms\tavg_ms\n"
    "select * from orders where customer_id = ? and status = ?\t4\t1023.2\t255.8\n"
    "delete from sessions where user_id = ?\t2\t550.0\t275.0\n"
    "update inventory set quantity = quantity - ? where product_id = ?\t2\t115.0\t57.5\n"
    "select name from customers where id = ?\t2\t84.0\t42.0\n"
)

EXPECTED_VERIFICATION_LOG = (
    "artifact_exists=yes\n"
    "data_rows=4\n"
    "verified=yes\n"
)

EXPECTED_ROWS = [
    ["fingerprint", "count", "total_ms", "avg_ms"],
    ["select * from orders where customer_id = ? and status = ?", "4", "1023.2", "255.8"],
    ["delete from sessions where user_id = ?", "2", "550.0", "275.0"],
    ["update inventory set quantity = quantity - ? where product_id = ?", "2", "115.0", "57.5"],
    ["select name from customers where id = ?", "2", "84.0", "42.0"],
]

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

def parse_tsv(path: Path):
    text = read_text(path)
    return list(csv.reader(text.splitlines(), delimiter="\t"))

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

    assert TOP_TSV.exists(), f"Deliverable TSV file is missing: {TOP_TSV}"
    assert TOP_TSV.is_file(), f"Deliverable path exists but is not a regular file: {TOP_TSV}"

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

def test_top_query_fingerprints_tsv_matches_expected_contents_exactly():
    actual = read_text(TOP_TSV)
    assert actual == EXPECTED_TOP_TSV, (
        f"{TOP_TSV} does not exactly match the required final report contents.\n"
        "The report must contain the exact header, four correctly grouped rows, "
        "one-decimal numeric formatting, required sort order, and a trailing newline."
    )

def test_top_query_fingerprints_has_required_tsv_shape_and_header():
    rows = parse_tsv(TOP_TSV)

    assert len(rows) == 5, (
        f"{TOP_TSV} must contain exactly 5 lines: 1 header plus 4 data rows; "
        f"found {len(rows)} parsed TSV lines."
    )
    assert rows[0] == ["fingerprint", "count", "total_ms", "avg_ms"], (
        f"{TOP_TSV} has the wrong header. Expected exactly: "
        "'fingerprint\\tcount\\ttotal_ms\\tavg_ms'; found: {rows[0]!r}"
    )

    for line_number, row in enumerate(rows, start=1):
        assert len(row) == 4, (
            f"{TOP_TSV} line {line_number} must have exactly 4 tab-separated fields; "
            f"found {len(row)} fields: {row!r}"
        )

    assert rows == EXPECTED_ROWS, (
        f"{TOP_TSV} rows are not the exact expected TSV rows. This usually means "
        "normalization, grouping, totals, averages, or sort order is still wrong."
    )

def test_top_query_fingerprints_numeric_fields_are_correctly_formatted():
    rows = parse_tsv(TOP_TSV)[1:]
    one_decimal = re.compile(r"^\d+\.\d$")

    for row_number, row in enumerate(rows, start=2):
        fingerprint, count, total_ms, avg_ms = row

        assert count.isdigit(), (
            f"{TOP_TSV} line {row_number} count for fingerprint {fingerprint!r} "
            f"must be an integer string; found {count!r}."
        )
        assert one_decimal.match(total_ms), (
            f"{TOP_TSV} line {row_number} total_ms for fingerprint {fingerprint!r} "
            f"must have exactly one digit after the decimal point; found {total_ms!r}."
        )
        assert one_decimal.match(avg_ms), (
            f"{TOP_TSV} line {row_number} avg_ms for fingerprint {fingerprint!r} "
            f"must have exactly one digit after the decimal point; found {avg_ms!r}."
        )

def test_semantic_grouping_normalized_literals_and_ignored_non_records():
    rows = parse_tsv(TOP_TSV)[1:]
    by_fingerprint = {row[0]: row[1:] for row in rows}

    assert len(rows) == 4, (
        f"{TOP_TSV} must have exactly 4 data rows, one per normalized fingerprint. "
        f"Found {len(rows)} rows, suggesting raw SQL lines may not have been grouped correctly."
    )

    orders_fp = "select * from orders where customer_id = ? and status = ?"
    inventory_fp = "update inventory set quantity = quantity - ? where product_id = ?"
    customers_fp = "select name from customers where id = ?"
    delete_fp = "delete from sessions where user_id = ?"

    assert by_fingerprint.get(orders_fp) == ["4", "1023.2", "255.8"], (
        "The four orders SELECT records must collapse into one fingerprint by replacing "
        "both integer customer IDs and quoted status strings with '?'. "
        f"Expected {orders_fp!r} -> count=4,total_ms=1023.2,avg_ms=255.8."
    )
    assert by_fingerprint.get(inventory_fp) == ["2", "115.0", "57.5"], (
        "The two inventory UPDATE records must collapse into one fingerprint by replacing "
        "standalone integers, including the decrement literal and product IDs, with '?'."
    )
    assert by_fingerprint.get(customers_fp) == ["2", "84.0", "42.0"], (
        "The two customer SELECT records must collapse into one fingerprint by replacing "
        "integer IDs with '?'."
    )
    assert by_fingerprint.get(delete_fp) == ["2", "550.0", "275.0"], (
        "The two DELETE records must collapse into one fingerprint by replacing integer "
        "user IDs with '?'."
    )

    forbidden_raw_fragments = [
        "101",
        "205",
        "305",
        "5001",
        "5002",
        "'pending'",
        "'shipped'",
        "#",
    ]
    report_text = read_text(TOP_TSV)
    for fragment in forbidden_raw_fragments:
        assert fragment not in report_text, (
            f"{TOP_TSV} still contains raw literal/comment fragment {fragment!r}; "
            "SQL fingerprints must normalize quoted strings and standalone integers, "
            "and comments must be ignored."
        )

def test_rows_are_sorted_by_total_ms_descending_then_fingerprint_ascending():
    rows = parse_tsv(TOP_TSV)[1:]
    actual_pairs = [(row[0], float(row[2])) for row in rows]
    expected_pairs = sorted(actual_pairs, key=lambda item: (-item[1], item[0]))

    assert actual_pairs == expected_pairs, (
        f"{TOP_TSV} data rows are not sorted by total_ms descending, then fingerprint "
        f"ascending. Found order: {actual_pairs!r}; expected order: {expected_pairs!r}."
    )

def test_verification_log_matches_expected_contents_exactly():
    actual = read_text(VERIFICATION_LOG)
    assert actual == EXPECTED_VERIFICATION_LOG, (
        f"{VERIFICATION_LOG} does not exactly match the required verification log. "
        "It must contain exactly three lines: artifact_exists=yes, data_rows=4, "
        "verified=yes, with no extra or missing content."
    )