ouroboros/tests/test_review_source_handles.py
Ouroboros c2e45111fb fix: restore portable release checks and symlink diagnostics
Preserve declared-entry hash failures and typed evidence omissions under Python 3.13. Keep the approved Windows artifact refusal explicit, isolate custody and nested pytest state, and synchronize the permission, lock, CSP, TLS and dispatcher fixtures without changing runtime policy.
2026-09-26 23:45:06 +03:00

349 lines
20 KiB
Python

"""Review/completion handles retain exact bytes through publication and child cleanup."""
import hashlib
import json
from pathlib import Path
import pytest
from starlette.applications import Starlette
from starlette.routing import Route
from starlette.testclient import TestClient
from ouroboros import artifacts, review_projection
from ouroboros.gateway import task_archive
from ouroboros.gateway.tasks import api_task_artifact
from ouroboros.headless import copy_child_task_result, prepare_task_drive, remove_subagent_task_drive
from ouroboros.task_results import write_task_result
from tests.test_acceptance_publication import _context, _run
def _field(ref, source):
if source == "review":
return {"review_projection": {"panels": [{"surface": "task_acceptance", "applied_source_ref": ref}]}}
return {"completion_observations": {"source_ref": ref, "source_status": "available"}}
@pytest.mark.parametrize("source", ["review", "completion"])
def test_child_source_closure_survives_real_cleanup(tmp_path, source):
parent = tmp_path / "canonical"
child = prepare_task_drive(parent, "source", "empty")
raw = b'{"full":"retained evidence"}'
ref = artifacts.store_actor_source_bytes(child, "source", category="context_checkpoints",
source_id=source, data=raw, extension="json")
write_task_result(child, "source", "completed", **_field(ref, source))
copied = copy_child_task_result(parent, {"id": "source", "drive_root": str(child)})
assert copied["child_ref_promotion"]["promoted_source_handle_count"] == 1
assert remove_subagent_task_drive(parent, "source", live=lambda _task: False) is True
assert not child.exists()
assert artifacts.read_actor_source_bytes(parent, "source", ref) == raw
assert artifacts.collect_task_artifact_records(parent, "source") == []
def test_failed_completion_promotion_retains_child_until_retry(tmp_path, monkeypatch):
parent = tmp_path / "canonical"
child = prepare_task_drive(parent, "source", "empty")
raw = b'{"full":"survives failed copy"}'
ref = artifacts.store_actor_source_bytes(child, "source", category="context_checkpoints",
source_id="completion", data=raw, extension="json")
write_task_result(child, "source", "completed", **_field(ref, "completion"))
with monkeypatch.context() as patch:
patch.setattr(artifacts, "store_actor_source_bytes", lambda *_a, **_k: (_ for _ in ()).throw(OSError("copy failed")))
copied = copy_child_task_result(parent, {"id": "source", "drive_root": str(child)})
assert copied["child_ref_promotion"]["status"] == "incomplete"
assert remove_subagent_task_drive(parent, "source", live=lambda _task: False) is False
assert child.exists()
copied = copy_child_task_result(parent, {"id": "source", "drive_root": str(child)})
assert copied["child_ref_promotion"]["status"] == "complete"
assert remove_subagent_task_drive(parent, "source", live=lambda _task: False) is True
assert artifacts.read_actor_source_bytes(parent, "source", ref) == raw
def test_unchanged_review_source_is_write_once(tmp_path, monkeypatch):
ctx = _context(tmp_path)
trace = {"review_runs": [_run()]}
review_projection.publish_acceptance_checkpoint(ctx, trace)
ref = trace["review_runs"][0]["applied_source_ref"]
path = artifacts.task_artifact_dir_path(tmp_path, "applied") / ref["path"]
stamp = path.stat().st_mtime_ns
monkeypatch.setattr(artifacts, "write_bytes_atomic", lambda *_a, **_k: pytest.fail("same source rewritten"))
review_projection.publish_acceptance_checkpoint(ctx, trace)
assert trace["review_runs"][0]["applied_source_ref"] == ref
assert path.stat().st_mtime_ns == stamp
assert not (path.parents[2] / artifacts._ARTIFACT_MANIFEST).exists()
@pytest.mark.serial
def test_source_download_is_bound_and_distinct_from_same_named_user_file(tmp_path):
ctx = _context(tmp_path)
trace = {"review_runs": [_run()]}
review_projection.publish_acceptance_checkpoint(ctx, trace)
ref = trace["review_runs"][0]["applied_source_ref"]
name = Path(ref["path"]).name
artifacts.store_task_artifact_bytes(tmp_path, "applied", name, b"user result", kind="user_file")
app = Starlette(routes=[Route("/api/tasks/{task_id}/artifacts/{name}", api_task_artifact)])
app.state.drive_root = tmp_path
with TestClient(app) as client:
url = f"/api/tasks/applied/artifacts/{name}"
artifact = client.get(url)
if task_archive.CONFINED:
assert artifact.status_code == 200 and artifact.content == b"user result"
else:
assert artifact.status_code == 503
assert artifact.json()["reason_code"] == "artifact_unavailable"
source = client.get(url, params={"source": ref["path"]})
assert source.status_code == 200
assert hashlib.sha256(source.content).hexdigest() == ref["sha256"]
assert len(json.loads(source.content)["actors"][0]["parsed"]["findings"]) == 80
assert client.get(url, params={"source": "source_handles/context_checkpoints/not-published.json"}).status_code == 404
(artifacts.task_artifact_dir_path(tmp_path, "applied") / ref["path"]).write_bytes(b"corrupt")
assert client.get(url, params={"source": ref["path"]}).status_code == 404
@pytest.mark.parametrize("panels", [True, 7, {"legacy": "unknown"}])
def test_unavailable_review_projection_does_not_hide_valid_completion_source(tmp_path, panels):
raw = b'{"delivery_results": []}'
ref = artifacts.store_actor_source_bytes(tmp_path, "source", category="context_checkpoints",
source_id="completion", data=raw, extension="json")
result = {"task_id": "source", "review_projection": {"panels": panels},
"completion_observations": {"source_ref": ref}}
assert artifacts.read_task_result_source_bytes(tmp_path, result, Path(ref["path"]).name, ref["path"]) == raw
def _nested_acceptance_sources(child):
result = artifacts.store_actor_source_bytes(
child, "source", category="tool_results", source_id="command-output",
data=b"complete output beyond the preview", extension="txt",
)
trajectory = artifacts.persist_tool_trajectory_source(child, "source", [{
"tool": "run_command", "result": "preview", "result_partial": True,
"result_source_ref": result,
}])
raw = json.dumps({"authority": "host_root", "request": {
"surface": "task_acceptance", "evidence": {"tool_trajectory_source_ref": trajectory},
}}).encode()
checkpoint = artifacts.store_actor_source_bytes(
child, "source", category="context_checkpoints", source_id="acceptance",
data=raw, extension="json",
)
write_task_result(child, "source", "completed", **_field(checkpoint, "review"))
return checkpoint, trajectory, result
@pytest.mark.parametrize("outer_already_copied", [False, True])
def test_nested_acceptance_sources_survive_copy_back_and_cleanup(tmp_path, outer_already_copied):
parent = tmp_path / "canonical"
child = prepare_task_drive(parent, "source", "empty")
refs = _nested_acceptance_sources(child)
before = [artifacts.read_actor_source_bytes(child, "source", ref) for ref in refs]
if outer_already_copied:
artifacts.store_actor_source_bytes(parent, "source", category="context_checkpoints",
source_id="acceptance", data=before[0], extension="json")
for _ in range(2):
copied = copy_child_task_result(parent, {"id": "source", "drive_root": str(child)})
assert copied["child_ref_promotion"]["status"] == "complete"
assert copied["child_ref_promotion"]["promoted_source_handle_count"] == 3
assert copied["review_projection"]["panels"][0]["applied_source_ref"] == refs[0]
assert remove_subagent_task_drive(parent, "source", live=lambda _task: False) is True
assert not child.exists()
assert [artifacts.read_actor_source_bytes(parent, "source", ref) for ref in refs] == before
assert artifacts.collect_task_artifact_records(parent, "source") == []
# The trajectory producer preserves the complete original handle contract.
assert refs[1]["size"] == len(before[1])
assert refs[1]["sha256"] == hashlib.sha256(before[1]).hexdigest()
assert refs[1]["read"]["arguments"]["path"] == refs[1]["path"]
def test_nested_copy_failure_holds_child_and_rechecks_existing_checkpoint(tmp_path, monkeypatch):
parent = tmp_path / "canonical"
child = prepare_task_drive(parent, "source", "empty")
checkpoint, trajectory, result = _nested_acceptance_sources(child)
store = artifacts.store_actor_source_bytes
def fail_output(*args, **kwargs):
if kwargs.get("source_id") == "command-output":
raise OSError("output copy failed")
return store(*args, **kwargs)
with monkeypatch.context() as patch:
patch.setattr(artifacts, "store_actor_source_bytes", fail_output)
copied = copy_child_task_result(parent, {"id": "source", "drive_root": str(child)})
promotion = copied["child_ref_promotion"]
assert promotion["status"] == "incomplete"
assert promotion["pending_refs"][0]["path"] == str(
artifacts.task_artifact_dir_path(child, "source") / result["path"])
assert artifacts.read_actor_source_bytes(parent, "source", checkpoint)
assert artifacts.read_actor_source_bytes(parent, "source", trajectory)
assert remove_subagent_task_drive(parent, "source", live=lambda _task: False) is False
copied = copy_child_task_result(parent, {"id": "source", "drive_root": str(child)})
assert copied["child_ref_promotion"]["status"] == "complete"
assert copied["child_ref_promotion"]["pending_refs"] == []
assert remove_subagent_task_drive(parent, "source", live=lambda _task: False) is True
assert artifacts.read_actor_source_bytes(parent, "source", result) == b"complete output beyond the preview"
@pytest.mark.parametrize("selected", [False, True])
@pytest.mark.parametrize("copy_failure", [False, True])
@pytest.mark.parametrize("canonical_checkpoint", [False, True], ids=["child_checkpoint", "canonical_checkpoint"])
def test_nested_trajectory_promotes_existing_call_blobs_without_crawling_prose(tmp_path, monkeypatch, selected, copy_failure, canonical_checkpoint):
from ouroboros.observability import persist_call, promote_child_task_refs, retry_pending_child_ref_promotions
from ouroboros.review_evidence import build_task_acceptance_evidence
from ouroboros.review_evidence_refs import acceptance_evidence_ref_vocabulary, resolve_criteria_evidence_refs
from ouroboros.task_results import load_task_result
from ouroboros.utils import sanitize_tool_args_for_log
parent = tmp_path / "canonical"
child = prepare_task_drive(parent, "source", "empty")
args = {"cmd": "x" * (4000 if selected else 100), "literal": str(child / "not-a-dependency.json")}
call = {"tool": "run_command", "tool_call_id": "call", "args": args, "result": "ok"}
trace = persist_call(child, task_id="source", call_id="call", call_type="tool", payload=call)
ctx = _context(child)
ctx.task_id = "source"
checkpoint_root = parent if canonical_checkpoint else child
ctx.task_metadata = {"budget_drive_root": str(checkpoint_root)}
evidence = build_task_acceptance_evidence(
ctx, drive_root=child, task_id="source",
llm_trace={"tool_calls": [{**call, "args": sanitize_tool_args_for_log("run_command", args), "trace_ref": trace}]},
agent_evidence={"tool_trajectory_indices": [0], "corpus_sha256": "f" * 64} if selected else None,
)
trajectory = evidence["tool_trajectory_source_ref"]
assert "corpus_sha256" not in trajectory # The model cannot author the host handle.
section = "tool_trajectory_selected" if selected else "tool_trajectory"
citation = evidence[section][0]["ref"]
assert acceptance_evidence_ref_vocabulary(evidence)[citation] == "tool_record"
criteria = [{"criterion": "command", "status": "supported", "evidence_refs": [citation]}]
run = _run()
run["request"].update(task_id="source", evidence=evidence)
run["actors"][0]["parsed"]["criteria_used"] = criteria
review_trace = {"review_runs": [run]}
review_projection.publish_acceptance_checkpoint(ctx, review_trace)
checkpoint = review_trace["review_runs"][0]["applied_source_ref"]
original_checkpoint = artifacts.read_actor_source_bytes(checkpoint_root, "source", checkpoint)
write_task_result(child, "source", "completed",
review_projection=load_task_result(checkpoint_root, "source")["review_projection"])
task = {"id": "source", "drive_root": str(child)}
if copy_failure:
store = artifacts.store_actor_source_bytes
def fail_corpus(*args, **kwargs):
if kwargs.get("source_id") == "acceptance_tool_trajectory":
raise OSError("corpus copy failed")
return store(*args, **kwargs)
with monkeypatch.context() as patch:
patch.setattr(artifacts, "store_actor_source_bytes", fail_corpus)
copied = copy_child_task_result(parent, task)
assert copied["child_ref_promotion"]["status"] == "incomplete"
assert copied["child_ref_promotion"]["pending_refs"]
assert remove_subagent_task_drive(parent, "source", live=lambda _task: False) is False
assert retry_pending_child_ref_promotions(parent)["completed"] == ["source"]
first_ref = None
for _ in range(2):
copied = copy_child_task_result(parent, task)
assert copied["child_ref_promotion"]["status"] == "complete"
ref = copied["review_projection"]["panels"][0]["applied_source_ref"]
first_ref = first_ref or ref
assert ref == first_ref
assert "corpus_sha256" not in ref # Checkpoints keep their own byte identity.
assert artifacts.read_actor_source_bytes(checkpoint_root, "source", checkpoint) == original_checkpoint
assert remove_subagent_task_drive(parent, "source", live=lambda _task: False) is True
assert not child.exists()
# Rebase the already promoted source again, then repeat after the child is
# gone. Neither a second physical digest nor idempotent copying renames rows.
other = tmp_path / "another-canonical"
for destination, source_root in ((parent, child), (other, parent), (other, parent)):
copied, state = promote_child_task_refs(destination, source_root, "source", copied)
assert state["status"] == "complete" and not state["pending_refs"]
ref = copied["review_projection"]["panels"][0]["applied_source_ref"]
saved = json.loads(artifacts.read_actor_source_bytes(destination, "source", ref))
evidence = saved["request"]["evidence"]
promoted = evidence["tool_trajectory_source_ref"]
assert promoted["corpus_sha256"] == trajectory["sha256"]
assert promoted["sha256"] != promoted["corpus_sha256"]
assert promoted["artifact_ref"].startswith(f"artifact_store:{promoted['path']}#chars=")
raw = artifacts.read_actor_source_bytes(destination, "source", promoted)
assert hashlib.sha256(raw).hexdigest() == promoted["sha256"]
with pytest.raises(ValueError, match="sha256 verification"):
artifacts.read_actor_source_bytes(destination, "source", {**promoted, "sha256": trajectory["sha256"]})
assert saved["actors"][0]["parsed"]["criteria_used"] == criteria
assert evidence[section][0]["ref"] == citation
vocabulary = acceptance_evidence_ref_vocabulary(evidence)
assert vocabulary[citation] == "tool_record"
assert resolve_criteria_evidence_refs(criteria, vocabulary) == []
recovered, complete, issue = artifacts.materialize_tool_args_source(destination, json.loads(raw)[0])
assert complete and not issue and recovered == args
assert artifacts.collect_task_artifact_records(destination, "source") == []
@pytest.mark.parametrize("outer_already_copied", [False, True])
@pytest.mark.parametrize("loss", ["missing", "corrupt", "legacy_ref"])
def test_nested_unavailable_source_is_disclosed_without_reconstructing_preview(tmp_path, loss, outer_already_copied):
parent = tmp_path / "canonical"
child = prepare_task_drive(parent, "source", "empty")
checkpoint, trajectory, result = _nested_acceptance_sources(child)
source_path = artifacts.task_artifact_dir_path(child, "source") / result["path"]
if loss == "missing":
source_path.unlink()
elif loss == "corrupt":
source_path.write_bytes(b"corrupt")
else:
# The historical producer dropped these fields; the filename is not a
# substitute for the missing producer-issued verification contract.
legacy = {k: v for k, v in trajectory.items() if k not in {"read", "size", "sha256"}}
raw = json.dumps({"request": {"surface": "task_acceptance", "evidence": {
"tool_trajectory_source_ref": legacy}}}).encode()
checkpoint = artifacts.store_actor_source_bytes(
child, "source", category="context_checkpoints", source_id="acceptance",
data=raw, extension="json")
write_task_result(child, "source", "completed", **_field(checkpoint, "review"))
if outer_already_copied:
artifacts.store_actor_source_bytes(
parent, "source", category="context_checkpoints", source_id="acceptance",
data=artifacts.read_actor_source_bytes(child, "source", checkpoint), extension="json")
# Same host publication on both roots must still publish its physical
# missing-source disclosure after the normal merge selects canonical.
projection = {"panels": [{"surface": "task_acceptance", "panel_id": "p",
"publication_revision": 1, "applied_source_ref": checkpoint}]}
write_task_result(parent, "source", "running", review_projection=projection)
write_task_result(child, "source", "completed", review_projection=projection)
copied = copy_child_task_result(parent, {"id": "source", "drive_root": str(child)})
assert copied["child_ref_promotion"]["unavailable_refs"]
promoted = copied["review_projection"]["panels"][0]["applied_source_ref"]
assert promoted != checkpoint
evidence = json.loads(artifacts.read_actor_source_bytes(parent, "source", promoted))["request"]["evidence"]
dependency = evidence["tool_trajectory_source_ref"]
if loss != "legacy_ref":
dependency = json.loads(artifacts.read_actor_source_bytes(parent, "source", dependency))[0]["result_source_ref"]
assert dependency["availability"] == "unavailable"
assert dependency["reason"] == {"missing": "source_missing", "corrupt": "digest_mismatch", "legacy_ref": "invalid_ref"}[loss]
assert not (artifacts.task_artifact_dir_path(parent, "source") / result["path"]).exists()
def test_copyback_prepares_bulk_artifacts_and_selected_review_refs_outside_lock(tmp_path, monkeypatch):
from ouroboros import headless, observability
parent = tmp_path / "canonical"
child = prepare_task_drive(parent, "source", "empty")
_nested_acceptance_sources(child)
artifacts.store_task_artifact_bytes(child, "source", "report.txt", b"actual deliverable")
write_task_result(child, "source", "completed", artifacts=artifacts.collect_task_artifact_records(child, "source"))
lock = parent / "task_results" / "source.json.lock"
bulk_copy = headless._copy_child_artifacts_to_parent
promote = observability._promote_task_source_ref
observed = []
def copy_bulk(*args, **kwargs):
assert not lock.exists(), "bulk artifact copying entered the result lock"
observed.append("bulk")
return bulk_copy(*args, **kwargs)
def promote_review(*args, **kwargs):
assert not lock.exists(), "CURRENT review reference I/O entered the result lock"
observed.append("review")
return promote(*args, **kwargs)
monkeypatch.setattr(headless, "_copy_child_artifacts_to_parent", copy_bulk)
monkeypatch.setattr(observability, "_promote_task_source_ref", promote_review)
copied = copy_child_task_result(parent, {"id": "source", "drive_root": str(child)})
assert copied["child_ref_promotion"]["status"] == "complete"
assert observed[0] == "bulk" and "review" in observed
assert remove_subagent_task_drive(parent, "source", live=lambda _task: False) is True
assert (artifacts.task_artifact_dir_path(parent, "source") / "report.txt").read_bytes() == b"actual deliverable"