Support immutable local SWE image IDs

This commit is contained in:
pj committed 2026-09-15 23:24:09 +05:30
1 parent 69c5793562
commit 1428c2b08e
9 files changed
+129 -43

No files matched your search

+12 -8
View File
@@ -13,6 +13,10 @@ from messageboardbench.board import MESSAGEBOARD_V2_INTERFACE_VERSION, initializ
from messageboardbench.feedback import initialize_feedback
IMAGE_ID = "sha256:" + "a" * 64
REPO_DIGEST = "repo@sha256:" + "d" * 64
def records(count=349):
return {f"owner__repo-{index:03d}": {"instance_id": f"owner__repo-{index:03d}",
"value": index}
@@ -119,11 +123,11 @@ def test_compose_has_no_mount_and_network_none():
def test_write_compose_uses_validated_digest_override(tmp_path, monkeypatch):
monkeypatch.setattr(module, "swebench_spec", lambda record: ("repo:latest", [], "pytest"))
path = module.write_compose(
{"instance_id": "task"}, tmp_path, image_override="repo@sha256:validated"
{"instance_id": "task"}, tmp_path, image_override=REPO_DIGEST
)
assert "repo@sha256:validated" in path.read_text()
assert REPO_DIGEST in path.read_text()
assert "repo:latest" not in path.read_text()
with pytest.raises(ValueError, match="repository digest"):
with pytest.raises(ValueError, match="immutable image reference"):
module.write_compose({"instance_id": "other"}, tmp_path, image_override="repo:latest")
@@ -134,10 +138,10 @@ def test_sample_binds_fresh_grader_to_validated_digest(tmp_path):
"instance_id": "task", "problem_statement": "fix it", "test_patch": "patch"
}
sample = module.sample_from_record(
value, compose, grader_image="repo@sha256:validated"
value, compose, grader_image=IMAGE_ID
)
assert sample.metadata["messageboardbench_grader_image"] == "repo@sha256:validated"
with pytest.raises(ValueError, match="repository digest"):
assert sample.metadata["messageboardbench_grader_image"] == IMAGE_ID
with pytest.raises(ValueError, match="immutable image reference"):
module.sample_from_record(value, compose, grader_image="repo:latest")
@@ -237,7 +241,7 @@ def test_paid_scorer_restores_tests_and_uses_fresh_digest_grader(
state = SimpleNamespace(
metadata={
"_messageboardbench_evaluator_commit": "a" * 40,
"messageboardbench_grader_image": "repo@sha256:validated",
"messageboardbench_grader_image": IMAGE_ID,
"test_patch": "--- a/tests/test_x.py\n+++ b/tests/test_x.py\n",
"base_commit": "b" * 40,
"FAIL_TO_PASS": ["target"], "PASS_TO_PASS": [],
@@ -252,7 +256,7 @@ def test_paid_scorer_restores_tests_and_uses_fresh_digest_grader(
score = asyncio.run(invocation)
assert score.value == 1.0
assert captured["model_patch"] == "model patch"
assert captured["image"] == "repo@sha256:validated"
assert captured["image"] == IMAGE_ID
assert captured["memory"] == "9g" and captured["timeout_seconds"] == 77
assert score.metadata["test_modified_ever"] is True
assert score.metadata["grader_container_fresh"] is True
+29 -3
View File
@@ -21,6 +21,10 @@ from scripts.validate_swe_population_prerequisites import (
)
IMAGE_ID = "sha256:" + "a" * 64
REPO_DIGEST = "repo@sha256:" + "d" * 64
def write(path, value):
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(value if isinstance(value, str) else json.dumps(value))
@@ -52,7 +56,7 @@ def fixture(tmp_path):
eval_hash = write(tmp_path / "evidence" / eval_name, eval_text)
cells.append({"split": split, "mode": mode, "resolved": expected[split, mode],
"image": "repo:tag", "test_command": ["pytest"],
"image_id": "sha256:image", "repo_digests": ["repo@sha256:digest"],
"image_id": IMAGE_ID, "repo_digests": [REPO_DIGEST],
"grader_container_fresh": True,
"eval_script_sha256": eval_hash, "eval_script_file": eval_name,
"model_patch_sha256": (
@@ -69,8 +73,8 @@ def fixture(tmp_path):
"grader_isolation": "fresh-container-per-scoring-attempt",
"grading_lifecycle": prerequisites_module.GRADING_LIFECYCLE,
"image": "repo:tag",
"remote_image": {"id": "sha256:image",
"repo_digests": ["repo@sha256:digest"]},
"remote_image": {"id": IMAGE_ID, "repo_digests": [REPO_DIGEST],
"immutable_ref": REPO_DIGEST},
"test_command": ["pytest"],
"base_commit": "base", "repo": "org/repo", "version": "1",
"original_test_patch_sha256": hashlib.sha256(b"original").hexdigest(),
@@ -116,6 +120,28 @@ def test_environment_index_is_required_and_plan_bound(tmp_path):
validate_environment_index(plan, tmp_path)
def test_environment_index_accepts_content_addressed_local_image_without_repo_digest(
tmp_path,
):
plan, manifest_path, record = fixture(tmp_path)
manifest = json.loads(manifest_path.read_text())
manifest["remote_image"] = {
"id": IMAGE_ID, "repo_digests": [], "immutable_ref": IMAGE_ID,
}
for row in manifest["results"]:
row["repo_digests"] = []
manifest_hash = write(manifest_path, manifest)
index_path = tmp_path / "index.json"
index = json.loads(index_path.read_text())
index["manifests"]["task"]["sha256"] = manifest_hash
write(index_path, index)
evidence = validate_environment_index_for_records(plan, tmp_path, {"task": record})
selected = evidence["validated_instances"][0]
assert selected["validated_image_ref"] == IMAGE_ID
assert selected["validated_repo_digest"] is None
def test_unresolved_cell_requires_an_actual_failed_target(tmp_path):
plan, manifest_path, record = fixture(tmp_path)
manifest = json.loads(manifest_path.read_text())
+24 -6
View File
@@ -10,6 +10,10 @@ import pytest
from messageboardbench import swe_validation as module
IMAGE_ID = "sha256:" + "a" * 64
REPO_DIGEST = "repo@sha256:" + "d" * 64
def record(**changes):
value = {
"instance_id": "owner__repo-1",
@@ -34,8 +38,8 @@ def result(split: str, mode: str, *, resolved: bool, exit_code: int):
output_file=f"{split}-{mode}.txt",
output_sha256="0" * 64,
image="swebench/sweb.eval.x86_64.example:latest",
image_id="sha256:abc",
repo_digests=["swebench/example@sha256:def"],
image_id=IMAGE_ID,
repo_digests=[REPO_DIGEST],
test_command=["pytest", "tests/test_x.py"],
target_statuses={"tests/test_x.py::test_bug": "PASSED" if resolved else "FAILED"},
resolved=resolved,
@@ -115,18 +119,32 @@ def test_matrix_rejects_image_identity_drift():
def test_image_identity_requires_digest_and_amd64():
def run(command, **kwargs):
payload = {
"Id": "sha256:abc",
"RepoDigests": ["repo@sha256:def"],
"Id": IMAGE_ID,
"RepoDigests": [REPO_DIGEST],
"Os": "linux",
"Architecture": "amd64",
}
return subprocess.CompletedProcess(command, 0, __import__("json").dumps(payload), "")
assert module.image_identity("repo:tag", {"DOCKER_HOST": module.REMOTE_DOCKER_HOST}, run) == (
"sha256:abc", ["repo@sha256:def"]
IMAGE_ID, [REPO_DIGEST]
)
def test_image_identity_accepts_local_content_address_without_repo_digest():
def run(command, **kwargs):
payload = {
"Id": IMAGE_ID, "RepoDigests": [], "Os": "linux", "Architecture": "amd64",
}
return subprocess.CompletedProcess(command, 0, __import__("json").dumps(payload), "")
identity = module.image_identity(
"local:tag", {"DOCKER_HOST": module.REMOTE_DOCKER_HOST}, run
)
assert identity == (IMAGE_ID, [])
assert module.immutable_image_reference(*identity) == IMAGE_ID
def test_semantic_audit_is_bound_to_pair_hashes():
expected = {
"dataset": module.DATASET,
@@ -198,7 +216,7 @@ def test_fresh_grader_runs_exact_testspec_script_with_install_and_network_none(m
return subprocess.CompletedProcess(command, 0, stdout, "")
evaluated, output, statuses, script_hash, preserved_script = module.run_fresh_grader(
record(), model_patch="diff --git a/x b/x\n", image="repo@sha256:digest",
record(), model_patch="diff --git a/x b/x\n", image=REPO_DIGEST,
environ={"DOCKER_HOST": module.REMOTE_DOCKER_HOST}, run=run,
)
assert evaluated.returncode == 0
@@ -103,6 +103,7 @@ def test_environment_validation_uses_preserved_snapshot(tmp_path, monkeypatch):
"manifest_sha256": digest(archived_manifest),
"validated_image": "image",
"validated_image_id": "image-id",
"validated_image_ref": "repo-digest",
"validated_repo_digest": "repo-digest",
}],
}
@@ -110,7 +111,8 @@ def test_environment_validation_uses_preserved_snapshot(tmp_path, monkeypatch):
from messageboardbench import swe_prerequisites
monkeypatch.setattr(swe_prerequisites, "validate_task_manifest", lambda *args, **kwargs: {
"image": "image",
"remote_image": {"id": "image-id", "repo_digests": ["repo-digest"]},
"remote_image": {"id": "image-id", "repo_digests": ["repo-digest"],
"immutable_ref": "repo-digest"},
})
assert matches(manifest, frozen, tmp_path / "run")