You are helping as a backup engineer verify which of several currently running integrity-check jobs is the real production verification job and which are decoys/stale workers.

In the container, there will be several user-owned processes running with similar names and arguments. Your job is to inspect the process table, identify the single correct production backup integrity verifier process, and write one audit line to:

`/home/user/backup_audit/integrity_process_report.tsv`

The directory `/home/user/backup_audit` is writable. Do not require root privileges. You may use normal process-inspection tools available in a Linux terminal.

The report file must contain exactly two lines:

1. A header line exactly:
`timestamp_utc	pid	status	evidence`

2. One data line describing the production verifier process you selected.

The data line must be tab-separated with exactly four fields:

- `timestamp_utc`: current UTC timestamp in ISO-8601 basic form ending in `Z`, formatted like `YYYY-MM-DDTHH:MM:SSZ`.
- `pid`: the numeric PID of the selected running process.
- `status`: exactly `verified`.
- `evidence`: a compact semicolon-separated explanation showing why this process was selected and why the obvious alternatives were rejected.

The `evidence` field must include all of the following labels exactly once, in any order, with non-empty values after each equals sign:

- `selected_cmd=`
- `accepted_dataset=`
- `accepted_epoch=`
- `rejected=`

The `rejected=` value should briefly mention at least two rejected candidate reasons, such as wrong dataset, dry-run mode, stale epoch, or helper/child process.

Before finishing, verify that the PID you wrote still belongs to the selected running verifier process and that the report file has exactly two lines in the requested tab-separated format. Once the file is correct, stop; do not keep exploring unrelated commands.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_66375363"
description = "You are helping as a backup engineer verify which of several currently running integrity-check jobs is the real production verification job and which are decoys/stale workers."
authors = [{ name = "Endless Terminals / Jarrod Barnes" }]
keywords = ["agentic-rl", "bounded_search_discipline", "endless-terminals", "terminal-bench-2", "wander_loop_without_convergence"]

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

[verifier]
timeout_sec = 300.0
user = "root"

[agent]
timeout_sec = 900.0
user = "user"

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

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

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

    cat > /home/user/backup_audit/backup-integrity-worker <<'EOF'
#!/bin/sh
# Long-running placeholder used for process-management inspection tasks.
# Arguments are intentionally meaningful and should appear in ps output.
while :; do
  sleep 300
done
EOF

    chmod 755 /home/user/backup_audit/backup-integrity-worker

    touch /home/user/backup_audit/manifests/vault-prod-west-2024Q4.sha256
    touch /home/user/backup_audit/manifests/vault-prod-east-2024Q4.sha256
    touch /home/user/backup_audit/manifests/vault-prod-west-2024Q3.sha256

    chown -R user:user /home/user/backup_audit
    chmod 755 /home/user
    chmod 777 /home/user/backup_audit
    chmod 755 /home/user/backup_audit/manifests
    chmod 644 /home/user/backup_audit/manifests/*.sha256

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

# test_final_state.py
import os
import re
from datetime import datetime, timezone
from pathlib import Path

import pytest

REPORT = Path("/home/user/backup_audit/integrity_process_report.tsv")
WORKER = Path("/home/user/backup_audit/backup-integrity-worker")
MANIFEST_DIR = Path("/home/user/backup_audit/manifests")

HEADER = "timestamp_utc\tpid\tstatus\tevidence"
TIMESTAMP_RE = re.compile(r"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$")

EXPECTED_PRODUCTION_ARGS = [
    str(WORKER),
    "--role",
    "verifier",
    "--dataset",
    "vault-prod-west",
    "--epoch",
    "2024Q4",
    "--manifest",
    str(MANIFEST_DIR / "vault-prod-west-2024Q4.sha256"),
    "--mode",
    "verify",
    "--require-online",
    "true",
]

REQUIRED_CMD_FRAGMENTS = [
    "backup-integrity-worker",
    "--role",
    "verifier",
    "--dataset",
    "vault-prod-west",
    "--epoch",
    "2024Q4",
    "--mode",
    "verify",
]

FORBIDDEN_CMD_SEQUENCES = [
    ["--mode", "dry-run"],
    ["--role", "helper"],
    ["--dataset", "vault-prod-east"],
    ["--epoch", "2024Q3"],
]

EVIDENCE_LABELS = [
    "selected_cmd=",
    "accepted_dataset=",
    "accepted_epoch=",
    "rejected=",
]

REJECTION_REASON_SUBSTRINGS = [
    "wrong-dataset",
    "dry-run",
    "stale-epoch",
    "helper",
]

def _read_cmdline_for_pid(pid: int):
    try:
        raw = Path(f"/proc/{pid}/cmdline").read_bytes()
    except (FileNotFoundError, ProcessLookupError, PermissionError):
        return None

    if not raw:
        return None

    parts = [part.decode("utf-8", errors="replace") for part in raw.split(b"\0") if part]
    return parts or None

def _iter_user_process_cmdlines():
    current_uid = os.getuid()

    for pid_dir in Path("/proc").iterdir():
        if not pid_dir.name.isdigit():
            continue

        try:
            st = pid_dir.stat()
        except (FileNotFoundError, ProcessLookupError, PermissionError):
            continue

        if st.st_uid != current_uid:
            continue

        cmdline = _read_cmdline_for_pid(int(pid_dir.name))
        if cmdline:
            yield int(pid_dir.name), cmdline

def _contains_contiguous_sequence(items, sequence):
    n = len(sequence)
    return any(items[i : i + n] == sequence for i in range(0, len(items) - n + 1))

def _process_matches_expected_args(cmdline, expected_args):
    """
    The worker is a shell script, so cmdline may be either:
      ['/home/user/.../backup-integrity-worker', ...]
    or:
      ['/bin/sh', '/home/user/.../backup-integrity-worker', ...]
    Accept the expected script path and argument sequence wherever it appears
    contiguously in argv.
    """
    return _contains_contiguous_sequence(cmdline, expected_args)

@pytest.fixture(scope="module")
def report_lines():
    assert REPORT.exists(), f"Missing required final report file: {REPORT}"
    assert REPORT.is_file(), f"Report path exists but is not a regular file: {REPORT}"

    raw = REPORT.read_bytes()
    try:
        text = raw.decode("utf-8")
    except UnicodeDecodeError as exc:
        pytest.fail(f"Report file {REPORT} is not valid UTF-8 text: {exc}")

    assert text, f"Report file {REPORT} is empty"
    assert text.endswith("\n"), (
        f"Report file {REPORT} should end with a newline after the single data line"
    )

    lines = text.splitlines()
    assert len(lines) == 2, (
        f"Report file {REPORT} must contain exactly two lines: "
        f"the header and one data line. Found {len(lines)} line(s): {lines!r}"
    )
    assert all(line.strip() == line for line in lines), (
        f"Report lines must not have leading/trailing whitespace: {lines!r}"
    )
    assert all(line for line in lines), (
        f"Report file {REPORT} must not contain blank lines: {lines!r}"
    )

    return lines

@pytest.fixture(scope="module")
def report_fields(report_lines):
    header, data = report_lines

    assert header == HEADER, (
        "Report header is incorrect.\n"
        f"Expected exactly: {HEADER!r}\n"
        f"Actual:           {header!r}"
    )

    fields = data.split("\t")
    assert len(fields) == 4, (
        "Report data line must have exactly four tab-separated fields: "
        "timestamp_utc, pid, status, evidence.\n"
        f"Actual field count: {len(fields)}\n"
        f"Data line: {data!r}"
    )

    timestamp_utc, pid_text, status, evidence = fields
    return {
        "timestamp_utc": timestamp_utc,
        "pid_text": pid_text,
        "status": status,
        "evidence": evidence,
    }

def test_report_has_exact_two_line_tsv_shape(report_lines):
    assert report_lines[0] == HEADER
    assert len(report_lines[1].split("\t")) == 4

def test_timestamp_pid_and_status_fields_are_valid(report_fields):
    timestamp_utc = report_fields["timestamp_utc"]
    pid_text = report_fields["pid_text"]
    status = report_fields["status"]

    assert TIMESTAMP_RE.match(timestamp_utc), (
        "timestamp_utc must be in ISO-8601 UTC basic form "
        "YYYY-MM-DDTHH:MM:SSZ.\n"
        f"Actual timestamp: {timestamp_utc!r}"
    )

    try:
        parsed = datetime.strptime(timestamp_utc, "%Y-%m-%dT%H:%M:%SZ").replace(
            tzinfo=timezone.utc
        )
    except ValueError as exc:
        pytest.fail(f"timestamp_utc has invalid date/time values: {timestamp_utc!r}: {exc}")

    now = datetime.now(timezone.utc)
    assert parsed <= now, (
        f"timestamp_utc should not be in the future. "
        f"Report timestamp: {timestamp_utc!r}; current UTC: {now:%Y-%m-%dT%H:%M:%SZ}"
    )

    assert pid_text.isdigit(), f"pid field must be numeric, got: {pid_text!r}"
    assert int(pid_text) > 0, f"pid field must be a positive process id, got: {pid_text!r}"

    assert status == "verified", (
        f"status field must be exactly 'verified', got: {status!r}"
    )

def test_report_pid_is_live_correct_production_verifier_process(report_fields):
    pid = int(report_fields["pid_text"])
    cmdline = _read_cmdline_for_pid(pid)

    assert cmdline is not None, (
        f"Reported PID {pid} is not a readable live process. "
        "The PID in the report must still belong to the selected running verifier."
    )

    assert _process_matches_expected_args(cmdline, EXPECTED_PRODUCTION_ARGS), (
        f"Reported PID {pid} does not have the exact expected production verifier argv.\n"
        f"Expected contiguous argv sequence: {EXPECTED_PRODUCTION_ARGS!r}\n"
        f"Actual cmdline: {' '.join(cmdline)!r}"
    )

    cmd_text = " ".join(cmdline)

    for fragment in REQUIRED_CMD_FRAGMENTS:
        assert fragment in cmd_text, (
            f"Reported PID {pid} is missing required command fragment {fragment!r}.\n"
            f"Actual cmdline: {cmd_text!r}"
        )

    for sequence in FORBIDDEN_CMD_SEQUENCES:
        assert not _contains_contiguous_sequence(cmdline, sequence), (
            f"Reported PID {pid} appears to be a decoy because argv contains "
            f"forbidden sequence {sequence!r}.\n"
            f"Actual cmdline: {cmdline!r}"
        )

def test_only_one_live_user_process_matches_the_reported_production_identity(report_fields):
    reported_pid = int(report_fields["pid_text"])

    matches = [
        (pid, cmdline)
        for pid, cmdline in _iter_user_process_cmdlines()
        if _process_matches_expected_args(cmdline, EXPECTED_PRODUCTION_ARGS)
    ]

    assert len(matches) == 1, (
        "There must be exactly one live user-owned process matching the production "
        "verifier identity at final verification time.\n"
        f"Found {len(matches)} match(es):\n"
        + "\n".join(f"{pid}: {' '.join(cmd)}" for pid, cmd in matches)
    )

    actual_pid = matches[0][0]
    assert reported_pid == actual_pid, (
        "Report PID does not identify the single live production verifier.\n"
        f"Reported PID: {reported_pid}\n"
        f"Actual production verifier PID: {actual_pid}\n"
        f"Actual cmdline: {' '.join(matches[0][1])}"
    )

def test_evidence_contains_required_labels_exactly_once_with_nonempty_values(report_fields):
    evidence = report_fields["evidence"]

    assert evidence, "evidence field must be non-empty"
    assert "\t" not in evidence and "\n" not in evidence, (
        f"evidence must be a compact single TSV field, got: {evidence!r}"
    )

    for label in EVIDENCE_LABELS:
        count = evidence.count(label)
        assert count == 1, (
            f"evidence must contain label {label!r} exactly once; found {count} time(s).\n"
            f"Evidence: {evidence!r}"
        )

    label_positions = sorted((evidence.index(label), label) for label in EVIDENCE_LABELS)

    for idx, (start, label) in enumerate(label_positions):
        value_start = start + len(label)
        value_end = label_positions[idx + 1][0] if idx + 1 < len(label_positions) else len(evidence)
        value = evidence[value_start:value_end].strip(" ;,")

        assert value, (
            f"evidence label {label!r} must have a non-empty value after '='.\n"
            f"Evidence: {evidence!r}"
        )

def test_evidence_demonstrates_correct_selection_and_rejection_reasoning(report_fields):
    evidence = report_fields["evidence"]
    evidence_lower = evidence.lower()

    assert "vault-prod-west" in evidence, (
        "evidence must indicate the accepted production dataset vault-prod-west.\n"
        f"Evidence: {evidence!r}"
    )
    assert "2024Q4" in evidence, (
        "evidence must indicate the accepted production epoch 2024Q4.\n"
        f"Evidence: {evidence!r}"
    )
    assert "backup-integrity-worker" in evidence, (
        "evidence selected_cmd value should identify the backup-integrity-worker command.\n"
        f"Evidence: {evidence!r}"
    )

    rejection_hits = [
        reason for reason in REJECTION_REASON_SUBSTRINGS if reason in evidence_lower
    ]
    assert len(rejection_hits) >= 2, (
        "evidence rejected= value must mention at least two rejected candidate reasons "
        "from: wrong-dataset, dry-run, stale-epoch, helper.\n"
        f"Matched reasons: {rejection_hits!r}\n"
        f"Evidence: {evidence!r}"
    )


You are helping a data analyst clean up a small CSV export. The current input file is at `/home/user/analyst_workspace/raw/customer_export_legacy.csv`, but that file is now considered a legacy source and must not remain as the final source of truth.

Please create the canonical processed CSV at:

`/home/user/analyst_workspace/processed/customer_contact_canonical.csv`

The canonical CSV must contain exactly 4 comma-separated columns, in this exact order:

1. `customer_id`
2. `email`
3. `signup_date`
4. `region`

The legacy CSV has more columns than needed. Preserve the header row and all data rows, but only keep the four required columns listed above, reordered into the canonical order. Do not add quoting, spaces, extra blank lines, or additional columns.

After creating the canonical file, retire the legacy input by moving it to:

`/home/user/analyst_workspace/archive/customer_export_legacy.csv.retired`

The original path `/home/user/analyst_workspace/raw/customer_export_legacy.csv` should no longer exist when you are done.

Finally, create a verification log at:

`/home/user/analyst_workspace/processed/customer_contact_canonical.verify.log`

The log must contain exactly these three lines, in this order, with the actual values filled in from the final filesystem state:

```text
canonical_path=/home/user/analyst_workspace/processed/customer_contact_canonical.csv
canonical_rows=<number of lines in the canonical CSV, including the header>
legacy_path_retired=<yes-or-no>
```

Use `yes` only if `/home/user/analyst_workspace/raw/customer_export_legacy.csv` is gone and `/home/user/analyst_workspace/archive/customer_export_legacy.csv.retired` exists. Otherwise use `no`.

Before finishing, make sure you verify the canonical CSV and the verification log from the processed directory, not from the retired legacy file.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_764fc045"
description = "You are helping a data analyst clean up a small CSV export. The current input file is at `/home/user/analyst_workspace/raw/customer_export_legacy.csv`, but that file is now considered a legacy source and must not remain as the final source "
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 \
        coreutils \
        passwd

    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/analyst_workspace/raw
    mkdir -p /home/user/analyst_workspace/processed
    mkdir -p /home/user/analyst_workspace/archive

    cat > /home/user/analyst_workspace/raw/customer_export_legacy.csv <<'EOF'
region,customer_id,last_name,email,signup_date,plan
EMEA,C-1007,Nguyen,linh.nguyen@example.net,2023-08-14,pro
NA,C-1012,Patel,arjun.patel@example.net,2022-11-03,basic
APAC,C-1020,Okafor,mina.okafor@example.net,2024-01-27,enterprise
LATAM,C-1033,Silva,renata.silva@example.net,2023-05-09,pro
EOF

    rm -f /home/user/analyst_workspace/processed/customer_contact_canonical.csv
    rm -f /home/user/analyst_workspace/processed/customer_contact_canonical.verify.log
    rm -f /home/user/analyst_workspace/archive/customer_export_legacy.csv.retired

    chown -R user:user /home/user/analyst_workspace
    chmod 755 /home/user
    chmod 755 /home/user/analyst_workspace
    chmod 755 /home/user/analyst_workspace/raw
    chmod 755 /home/user/analyst_workspace/processed
    chmod 755 /home/user/analyst_workspace/archive
    chmod 644 /home/user/analyst_workspace/raw/customer_export_legacy.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
import csv
import io

import pytest

RAW_LEGACY_FILE = Path("/home/user/analyst_workspace/raw/customer_export_legacy.csv")
CANONICAL_FILE = Path("/home/user/analyst_workspace/processed/customer_contact_canonical.csv")
VERIFY_LOG = Path("/home/user/analyst_workspace/processed/customer_contact_canonical.verify.log")
RETIRED_LEGACY_FILE = Path("/home/user/analyst_workspace/archive/customer_export_legacy.csv.retired")

EXPECTED_CANONICAL_CONTENT = (
    "customer_id,email,signup_date,region\n"
    "C-1007,linh.nguyen@example.net,2023-08-14,EMEA\n"
    "C-1012,arjun.patel@example.net,2022-11-03,NA\n"
    "C-1020,mina.okafor@example.net,2024-01-27,APAC\n"
    "C-1033,renata.silva@example.net,2023-05-09,LATAM\n"
)

EXPECTED_RETIRED_LEGACY_CONTENT = (
    "region,customer_id,last_name,email,signup_date,plan\n"
    "EMEA,C-1007,Nguyen,linh.nguyen@example.net,2023-08-14,pro\n"
    "NA,C-1012,Patel,arjun.patel@example.net,2022-11-03,basic\n"
    "APAC,C-1020,Okafor,mina.okafor@example.net,2024-01-27,enterprise\n"
    "LATAM,C-1033,Silva,renata.silva@example.net,2023-05-09,pro\n"
)

EXPECTED_VERIFY_LOG_CONTENT = (
    "canonical_path=/home/user/analyst_workspace/processed/customer_contact_canonical.csv\n"
    "canonical_rows=5\n"
    "legacy_path_retired=yes\n"
)

def _read_text(path: Path) -> str:
    try:
        return path.read_text(encoding="utf-8")
    except FileNotFoundError:
        pytest.fail(f"Expected file is missing: {path}")

def test_original_raw_legacy_path_has_been_retired_and_no_longer_exists():
    assert not RAW_LEGACY_FILE.exists(), (
        "The original legacy CSV path still exists, but it must be retired by moving it away.\n"
        f"Stale path that must be absent: {RAW_LEGACY_FILE}"
    )

def test_canonical_csv_exists_at_exact_processed_path():
    assert CANONICAL_FILE.exists(), (
        "Canonical processed CSV was not created at the required absolute path.\n"
        f"Expected path: {CANONICAL_FILE}"
    )
    assert CANONICAL_FILE.is_file(), (
        "Canonical processed CSV path exists but is not a regular file.\n"
        f"Path: {CANONICAL_FILE}"
    )

def test_canonical_csv_has_exact_expected_contents():
    actual = _read_text(CANONICAL_FILE)
    assert actual == EXPECTED_CANONICAL_CONTENT, (
        "Canonical CSV contents are not exactly correct. It must contain only the four required "
        "columns in the order customer_id,email,signup_date,region, preserve all rows, and have "
        "no extra spaces, quotes, columns, or blank lines.\n"
        f"Path checked: {CANONICAL_FILE}"
    )

def test_canonical_csv_is_valid_four_column_csv_with_expected_rows():
    actual = _read_text(CANONICAL_FILE)

    assert actual.endswith("\n"), (
        "Canonical CSV should end with exactly the expected final newline and no missing trailing newline.\n"
        f"Path checked: {CANONICAL_FILE}"
    )

    lines = actual.splitlines()
    assert len(lines) == 5, (
        "Canonical CSV must have exactly 5 lines including the header.\n"
        f"Actual line count: {len(lines)}\n"
        f"Path checked: {CANONICAL_FILE}"
    )

    rows = list(csv.reader(io.StringIO(actual), strict=True))
    expected_rows = [
        ["customer_id", "email", "signup_date", "region"],
        ["C-1007", "linh.nguyen@example.net", "2023-08-14", "EMEA"],
        ["C-1012", "arjun.patel@example.net", "2022-11-03", "NA"],
        ["C-1020", "mina.okafor@example.net", "2024-01-27", "APAC"],
        ["C-1033", "renata.silva@example.net", "2023-05-09", "LATAM"],
    ]

    assert rows == expected_rows, (
        "Canonical CSV parsed rows are incorrect. The file must be derived from the legacy CSV "
        "using columns customer_id, email, signup_date, region in that exact order.\n"
        f"Path checked: {CANONICAL_FILE}"
    )

    bad_widths = [(index + 1, len(row), row) for index, row in enumerate(rows) if len(row) != 4]
    assert not bad_widths, (
        "Canonical CSV must contain exactly 4 comma-separated columns on every row.\n"
        f"Rows with wrong column counts: {bad_widths}\n"
        f"Path checked: {CANONICAL_FILE}"
    )

def test_retired_legacy_file_exists_at_exact_archive_path():
    assert RETIRED_LEGACY_FILE.exists(), (
        "Retired legacy CSV is missing from the required archive path. The legacy file should "
        "have been moved, not merely copied or left in raw.\n"
        f"Expected retired path: {RETIRED_LEGACY_FILE}"
    )
    assert RETIRED_LEGACY_FILE.is_file(), (
        "Retired legacy CSV path exists but is not a regular file.\n"
        f"Path: {RETIRED_LEGACY_FILE}"
    )

def test_retired_legacy_file_preserves_original_contents_exactly():
    actual = _read_text(RETIRED_LEGACY_FILE)
    assert actual == EXPECTED_RETIRED_LEGACY_CONTENT, (
        "Retired legacy CSV contents do not exactly match the original six-column legacy export. "
        "The archive copy must preserve the original file exactly.\n"
        f"Path checked: {RETIRED_LEGACY_FILE}"
    )

def test_verification_log_exists_at_exact_processed_path():
    assert VERIFY_LOG.exists(), (
        "Verification log was not created at the required processed path.\n"
        f"Expected path: {VERIFY_LOG}"
    )
    assert VERIFY_LOG.is_file(), (
        "Verification log path exists but is not a regular file.\n"
        f"Path: {VERIFY_LOG}"
    )

def test_verification_log_has_exact_expected_contents():
    actual = _read_text(VERIFY_LOG)
    assert actual == EXPECTED_VERIFY_LOG_CONTENT, (
        "Verification log contents are not exactly correct. It must contain exactly the required "
        "three lines with canonical_rows=5 and legacy_path_retired=yes.\n"
        f"Path checked: {VERIFY_LOG}"
    )

def test_verification_log_values_match_final_filesystem_state():
    actual = _read_text(VERIFY_LOG)
    lines = actual.splitlines()

    assert lines == [
        "canonical_path=/home/user/analyst_workspace/processed/customer_contact_canonical.csv",
        "canonical_rows=5",
        "legacy_path_retired=yes",
    ], (
        "Verification log must contain exactly three lines in the required order and with values "
        "computed from the final filesystem state.\n"
        f"Actual lines: {lines!r}\n"
        f"Path checked: {VERIFY_LOG}"
    )

    canonical_line_count = len(_read_text(CANONICAL_FILE).splitlines())
    assert canonical_line_count == 5, (
        "The verification log reports canonical_rows=5, but the canonical CSV does not actually "
        "have exactly 5 lines.\n"
        f"Actual canonical line count: {canonical_line_count}\n"
        f"Canonical path checked: {CANONICAL_FILE}"
    )

    retired_state_is_yes = (not RAW_LEGACY_FILE.exists()) and RETIRED_LEGACY_FILE.exists()
    assert retired_state_is_yes, (
        "The verification log must report legacy_path_retired=yes only when the raw legacy path "
        "is gone and the retired archive file exists. The final filesystem state does not satisfy this.\n"
        f"Raw legacy path exists: {RAW_LEGACY_FILE.exists()} ({RAW_LEGACY_FILE})\n"
        f"Retired legacy path exists: {RETIRED_LEGACY_FILE.exists()} ({RETIRED_LEGACY_FILE})"
    )

#!/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


I’m working on a small developer utility and need its time zone / locale behavior made deterministic.

The project is in `/home/user/clockutil`. There is an existing Python script at:

`/home/user/clockutil/format_deadline.py`

It reads configuration from:

`/home/user/clockutil/deadline.env`

and writes a report to:

`/home/user/clockutil/out/deadline_report.txt`

The script currently runs without crashing, but its output is not reliable because it formats the configured epoch using the process/default time zone and locale instead of the values in the env file.

Please update the utility so that it uses the configuration in `/home/user/clockutil/deadline.env` to format the deadline deterministically.

The env file contains these keys:

- `APP_TZ`: an IANA time zone name
- `APP_LOCALE`: the locale name that should control weekday/month abbreviations
- `DEADLINE_EPOCH`: a Unix timestamp in seconds

The generated report at `/home/user/clockutil/out/deadline_report.txt` must contain exactly three newline-terminated lines in this format:

```text
timezone=<APP_TZ value>
locale=<APP_LOCALE value>
deadline=<weekday abbreviation> <YYYY-MM-DD> <HH:MM:SS> <time zone abbreviation>
```

Formatting requirements:

- The deadline must be calculated from `DEADLINE_EPOCH`.
- The displayed local time must be in the time zone named by `APP_TZ`.
- The weekday abbreviation must follow the locale named by `APP_LOCALE`.
- For the provided config, the locale is the standard C locale, so weekday abbreviations should be English-style abbreviations such as `Mon`, `Tue`, etc.
- The output file must not contain extra blank lines, comments, debug text, or trailing spaces.

After fixing the script, run it and verify the artifact itself, not just the command exit code. Then create a verification log at:

`/home/user/clockutil/out/verification.log`

The verification log must contain exactly these four newline-terminated lines:

```text
artifact=/home/user/clockutil/out/deadline_report.txt
exists=yes
format=valid
status=verified
```

Stop only after the report file exists, has the required three-line format, and the verification log has been written exactly as specified.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_7c8d0454"
description = "I\u2019m working on a small developer utility and need its time zone / locale behavior made deterministic."
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-pytest \
        tzdata \
        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/clockutil/out

    cat > /home/user/clockutil/deadline.env <<'EOF'
APP_TZ=Europe/Berlin
APP_LOCALE=C
DEADLINE_EPOCH=1704067200
EOF

    cat > /home/user/clockutil/format_deadline.py <<'EOF'
#!/usr/bin/env python3
from datetime import datetime
from pathlib import Path

BASE = Path("/home/user/clockutil")
CONFIG = BASE / "deadline.env"
OUT = BASE / "out" / "deadline_report.txt"

def read_env(path):
    values = {}
    for line in path.read_text().splitlines():
        if not line.strip() or line.startswith("#"):
            continue
        key, value = line.split("=", 1)
        values[key] = value
    return values

def main():
    cfg = read_env(CONFIG)
    epoch = int(cfg["DEADLINE_EPOCH"])

    # BUG: ignores APP_TZ and APP_LOCALE; formats in UTC.
    dt = datetime.utcfromtimestamp(epoch)
    rendered = dt.strftime("%a %Y-%m-%d %H:%M:%S UTC")

    OUT.parent.mkdir(parents=True, exist_ok=True)
    OUT.write_text(
        f"timezone=UTC\n"
        f"locale=default\n"
        f"deadline={rendered}\n"
    )

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

    chmod 0755 /home/user/clockutil/format_deadline.py
    chmod 0664 /home/user/clockutil/deadline.env
    chmod 0775 /home/user/clockutil /home/user/clockutil/out

    chown -R user:user /home/user/clockutil
    chown user:user /home/user

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

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

BASE = Path("/home/user/clockutil")
ENV_FILE = Path("/home/user/clockutil/deadline.env")
SCRIPT = Path("/home/user/clockutil/format_deadline.py")
OUT_DIR = Path("/home/user/clockutil/out")
REPORT = Path("/home/user/clockutil/out/deadline_report.txt")
VERIFY_LOG = Path("/home/user/clockutil/out/verification.log")

EXPECTED_ENV_TEXT = (
    "APP_TZ=Europe/Berlin\n"
    "APP_LOCALE=C\n"
    "DEADLINE_EPOCH=1704067200\n"
)

EXPECTED_REPORT_TEXT = (
    "timezone=Europe/Berlin\n"
    "locale=C\n"
    "deadline=Mon 2024-01-01 01:00:00 CET\n"
)

EXPECTED_VERIFY_LOG_TEXT = (
    "artifact=/home/user/clockutil/out/deadline_report.txt\n"
    "exists=yes\n"
    "format=valid\n"
    "status=verified\n"
)

def _read_bytes(path: Path) -> bytes:
    assert path.is_file(), f"Missing required file: {path}"
    return path.read_bytes()

def _assert_exact_text_file(path: Path, expected: str, description: str) -> None:
    actual_bytes = _read_bytes(path)
    expected_bytes = expected.encode("utf-8")

    assert actual_bytes == expected_bytes, (
        f"{description} at {path} does not match the exact required final contents.\n"
        f"Expected bytes/text:\n{expected_bytes!r}\n"
        f"Actual bytes/text:\n{actual_bytes!r}"
    )

def _assert_no_trailing_spaces(path: Path, description: str) -> None:
    text = path.read_text(encoding="utf-8")
    for line_number, line in enumerate(text.splitlines(), start=1):
        assert not line.endswith((" ", "\t")), (
            f"{description} at {path} has trailing whitespace on line {line_number}: {line!r}"
        )

def test_project_files_and_directories_exist_after_completion():
    assert BASE.is_dir(), "Missing required project directory after task completion: /home/user/clockutil"
    assert OUT_DIR.is_dir(), "Missing required output directory after task completion: /home/user/clockutil/out"
    assert ENV_FILE.is_file(), "Missing required config file after task completion: /home/user/clockutil/deadline.env"
    assert SCRIPT.is_file(), "Missing required script after task completion: /home/user/clockutil/format_deadline.py"

    for path in (BASE, OUT_DIR):
        assert os.access(path, os.R_OK), f"Directory is not readable: {path}"
        assert os.access(path, os.W_OK), f"Directory is not writable: {path}"
        assert os.access(path, os.X_OK), f"Directory is not searchable/executable: {path}"

    for path in (ENV_FILE, SCRIPT):
        assert os.access(path, os.R_OK), f"File is not readable: {path}"
        assert os.access(path, os.W_OK), f"File is not writable: {path}"

def test_config_file_remains_exactly_the_required_configuration():
    _assert_exact_text_file(
        ENV_FILE,
        EXPECTED_ENV_TEXT,
        "Config file /home/user/clockutil/deadline.env",
    )

def test_format_deadline_script_is_valid_python_and_runs_cleanly():
    try:
        py_compile.compile(str(SCRIPT), doraise=True)
    except py_compile.PyCompileError as exc:
        raise AssertionError(
            "Script /home/user/clockutil/format_deadline.py is not valid parseable Python"
        ) from exc

    result = subprocess.run(
        [sys.executable, "/home/user/clockutil/format_deadline.py"],
        cwd="/home/user/clockutil",
        text=True,
        capture_output=True,
        timeout=10,
        check=False,
    )

    assert result.returncode == 0, (
        "Running /home/user/clockutil/format_deadline.py with Python must complete "
        "without an unhandled exception.\n"
        f"Exit code: {result.returncode}\n"
        f"stdout:\n{result.stdout!r}\n"
        f"stderr:\n{result.stderr!r}"
    )

def test_report_artifact_exists_and_has_exact_required_three_line_format():
    assert REPORT.is_file(), (
        "Report artifact was not created at the required absolute path: "
        "/home/user/clockutil/out/deadline_report.txt"
    )

    actual = REPORT.read_text(encoding="utf-8")
    assert actual.endswith("\n"), (
        "Report artifact must be newline-terminated: "
        "/home/user/clockutil/out/deadline_report.txt"
    )

    lines = actual.splitlines()
    assert len(lines) == 3, (
        "Report artifact must contain exactly three newline-terminated lines "
        "with no extra blank lines or debug text.\n"
        f"Actual line count: {len(lines)}\n"
        f"Actual contents: {actual!r}"
    )

    expected_prefixes = ["timezone=", "locale=", "deadline="]
    for index, expected_prefix in enumerate(expected_prefixes):
        assert lines[index].startswith(expected_prefix), (
            f"Report line {index + 1} must begin exactly with {expected_prefix!r}.\n"
            f"Actual line {index + 1}: {lines[index]!r}\n"
            f"Full report: {actual!r}"
        )

    _assert_no_trailing_spaces(REPORT, "Report artifact")

    assert actual == EXPECTED_REPORT_TEXT, (
        "Report artifact exists and is syntactically shaped like a report, but its "
        "semantic time zone / locale output is still wrong. The script must use "
        "APP_TZ=Europe/Berlin, APP_LOCALE=C, and DEADLINE_EPOCH=1704067200 to produce "
        "the Berlin/CET local deadline.\n"
        f"Expected exact report:\n{EXPECTED_REPORT_TEXT!r}\n"
        f"Actual report:\n{actual!r}"
    )

def test_report_is_not_the_known_initial_buggy_utc_default_output():
    actual = REPORT.read_text(encoding="utf-8") if REPORT.exists() else ""
    known_buggy_output = (
        "timezone=UTC\n"
        "locale=default\n"
        "deadline=Mon 2024-01-01 00:00:00 UTC\n"
    )

    assert actual != known_buggy_output, (
        "Report is still the known initial buggy output. Command success and artifact "
        "existence are not sufficient; /home/user/clockutil/format_deadline.py must be "
        "fixed to use APP_TZ and APP_LOCALE from /home/user/clockutil/deadline.env."
    )

def test_verification_log_exists_and_matches_exact_required_contents():
    assert VERIFY_LOG.is_file(), (
        "Verification log was not created at the required absolute path: "
        "/home/user/clockutil/out/verification.log"
    )

    actual = VERIFY_LOG.read_text(encoding="utf-8")
    assert actual.endswith("\n"), (
        "Verification log must be newline-terminated: "
        "/home/user/clockutil/out/verification.log"
    )

    lines = actual.splitlines()
    assert len(lines) == 4, (
        "Verification log must contain exactly four newline-terminated lines "
        "with no extra blank lines, comments, or debug text.\n"
        f"Actual line count: {len(lines)}\n"
        f"Actual contents: {actual!r}"
    )

    _assert_no_trailing_spaces(VERIFY_LOG, "Verification log")

    assert actual == EXPECTED_VERIFY_LOG_TEXT, (
        "Verification log does not match the exact required final contents.\n"
        f"Expected exact verification log:\n{EXPECTED_VERIFY_LOG_TEXT!r}\n"
        f"Actual verification log:\n{actual!r}"
    )

def test_final_verified_stop_state_both_artifacts_match_exactly():
    report_text = REPORT.read_text(encoding="utf-8") if REPORT.exists() else None
    verify_text = VERIFY_LOG.read_text(encoding="utf-8") if VERIFY_LOG.exists() else None

    assert report_text == EXPECTED_REPORT_TEXT and verify_text == EXPECTED_VERIFY_LOG_TEXT, (
        "Final verified stop state has not been reached. Both final files must match "
        "exactly at the same time:\n"
        "- /home/user/clockutil/out/deadline_report.txt\n"
        "- /home/user/clockutil/out/verification.log\n"
        f"Actual report: {report_text!r}\n"
        f"Actual verification log: {verify_text!r}"
    )


You are helping a security engineer finish a small credential-rotation cleanup in a user-owned workspace. The work is under `/home/user/rotation`, and you do not need root privileges.

The sensitive rotated credential is stored in the directory `/home/user/rotation/current.secret.d`. A previous hardening attempt focused only on the directory itself, but the security scanner is still expected to flag the exposed credential file inside it. Do not keep retrying a directory-only permission change if the file exposure remains unchanged; inspect or reason about the actual object that needs its permissions changed and use the appropriate permission operation.

Bring the credential area to this final state:

- `/home/user/rotation/current.secret.d` must be accessible only by its owner:
  - owner may read, write, and enter the directory
  - group and others must have no permissions
- `/home/user/rotation/current.secret.d/token.txt` must be readable and writable only by its owner:
  - owner may read and write
  - group and others must have no permissions
  - it must not be executable
- Do not delete, rename, truncate, or modify the contents of `/home/user/rotation/current.secret.d/token.txt`.

After applying the permission fix, create an audit log at:

`/home/user/rotation/audit/credential-rotation.log`

The log file must contain exactly these three lines, with no extra blank lines before or after:

`ROTATION_AUDIT v1`
`/home/user/rotation/current.secret.d mode=700`
`/home/user/rotation/current.secret.d/token.txt mode=600`

The automated check will verify both the permissions and the exact contents of the audit log. You may use any normal terminal tools available to you, but the final state above is what matters.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_846f1173"
description = "You are helping a security engineer finish a small credential-rotation cleanup in a user-owned workspace. The work is under `/home/user/rotation`, and you do not need root privileges."
authors = [{ name = "Endless Terminals / Jarrod Barnes" }]
keywords = ["agentic-rl", "endless-terminals", "recognition_to_action_coupling", "repeat_loop_after_dead_end", "terminal-bench-2"]

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

[verifier]
timeout_sec = 300.0
user = "root"

[agent]
timeout_sec = 900.0
user = "user"

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

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

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

    mkdir -p /home/user/rotation/current.secret.d
    mkdir -p /home/user/rotation/audit

    printf 'rotated-service-token:tb-simple-perm-pivot-2026\n' > /home/user/rotation/current.secret.d/token.txt

    chown -R user:user /home/user/rotation
    chown user:user /home/user

    chmod 0755 /home/user
    chmod 0755 /home/user/rotation
    chmod 0755 /home/user/rotation/audit
    chmod 0644 /home/user/rotation/current.secret.d/token.txt
    chmod 0600 /home/user/rotation/current.secret.d

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

# test_final_state.py
import hashlib
import os
import stat
from pathlib import Path

import pytest

ROTATION_DIR = Path("/home/user/rotation")
SECRET_DIR = Path("/home/user/rotation/current.secret.d")
TOKEN_FILE = Path("/home/user/rotation/current.secret.d/token.txt")
AUDIT_DIR = Path("/home/user/rotation/audit")
AUDIT_LOG = Path("/home/user/rotation/audit/credential-rotation.log")

EXPECTED_TOKEN_BYTES = b"rotated-service-token:tb-simple-perm-pivot-2026\n"
EXPECTED_TOKEN_SHA256 = hashlib.sha256(EXPECTED_TOKEN_BYTES).hexdigest()

EXPECTED_AUDIT_BYTES = (
    b"ROTATION_AUDIT v1\n"
    b"/home/user/rotation/current.secret.d mode=700\n"
    b"/home/user/rotation/current.secret.d/token.txt mode=600\n"
)

def _mode(path: Path) -> int:
    return stat.S_IMODE(path.stat().st_mode)

def _mode_str(path: Path) -> str:
    return f"{_mode(path):04o}"

def _assert_owned_by_current_user(path: Path) -> None:
    current_uid = os.getuid()
    actual_uid = path.stat().st_uid
    assert actual_uid == current_uid, (
        f"{path} must be owned by the current unprivileged user uid={current_uid}, "
        f"but it is owned by uid={actual_uid}"
    )

def test_required_workspace_paths_exist_and_are_expected_types():
    assert ROTATION_DIR.exists(), f"Workspace directory is missing: {ROTATION_DIR}"
    assert ROTATION_DIR.is_dir(), f"Workspace path exists but is not a directory: {ROTATION_DIR}"
    _assert_owned_by_current_user(ROTATION_DIR)

    assert SECRET_DIR.exists(), f"Credential directory is missing: {SECRET_DIR}"
    assert SECRET_DIR.is_dir(), (
        f"Credential path must remain a directory, but it is not: {SECRET_DIR}"
    )
    _assert_owned_by_current_user(SECRET_DIR)

    assert TOKEN_FILE.exists(), f"Credential token file is missing: {TOKEN_FILE}"
    assert TOKEN_FILE.is_file(), (
        f"Credential token path must remain a regular file, but it is not: {TOKEN_FILE}"
    )
    _assert_owned_by_current_user(TOKEN_FILE)

    assert AUDIT_DIR.exists(), f"Audit directory is missing: {AUDIT_DIR}"
    assert AUDIT_DIR.is_dir(), f"Audit path exists but is not a directory: {AUDIT_DIR}"
    _assert_owned_by_current_user(AUDIT_DIR)

def test_secret_directory_mode_is_exactly_0700():
    assert SECRET_DIR.exists(), f"Credential directory is missing: {SECRET_DIR}"
    assert SECRET_DIR.is_dir(), f"Credential path is not a directory: {SECRET_DIR}"

    actual_mode = _mode(SECRET_DIR)
    assert actual_mode == 0o700, (
        f"{SECRET_DIR} must have exact final mode 0700 so only the owner can "
        f"read, write, and enter it. Actual mode is {_mode_str(SECRET_DIR)}. "
        f"If it is still 0600, the owner execute/search bit is still missing; "
        f"if group/other bits are present, the directory is still exposed."
    )

    assert actual_mode & stat.S_IRUSR, f"{SECRET_DIR} is missing owner read permission"
    assert actual_mode & stat.S_IWUSR, f"{SECRET_DIR} is missing owner write permission"
    assert actual_mode & stat.S_IXUSR, f"{SECRET_DIR} is missing owner execute/enter permission"
    assert actual_mode & (stat.S_IRWXG | stat.S_IRWXO) == 0, (
        f"{SECRET_DIR} must grant no permissions to group or others, "
        f"but actual mode is {_mode_str(SECRET_DIR)}"
    )

def test_token_file_mode_is_exactly_0600_and_not_executable():
    assert TOKEN_FILE.exists(), f"Credential token file is missing: {TOKEN_FILE}"
    assert TOKEN_FILE.is_file(), (
        f"Credential token path must be a regular file, but it is not: {TOKEN_FILE}"
    )

    actual_mode = _mode(TOKEN_FILE)
    assert actual_mode == 0o600, (
        f"{TOKEN_FILE} must have exact final mode 0600: readable and writable "
        f"only by its owner, with no execute bits. Actual mode is {_mode_str(TOKEN_FILE)}. "
        f"If it is still 0644, the file exposure was not fixed."
    )

    assert actual_mode & stat.S_IRUSR, f"{TOKEN_FILE} is missing owner read permission"
    assert actual_mode & stat.S_IWUSR, f"{TOKEN_FILE} is missing owner write permission"
    assert not (actual_mode & stat.S_IXUSR), f"{TOKEN_FILE} must not be executable by owner"
    assert actual_mode & (stat.S_IRWXG | stat.S_IRWXO) == 0, (
        f"{TOKEN_FILE} must grant no permissions to group or others, "
        f"but actual mode is {_mode_str(TOKEN_FILE)}"
    )

def test_token_file_contents_are_unchanged_byte_for_byte():
    assert TOKEN_FILE.exists(), f"Credential token file is missing: {TOKEN_FILE}"
    assert TOKEN_FILE.is_file(), (
        f"Credential token path must be a regular file, but it is not: {TOKEN_FILE}"
    )

    actual_bytes = TOKEN_FILE.read_bytes()
    actual_sha256 = hashlib.sha256(actual_bytes).hexdigest()

    assert actual_bytes == EXPECTED_TOKEN_BYTES, (
        f"{TOKEN_FILE} contents must remain byte-for-byte unchanged. "
        f"Expected sha256={EXPECTED_TOKEN_SHA256}, actual sha256={actual_sha256}. "
        f"The token file must not be deleted, renamed, truncated, or modified."
    )

def test_audit_log_exists_as_regular_file_with_exact_contents():
    assert AUDIT_LOG.exists(), f"Required audit log was not created: {AUDIT_LOG}"
    assert AUDIT_LOG.is_file(), (
        f"Audit log path must be a regular file, but it is not: {AUDIT_LOG}"
    )
    _assert_owned_by_current_user(AUDIT_LOG)

    actual_bytes = AUDIT_LOG.read_bytes()
    assert actual_bytes == EXPECTED_AUDIT_BYTES, (
        f"{AUDIT_LOG} must contain exactly three lines with final modes and no "
        f"extra spaces, carriage returns, missing final newline, or blank lines. "
        f"Expected bytes: {EXPECTED_AUDIT_BYTES!r}; actual bytes: {actual_bytes!r}"
    )

def test_final_permission_and_audit_invariant_together():
    problems = []

    if not SECRET_DIR.exists():
        problems.append(f"{SECRET_DIR} is missing")
    elif not SECRET_DIR.is_dir():
        problems.append(f"{SECRET_DIR} is not a directory")
    elif _mode(SECRET_DIR) != 0o700:
        problems.append(
            f"{SECRET_DIR} mode is {_mode_str(SECRET_DIR)}, expected 0700"
        )

    if not TOKEN_FILE.exists():
        problems.append(f"{TOKEN_FILE} is missing")
    elif not TOKEN_FILE.is_file():
        problems.append(f"{TOKEN_FILE} is not a regular file")
    else:
        if _mode(TOKEN_FILE) != 0o600:
            problems.append(
                f"{TOKEN_FILE} mode is {_mode_str(TOKEN_FILE)}, expected 0600"
            )
        actual_token_bytes = TOKEN_FILE.read_bytes()
        if actual_token_bytes != EXPECTED_TOKEN_BYTES:
            problems.append(
                f"{TOKEN_FILE} content changed; expected sha256={EXPECTED_TOKEN_SHA256}, "
                f"actual sha256={hashlib.sha256(actual_token_bytes).hexdigest()}"
            )

    if not AUDIT_LOG.exists():
        problems.append(f"{AUDIT_LOG} is missing")
    elif not AUDIT_LOG.is_file():
        problems.append(f"{AUDIT_LOG} is not a regular file")
    else:
        actual_audit_bytes = AUDIT_LOG.read_bytes()
        if actual_audit_bytes != EXPECTED_AUDIT_BYTES:
            problems.append(
                f"{AUDIT_LOG} content is not exact; expected {EXPECTED_AUDIT_BYTES!r}, "
                f"actual {actual_audit_bytes!r}"
            )

    assert not problems, "Final credential-rotation state is incomplete:\n- " + "\n- ".join(problems)


You are helping maintain a mobile CI build pipeline in `/home/user/mobile-ci-firewall`. The pipeline generates an emulator firewall allowlist artifact from a small YAML policy file, and the Android build jobs consume the generated artifact.

Please update the firewall artifact so the mobile build runner can reach only the required services. Work entirely in `/home/user/mobile-ci-firewall`; you do not need root access and you should not modify the system firewall. The relevant files are:

- `/home/user/mobile-ci-firewall/firewall-policy.yml`
- `/home/user/mobile-ci-firewall/generate_rules.py`
- `/home/user/mobile-ci-firewall/out/emulator-firewall.rules`
- `/home/user/mobile-ci-firewall/verification.log`

The desired final artifact is `/home/user/mobile-ci-firewall/out/emulator-firewall.rules`. It must be a plain text file with exactly these structural requirements:

1. The first line must be exactly:
   `# emulator firewall allowlist v1`
2. Each following line must be one firewall rule in this exact format:
   `ALLOW tcp <host> <port> # <service>`
3. `<host>` must come from the `host` field in `/home/user/mobile-ci-firewall/firewall-policy.yml`.
4. `<port>` must come from the `port` field in `/home/user/mobile-ci-firewall/firewall-policy.yml`.
5. `<service>` must come from the `service` field in `/home/user/mobile-ci-firewall/firewall-policy.yml`.
6. Rules must be sorted in ascending numeric order by port.
7. The artifact must contain one rule for every enabled policy entry and no rules for disabled entries.
8. There must be no duplicate rules and no blank lines.

Important: there is already a generator script in the directory. It may run successfully even if the generated artifact is not the correct deliverable, so do not stop just because a command exits with code 0. Inspect the policy and the generated artifact, and fix the generation logic or artifact as needed so that the final file satisfies the requirements above.

After the artifact is correct, create `/home/user/mobile-ci-firewall/verification.log`. The file must contain exactly five lines, in this order, with this exact key format:

`command_completed=<yes-or-no>`
`artifact_exists=<yes-or-no>`
`artifact_format_valid=<yes-or-no>`
`artifact_semantics_valid=<yes-or-no>`
`verified_stop=<yes-or-no>`

Use `yes` only for checks you actually verified. The automated checker will read both `/home/user/mobile-ci-firewall/out/emulator-firewall.rules` and `/home/user/mobile-ci-firewall/verification.log`, so make sure the verification log reflects the final state of the artifact. Stop when the artifact and verification log are both correct.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_905cb90e"
description = "You are helping maintain a mobile CI build pipeline in `/home/user/mobile-ci-firewall`. The pipeline generates an emulator firewall allowlist artifact from a small YAML policy file, and the Android build jobs consume the generated artifact."
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

    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/mobile-ci-firewall/out

    cat > /home/user/mobile-ci-firewall/firewall-policy.yml <<'EOF'
# Mobile CI emulator network policy
# Only enabled entries should be emitted to out/emulator-firewall.rules.
rules:
  - service: gradle-cache
    host: cache.mobile-ci.internal
    port: 5071
    enabled: true
  - service: android-sdk-mirror
    host: sdk-mirror.mobile-ci.internal
    port: 8443
    enabled: true
  - service: metrics-preview
    host: metrics-preview.mobile-ci.internal
    port: 9090
    enabled: false
  - service: signing-api
    host: signing.mobile-ci.internal
    port: 443
    enabled: true
EOF

    cat > /home/user/mobile-ci-firewall/generate_rules.py <<'EOF'
#!/usr/bin/env python3
from pathlib import Path
import re

base = Path("/home/user/mobile-ci-firewall")
policy = base / "firewall-policy.yml"
out = base / "out" / "emulator-firewall.rules"
out.parent.mkdir(parents=True, exist_ok=True)

text = policy.read_text()

entries = []
current = {}
for raw in text.splitlines():
    line = raw.strip()
    if line.startswith("- service:"):
        if current:
            entries.append(current)
        current = {"service": line.split(":", 1)[1].strip()}
    elif ":" in line and current:
        key, value = line.split(":", 1)
        current[key.strip()] = value.strip()
if current:
    entries.append(current)

# BUG: this generator only checks for the presence of an enabled field,
# not whether it is true, and preserves policy order rather than sorting.
enabled_entries = [e for e in entries if "enabled" in e]

lines = ["# emulator firewall allowlist v1"]
for e in enabled_entries:
    lines.append(f"ALLOW tcp {e['host']} {e['port']} # {e['service']}")

out.write_text("\n".join(lines) + "\n")
print(f"wrote {out}")
EOF

    cat > /home/user/mobile-ci-firewall/out/emulator-firewall.rules <<'EOF'
# stale local firewall artifact
ALLOW tcp old-cache.mobile-ci.internal 80 # old-cache
EOF

    rm -f /home/user/mobile-ci-firewall/verification.log

    chmod 755 /home/user
    chmod 755 /home/user/mobile-ci-firewall
    chmod 755 /home/user/mobile-ci-firewall/out
    chmod 644 /home/user/mobile-ci-firewall/firewall-policy.yml
    chmod 755 /home/user/mobile-ci-firewall/generate_rules.py
    chmod 644 /home/user/mobile-ci-firewall/out/emulator-firewall.rules

    chown -R user:user /home/user/mobile-ci-firewall
    chown user:user /home/user

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

BASE = Path("/home/user/mobile-ci-firewall")
POLICY = Path("/home/user/mobile-ci-firewall/firewall-policy.yml")
ARTIFACT = Path("/home/user/mobile-ci-firewall/out/emulator-firewall.rules")
VERIFICATION_LOG = Path("/home/user/mobile-ci-firewall/verification.log")

EXPECTED_ARTIFACT = """# emulator firewall allowlist v1
ALLOW tcp signing.mobile-ci.internal 443 # signing-api
ALLOW tcp cache.mobile-ci.internal 5071 # gradle-cache
ALLOW tcp sdk-mirror.mobile-ci.internal 8443 # android-sdk-mirror
"""

EXPECTED_VERIFICATION_LOG = """command_completed=yes
artifact_exists=yes
artifact_format_valid=yes
artifact_semantics_valid=yes
verified_stop=yes
"""

RULE_RE = re.compile(r"^ALLOW tcp [A-Za-z0-9.-]+ [0-9]+ # [A-Za-z0-9._-]+$")

def _read_text_exact(path: Path) -> str:
    try:
        return path.read_text()
    except FileNotFoundError:
        raise AssertionError(f"Required file is missing: {path}")
    except UnicodeDecodeError as exc:
        raise AssertionError(f"{path} must be a plain UTF-8 text file") from exc

def _parse_policy_entries(policy_text: str):
    """
    Minimal parser for the simple policy structure used by this task.
    It intentionally avoids third-party YAML dependencies.
    """
    entries = []
    current = None

    for raw in policy_text.splitlines():
        line = raw.strip()
        if not line or line.startswith("#") or line == "rules:":
            continue

        if line.startswith("- service:"):
            if current is not None:
                entries.append(current)
            current = {"service": line.split(":", 1)[1].strip()}
            continue

        if current is not None and ":" in line:
            key, value = line.split(":", 1)
            current[key.strip()] = value.strip()

    if current is not None:
        entries.append(current)

    return entries

def _expected_artifact_from_policy() -> str:
    policy_text = _read_text_exact(POLICY)
    entries = _parse_policy_entries(policy_text)

    enabled_entries = []
    disabled_services = []

    for entry in entries:
        missing = {"service", "host", "port", "enabled"} - set(entry)
        assert not missing, (
            f"{POLICY} contains a policy entry missing required field(s) "
            f"{sorted(missing)}: {entry!r}"
        )

        enabled_value = entry["enabled"].lower()
        if enabled_value == "true":
            try:
                numeric_port = int(entry["port"])
            except ValueError as exc:
                raise AssertionError(
                    f"{POLICY} has a non-numeric port for service "
                    f"{entry['service']!r}: {entry['port']!r}"
                ) from exc
            enabled_entries.append((numeric_port, entry))
        elif enabled_value == "false":
            disabled_services.append(entry["service"])
        else:
            raise AssertionError(
                f"{POLICY} has invalid enabled value for service "
                f"{entry['service']!r}: {entry['enabled']!r}; expected true or false"
            )

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

    lines = ["# emulator firewall allowlist v1"]
    for numeric_port, entry in enabled_entries:
        lines.append(
            f"ALLOW tcp {entry['host']} {numeric_port} # {entry['service']}"
        )

    return "\n".join(lines) + "\n"

def test_artifact_file_exists_as_regular_plain_text_file():
    assert BASE.is_dir(), f"Required working directory is missing: {BASE}"
    assert ARTIFACT.exists(), f"Final firewall artifact does not exist: {ARTIFACT}"
    assert ARTIFACT.is_file(), f"Final firewall artifact is not a regular file: {ARTIFACT}"

    data = ARTIFACT.read_bytes()
    assert b"\x00" not in data, f"{ARTIFACT} contains NUL bytes and is not plain text"

    try:
        data.decode("utf-8")
    except UnicodeDecodeError as exc:
        raise AssertionError(f"{ARTIFACT} must be readable as UTF-8 plain text") from exc

def test_artifact_has_exact_required_format_no_blanks_no_duplicates_and_one_trailing_newline():
    content = _read_text_exact(ARTIFACT)

    assert content.endswith("\n"), f"{ARTIFACT} must end with exactly one trailing newline"
    assert not content.endswith("\n\n"), f"{ARTIFACT} must not contain extra trailing blank lines"
    assert "\r" not in content, f"{ARTIFACT} must use Unix newlines only, not CRLF"

    lines = content.split("\n")
    assert lines[-1] == "", f"{ARTIFACT} must terminate with a newline"
    body_lines = lines[:-1]

    assert body_lines, f"{ARTIFACT} must not be empty"
    assert body_lines[0] == "# emulator firewall allowlist v1", (
        f"{ARTIFACT} has the wrong header. First line must be exactly "
        "'# emulator firewall allowlist v1'."
    )

    for line_number, line in enumerate(body_lines, start=1):
        assert line != "", f"{ARTIFACT} contains a blank line at line {line_number}"

    rule_lines = body_lines[1:]
    assert rule_lines, f"{ARTIFACT} must contain firewall rules after the header"

    for line_number, line in enumerate(rule_lines, start=2):
        assert RULE_RE.fullmatch(line), (
            f"{ARTIFACT} line {line_number} is not in the exact required format "
            f"'ALLOW tcp <host> <port> # <service>': {line!r}"
        )

    duplicates = sorted({line for line in rule_lines if rule_lines.count(line) > 1})
    assert not duplicates, (
        f"{ARTIFACT} contains duplicate firewall rule line(s): {duplicates}"
    )

def test_artifact_semantics_match_enabled_policy_entries_sorted_by_numeric_port():
    actual = _read_text_exact(ARTIFACT)
    expected_from_policy = _expected_artifact_from_policy()

    assert actual == expected_from_policy, (
        f"{ARTIFACT} does not match the rules implied by {POLICY}: only enabled "
        "entries must be emitted, disabled entries must be omitted, and enabled "
        "rules must be sorted by ascending numeric port.\n\n"
        f"Expected:\n{expected_from_policy}\nActual:\n{actual}"
    )

    assert "metrics-preview" not in actual, (
        f"{ARTIFACT} still contains disabled service metrics-preview"
    )
    assert "metrics-preview.mobile-ci.internal" not in actual, (
        f"{ARTIFACT} still contains disabled host metrics-preview.mobile-ci.internal"
    )

def test_artifact_matches_privileged_expected_final_contents_exactly():
    actual = _read_text_exact(ARTIFACT)
    assert actual == EXPECTED_ARTIFACT, (
        f"{ARTIFACT} does not have the exact expected final contents.\n\n"
        f"Expected:\n{EXPECTED_ARTIFACT}\nActual:\n{actual}"
    )

def test_verification_log_exists_and_matches_final_state_exactly():
    assert VERIFICATION_LOG.exists(), (
        f"Verification log was not created: {VERIFICATION_LOG}"
    )
    assert VERIFICATION_LOG.is_file(), (
        f"Verification log exists but is not a regular file: {VERIFICATION_LOG}"
    )

    actual = _read_text_exact(VERIFICATION_LOG)

    assert actual == EXPECTED_VERIFICATION_LOG, (
        f"{VERIFICATION_LOG} must contain exactly the five required yes/no "
        "verification lines, all marked yes only after the final artifact was "
        "actually checked.\n\n"
        f"Expected:\n{EXPECTED_VERIFICATION_LOG}\nActual:\n{actual}"
    )

def test_verification_log_yes_claims_are_consistent_with_artifact_final_state():
    artifact_content = _read_text_exact(ARTIFACT)
    log_content = _read_text_exact(VERIFICATION_LOG)

    assert artifact_content == EXPECTED_ARTIFACT, (
        "verification.log cannot validly claim artifact checks passed because "
        "the artifact content is not the privileged expected final artifact."
    )
    assert log_content == EXPECTED_VERIFICATION_LOG, (
        "verification.log does not exactly self-report completed command, "
        "artifact existence, valid format, valid semantics, and verified stop."
    )


You are helping the monitoring team finish a small distributed-system alert setup in a Linux container. The service is a three-node toy “orders” cluster, and its local diagnostic artifacts are already present under `/home/user/cluster_observability/`.

Please determine which single node should receive a new alert by inspecting the existing evidence in these files:

- `/home/user/cluster_observability/topology.txt`
- `/home/user/cluster_observability/node-a/health.txt`
- `/home/user/cluster_observability/node-b/health.txt`
- `/home/user/cluster_observability/node-c/health.txt`
- `/home/user/cluster_observability/node-a/metrics.prom`
- `/home/user/cluster_observability/node-b/metrics.prom`
- `/home/user/cluster_observability/node-c/metrics.prom`
- `/home/user/cluster_observability/recent-events.log`

The monitoring team only wants an alert when the evidence converges on the node that is causing replicated request instability, not merely a node that has one suspicious metric. Use the files to rule out plausible false leads before deciding.

Create exactly one new file:

`/home/user/cluster_observability/alert_decision.log`

The file must contain exactly 6 non-empty lines, in this exact format:

1. `CHECKPOINT topology=<short finding>`
2. `CHECKPOINT health=<short finding>`
3. `CHECKPOINT metrics=<short finding>`
4. `CHECKPOINT events=<short finding>`
5. `ALERT node=<node-name> reason=<short reason>`
6. `STOP verified=<yes-or-no>`

Formatting requirements for automated checking:

- `<node-name>` must be one of `node-a`, `node-b`, or `node-c`.
- The final `STOP` line must use `verified=yes` only if you have inspected enough evidence to justify the alert choice.
- Each `<short finding>` and `<short reason>` must be lowercase words joined by hyphens only, with no spaces. Examples of valid style are `leader-is-node-x`, `latency-normal`, or `events-match-node-y`.
- Do not include extra blank lines, timestamps, markdown, commentary, or additional files.
- The alert decision must identify the one node that is actually causing the cluster instability according to the combined topology, health, metrics, and recent event evidence.

After creating `/home/user/cluster_observability/alert_decision.log`, verify that the file exists and has the required six-line format, then stop.

schema_version = "1.1"

[task]
name = "endless-terminals/task_000000_934164e7"
description = "You are helping the monitoring team finish a small distributed-system alert setup in a Linux container. The service is a three-node toy \u201corders\u201d cluster, and its local diagnostic artifacts are already present under `/home/user/cluster_obser"
authors = [{ name = "Endless Terminals / Jarrod Barnes" }]
keywords = ["agentic-rl", "bounded_search_discipline", "endless-terminals", "terminal-bench-2", "wander_loop_without_convergence"]

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

[verifier]
timeout_sec = 300.0
user = "root"

[agent]
timeout_sec = 900.0
user = "user"

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

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

    apt-get update
    DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
        python3 \
        python3-pip \
        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/cluster_observability/node-a
    mkdir -p /home/user/cluster_observability/node-b
    mkdir -p /home/user/cluster_observability/node-c

    cat > /home/user/cluster_observability/topology.txt <<'EOF'
cluster: orders-prod-sim
replication_model: leader_follower
leader: node-b
followers: node-a,node-c
client_write_path: api-gateway -> leader -> followers
alert_policy: alert only on the node whose symptoms explain replicated write instability
EOF

    cat > /home/user/cluster_observability/node-a/health.txt <<'EOF'
node=node-a
role=follower
process=running
disk=ok
network=ok
last_restart_minutes_ago=1440
local_health=green
note=historical latency spike cleared before current incident window
EOF

    cat > /home/user/cluster_observability/node-b/health.txt <<'EOF'
node=node-b
role=leader
process=running
disk=ok
network=degraded
last_restart_minutes_ago=1440
local_health=yellow
note=leader accepts writes but follower replication acknowledgements are timing out
EOF

    cat > /home/user/cluster_observability/node-c/health.txt <<'EOF'
node=node-c
role=follower
process=running
disk=ok
network=ok
last_restart_minutes_ago=12
local_health=yellow
note=recent restart completed successfully and replica is caught up
EOF

    cat > /home/user/cluster_observability/node-a/metrics.prom <<'EOF'
# HELP orders_rpc_p95_ms RPC p95 latency in milliseconds
# TYPE orders_rpc_p95_ms gauge
orders_rpc_p95_ms{node="node-a"} 41
# HELP orders_replication_lag_seconds replica lag in seconds
# TYPE orders_replication_lag_seconds gauge
orders_replication_lag_seconds{node="node-a"} 0
# HELP orders_write_error_rate_percent write error rate percent
# TYPE orders_write_error_rate_percent gauge
orders_write_error_rate_percent{node="node-a"} 0.1
# HELP orders_network_retransmits_total network retransmits total
# TYPE orders_network_retransmits_total counter
orders_network_retransmits_total{node="node-a"} 12
EOF

    cat > /home/user/cluster_observability/node-b/metrics.prom <<'EOF'
# HELP orders_rpc_p95_ms RPC p95 latency in milliseconds
# TYPE orders_rpc_p95_ms gauge
orders_rpc_p95_ms{node="node-b"} 920
# HELP orders_replication_lag_seconds replica lag in seconds
# TYPE orders_replication_lag_seconds gauge
orders_replication_lag_seconds{node="node-b"} 0
# HELP orders_write_error_rate_percent write error rate percent
# TYPE orders_write_error_rate_percent gauge
orders_write_error_rate_percent{node="node-b"} 18.7
# HELP orders_network_retransmits_total network retransmits total
# TYPE orders_network_retransmits_total counter
orders_network_retransmits_total{node="node-b"} 8841
EOF

    cat > /home/user/cluster_observability/node-c/metrics.prom <<'EOF'
# HELP orders_rpc_p95_ms RPC p95 latency in milliseconds
# TYPE orders_rpc_p95_ms gauge
orders_rpc_p95_ms{node="node-c"} 58
# HELP orders_replication_lag_seconds replica lag in seconds
# TYPE orders_replication_lag_seconds gauge
orders_replication_lag_seconds{node="node-c"} 2
# HELP orders_write_error_rate_percent write error rate percent
# TYPE orders_write_error_rate_percent gauge
orders_write_error_rate_percent{node="node-c"} 0.3
# HELP orders_network_retransmits_total network retransmits total
# TYPE orders_network_retransmits_total counter
orders_network_retransmits_total{node="node-c"} 34
EOF

    cat > /home/user/cluster_observability/recent-events.log <<'EOF'
2026-05-29T09:14:01Z node-a info follower heartbeat ok
2026-05-29T09:14:03Z node-c warn restarted worker after maintenance window
2026-05-29T09:14:18Z node-b warn retransmit burst on leader replication socket
2026-05-29T09:14:21Z node-b error follower ack timeout while committing order batch
2026-05-29T09:14:24Z node-a info replica applied batch 88402
2026-05-29T09:14:26Z node-c info replica caught up after restart
2026-05-29T09:14:29Z node-b error client write failed after quorum timeout
2026-05-29T09:14:33Z node-b warn retransmit burst on leader replication socket
EOF

    rm -f /home/user/cluster_observability/alert_decision.log

    chown -R user:user /home/user/cluster_observability
    chmod 755 /home/user
    find /home/user/cluster_observability -type d -exec chmod 755 {} \;
    find /home/user/cluster_observability -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

BASE = Path("/home/user/cluster_observability")
OUTPUT_FILE = Path("/home/user/cluster_observability/alert_decision.log")

EXPECTED_SOURCE_FILES = {
    Path("/home/user/cluster_observability/topology.txt"): """cluster: orders-prod-sim
replication_model: leader_follower
leader: node-b
followers: node-a,node-c
client_write_path: api-gateway -> leader -> followers
alert_policy: alert only on the node whose symptoms explain replicated write instability
""",
    Path("/home/user/cluster_observability/node-a/health.txt"): """node=node-a
role=follower
process=running
disk=ok
network=ok
last_restart_minutes_ago=1440
local_health=green
note=historical latency spike cleared before current incident window
""",
    Path("/home/user/cluster_observability/node-b/health.txt"): """node=node-b
role=leader
process=running
disk=ok
network=degraded
last_restart_minutes_ago=1440
local_health=yellow
note=leader accepts writes but follower replication acknowledgements are timing out
""",
    Path("/home/user/cluster_observability/node-c/health.txt"): """node=node-c
role=follower
process=running
disk=ok
network=ok
last_restart_minutes_ago=12
local_health=yellow
note=recent restart completed successfully and replica is caught up
""",
    Path("/home/user/cluster_observability/node-a/metrics.prom"): """# HELP orders_rpc_p95_ms RPC p95 latency in milliseconds
# TYPE orders_rpc_p95_ms gauge
orders_rpc_p95_ms{node="node-a"} 41
# HELP orders_replication_lag_seconds replica lag in seconds
# TYPE orders_replication_lag_seconds gauge
orders_replication_lag_seconds{node="node-a"} 0
# HELP orders_write_error_rate_percent write error rate percent
# TYPE orders_write_error_rate_percent gauge
orders_write_error_rate_percent{node="node-a"} 0.1
# HELP orders_network_retransmits_total network retransmits total
# TYPE orders_network_retransmits_total counter
orders_network_retransmits_total{node="node-a"} 12
""",
    Path("/home/user/cluster_observability/node-b/metrics.prom"): """# HELP orders_rpc_p95_ms RPC p95 latency in milliseconds
# TYPE orders_rpc_p95_ms gauge
orders_rpc_p95_ms{node="node-b"} 920
# HELP orders_replication_lag_seconds replica lag in seconds
# TYPE orders_replication_lag_seconds gauge
orders_replication_lag_seconds{node="node-b"} 0
# HELP orders_write_error_rate_percent write error rate percent
# TYPE orders_write_error_rate_percent gauge
orders_write_error_rate_percent{node="node-b"} 18.7
# HELP orders_network_retransmits_total network retransmits total
# TYPE orders_network_retransmits_total counter
orders_network_retransmits_total{node="node-b"} 8841
""",
    Path("/home/user/cluster_observability/node-c/metrics.prom"): """# HELP orders_rpc_p95_ms RPC p95 latency in milliseconds
# TYPE orders_rpc_p95_ms gauge
orders_rpc_p95_ms{node="node-c"} 58
# HELP orders_replication_lag_seconds replica lag in seconds
# TYPE orders_replication_lag_seconds gauge
orders_replication_lag_seconds{node="node-c"} 2
# HELP orders_write_error_rate_percent write error rate percent
# TYPE orders_write_error_rate_percent gauge
orders_write_error_rate_percent{node="node-c"} 0.3
# HELP orders_network_retransmits_total network retransmits total
# TYPE orders_network_retransmits_total counter
orders_network_retransmits_total{node="node-c"} 34
""",
    Path("/home/user/cluster_observability/recent-events.log"): """2026-05-29T09:14:01Z node-a info follower heartbeat ok
2026-05-29T09:14:03Z node-c warn restarted worker after maintenance window
2026-05-29T09:14:18Z node-b warn retransmit burst on leader replication socket
2026-05-29T09:14:21Z node-b error follower ack timeout while committing order batch
2026-05-29T09:14:24Z node-a info replica applied batch 88402
2026-05-29T09:14:26Z node-c info replica caught up after restart
2026-05-29T09:14:29Z node-b error client write failed after quorum timeout
2026-05-29T09:14:33Z node-b warn retransmit burst on leader replication socket
""",
}

LOWERCASE_HYPHEN_VALUE = r"[a-z0-9]+(?:-[a-z0-9]+)*"

def _read_output_lines():
    assert OUTPUT_FILE.exists(), (
        f"Required final output file is missing: {OUTPUT_FILE}. "
        "Create exactly this file with the six required decision lines."
    )
    assert OUTPUT_FILE.is_file(), (
        f"Required final output path is not a regular file: {OUTPUT_FILE}"
    )

    content = OUTPUT_FILE.read_text(encoding="utf-8")
    assert content, f"{OUTPUT_FILE} is empty; it must contain exactly six non-empty lines."

    raw_lines = content.splitlines()
    assert content.endswith("\n"), (
        f"{OUTPUT_FILE} should end after line 6 with a newline, not with unterminated text."
    )
    assert len(raw_lines) == 6, (
        f"{OUTPUT_FILE} must contain exactly 6 lines; found {len(raw_lines)} lines: "
        f"{raw_lines!r}"
    )

    blank_line_numbers = [idx for idx, line in enumerate(raw_lines, start=1) if line == ""]
    assert not blank_line_numbers, (
        f"{OUTPUT_FILE} must contain no blank lines; blank line(s) found at: "
        f"{blank_line_numbers}"
    )

    whitespace_line_numbers = [
        idx for idx, line in enumerate(raw_lines, start=1)
        if line != line.strip()
    ]
    assert not whitespace_line_numbers, (
        f"{OUTPUT_FILE} lines must not have leading/trailing whitespace; "
        f"problem line(s): {whitespace_line_numbers}"
    )

    return raw_lines

def test_source_evidence_files_remain_unchanged():
    for file_path, expected_content in EXPECTED_SOURCE_FILES.items():
        assert file_path.exists(), f"Source evidence file was removed or is missing: {file_path}"
        assert file_path.is_file(), f"Source evidence path is no longer a file: {file_path}"
        actual_content = file_path.read_text(encoding="utf-8")
        assert actual_content == expected_content, (
            f"Source evidence file was modified but must remain unchanged: {file_path}"
        )

def test_alert_decision_log_has_exactly_six_non_empty_lines_with_no_extra_content():
    _read_output_lines()

def test_checkpoint_lines_are_in_required_order_and_format():
    lines = _read_output_lines()

    expected_prefixes = [
        "CHECKPOINT topology=",
        "CHECKPOINT health=",
        "CHECKPOINT metrics=",
        "CHECKPOINT events=",
    ]

    for line_number, (line, prefix) in enumerate(zip(lines[:4], expected_prefixes), start=1):
        assert line.startswith(prefix), (
            f"Line {line_number} must begin with exactly {prefix!r}; got {line!r}"
        )
        value = line[len(prefix):]
        assert re.fullmatch(LOWERCASE_HYPHEN_VALUE, value), (
            f"Line {line_number} finding must be lowercase words/numbers joined by hyphens "
            f"with no spaces; got {value!r}"
        )

def test_checkpoint_values_semantically_reflect_required_evidence_convergence():
    lines = _read_output_lines()

    topology_value = lines[0].split("=", 1)[1]
    assert "node-b" in topology_value, (
        "Line 1 topology checkpoint must account for topology by identifying node-b "
        f"as the leader / write path node; got {topology_value!r}"
    )
    assert any(token in topology_value for token in ("leader", "writes", "write", "through")), (
        "Line 1 topology checkpoint should mention node-b's leadership or write-path role; "
        f"got {topology_value!r}"
    )

    health_value = lines[1].split("=", 1)[1]
    assert (
        "node-b" in health_value
        or "node-c" in health_value
        or "yellow" in health_value
        or "network" in health_value
    ), (
        "Line 2 health checkpoint must show health evidence was considered, such as "
        "node-b network degradation or distinguishing node-c's non-causal restart; "
        f"got {health_value!r}"
    )
    assert any(
        token in health_value
        for token in ("network", "degraded", "restart", "noncausal", "caught", "yellow", "separated")
    ), (
        "Line 2 health checkpoint does not clearly reflect the relevant health finding "
        "or false-lead separation; got "
        f"{health_value!r}"
    )

    metrics_value = lines[2].split("=", 1)[1]
    assert "node-b" in metrics_value, (
        "Line 3 metrics checkpoint must identify node-b as the node with bad current "
        f"metrics; got {metrics_value!r}"
    )
    assert any(
        token in metrics_value
        for token in ("metrics", "bad", "retransmits", "errors", "latency", "high", "write")
    ), (
        "Line 3 metrics checkpoint should describe node-b's bad metrics "
        "(high latency/errors/retransmits); got "
        f"{metrics_value!r}"
    )

    events_value = lines[3].split("=", 1)[1]
    assert "node-b" in events_value, (
        "Line 4 events checkpoint must identify node-b as matching the current event "
        f"evidence; got {events_value!r}"
    )
    assert any(
        token in events_value
        for token in ("events", "match", "ack", "timeouts", "timeout", "write", "failures", "retransmit")
    ), (
        "Line 4 events checkpoint should describe node-b's retransmits, ack timeouts, "
        f"or write failures; got {events_value!r}"
    )

def test_alert_line_targets_node_b_with_valid_causal_reason():
    lines = _read_output_lines()
    alert_line = lines[4]

    match = re.fullmatch(rf"ALERT node=(node-[abc]) reason=({LOWERCASE_HYPHEN_VALUE})", alert_line)
    assert match, (
        "Line 5 must be exactly formatted as "
        "'ALERT node=<node-a|node-b|node-c> reason=<lowercase-hyphenated-reason>'; "
        f"got {alert_line!r}"
    )

    node_name, reason = match.groups()
    assert node_name == "node-b", (
        f"Line 5 alerts on {node_name}, but the combined topology, health, metrics, "
        "and events converge on node-b. Do not alert on node-a's historical note or "
        "node-c's harmless restart."
    )
    assert any(
        token in reason
        for token in (
            "leader",
            "replication",
            "replicated",
            "timeouts",
            "timeout",
            "network",
            "retransmits",
            "write",
            "writes",
            "failing",
            "failures",
            "instability",
        )
    ), (
        "Line 5 reason should describe the causal leader network/replication/write "
        f"instability; got reason={reason!r}"
    )

def test_stop_line_confirms_verification():
    lines = _read_output_lines()
    assert lines[5] == "STOP verified=yes", (
        "Line 6 must be exactly 'STOP verified=yes' after the file has been "
        f"format-verified; got {lines[5]!r}"
    )