Files
odysseus/tests/test_audit_c5_benchmark_evidence.py
T

3021 lines
142 KiB
Python

"""Deterministic tests for audit_c5_benchmark_evidence.py.
All tests use temporary synthetic fixtures - no network, no runtime, no model.
Tests are self-contained and safe to run repeatedly without changing source data.
GFM integration checks are separate from the dependency-free unit suite:
python -m venv /tmp/c5-gfm
/tmp/c5-gfm/bin/pip install cmarkgfm==2025.10.22
/tmp/c5-gfm/bin/python tests/test_audit_c5_benchmark_evidence.py --gfm
The explicit --gfm command fails if cmarkgfm is unavailable; it never skips.
"""
from __future__ import annotations
import hashlib
import json
import os
import sys
import tempfile
import unittest
from pathlib import Path
# Ensure project root is on path for import without conftest.
_ROOT = Path(__file__).resolve().parents[1]
if str(_ROOT) not in sys.path:
sys.path.insert(0, str(_ROOT))
import scripts.audit_c5_benchmark_evidence as auditor
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
def _sha256(data: bytes) -> str:
return hashlib.sha256(data).hexdigest()
def _write(path: Path, content: bytes) -> str:
"""Write bytes to path and return its sha256."""
path.parent.mkdir(parents=True, exist_ok=True)
path.write_bytes(content)
return _sha256(content)
def _manifest(artifacts: list, campaign_id: str = "TEST-CAMPAIGN-01", expected_sets: dict | None = None) -> dict:
d = {
"schema_version": 1,
"campaign_id": campaign_id,
"description": "Synthetic test manifest",
"artifacts": artifacts,
}
if expected_sets:
d["expected_sets"] = expected_sets
return d
def _run_audit(
tmp: Path,
manifest_dict: dict,
deterministic: bool = False,
trusted_sources: list[str] | None = None,
trusted_expected_sets: dict | None = None,
) -> dict:
"""Write manifest to tmp, run audit, return parsed result."""
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(manifest_dict))
return auditor.audit(
str(mpath),
str(tmp),
deterministic=deterministic,
trusted_sources=trusted_sources,
trusted_expected_sets=trusted_expected_sets,
)
# ---------------------------------------------------------------------------
# Baseline Integrity and Safety Tests
# ---------------------------------------------------------------------------
class TestValidMatchingHash(unittest.TestCase):
"""VERIFIED: artifact present, observed hash matches expected hash."""
def test_verified_when_observed_matches_expected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
content = b"hello world"
h = _write(tmp / "file.txt", content)
result = _run_audit(tmp, _manifest([{
"path": "file.txt",
"type": "result_record",
"expected_sha256": h,
}]))
art = result["artifacts"][0]
self.assertEqual(art["status"], "VERIFIED")
self.assertTrue(art["present"])
self.assertEqual(art["observed_sha256"], h)
self.assertEqual(art["expected_sha256"], h)
self.assertTrue(art["hash_match"])
self.assertEqual(result["totals"]["VERIFIED"], 1)
class TestMismatchedHash(unittest.TestCase):
"""MISMATCH: artifact present, but observed hash differs from expected."""
def test_mismatch_when_hash_differs(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
content = b"actual content"
_write(tmp / "data.json", content)
wrong_hash = _sha256(b"different content")
result = _run_audit(tmp, _manifest([{
"path": "data.json",
"type": "campaign_manifest",
"expected_sha256": wrong_hash,
}]))
art = result["artifacts"][0]
self.assertEqual(art["status"], "MISMATCH")
self.assertTrue(art["present"])
self.assertNotEqual(art["observed_sha256"], art["expected_sha256"])
self.assertFalse(art["hash_match"])
self.assertEqual(result["totals"]["MISMATCH"], 1)
class TestMissingArtifact(unittest.TestCase):
"""MISSING: expected artifact is absent from the filesystem."""
def test_missing_when_file_absent(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
result = _run_audit(tmp, _manifest([{
"path": "nonexistent/file.json",
"type": "trajectory",
"expected_sha256": "a" * 64,
}]))
art = result["artifacts"][0]
self.assertEqual(art["status"], "MISSING")
self.assertFalse(art["present"])
self.assertIsNone(art["observed_sha256"])
self.assertIsNone(art["size_bytes"])
self.assertEqual(result["totals"]["MISSING"], 1)
class TestObservedOnlyNoExpectedHash(unittest.TestCase):
"""OBSERVED_ONLY: artifact exists but manifest has no expected hash."""
def test_observed_only_when_no_expected_hash(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
_write(tmp / "report.md", b"# Report\n")
result = _run_audit(tmp, _manifest([{
"path": "report.md",
"type": "result_record",
}]))
art = result["artifacts"][0]
self.assertEqual(art["status"], "OBSERVED_ONLY")
self.assertTrue(art["present"])
self.assertIsNotNone(art["observed_sha256"])
self.assertIsNone(art["expected_sha256"])
self.assertFalse(art["hash_match"])
self.assertEqual(result["totals"]["OBSERVED_ONLY"], 1)
def test_observed_only_when_expected_hash_is_null(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
_write(tmp / "report.md", b"# Report\n")
result = _run_audit(tmp, _manifest([{
"path": "report.md",
"type": "result_record",
"expected_sha256": None,
}]))
art = result["artifacts"][0]
self.assertEqual(art["status"], "OBSERVED_ONLY")
class TestInvalidManifest(unittest.TestCase):
"""INVALID: manifest fails validation."""
def test_invalid_missing_schema_version(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps({"campaign_id": "X", "artifacts": []}))
result = auditor.audit(str(mpath), str(tmp))
self.assertFalse(result["manifest_valid"])
self.assertGreater(len(result["errors"]), 0)
def test_invalid_wrong_schema_version(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
result = _run_audit(tmp, {"schema_version": 99, "campaign_id": "X", "artifacts": []})
self.assertFalse(result["manifest_valid"])
def test_invalid_artifacts_not_a_list(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
result = _run_audit(tmp, {"schema_version": 1, "campaign_id": "X", "artifacts": "oops"})
self.assertFalse(result["manifest_valid"])
def test_invalid_malformed_json(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text("{not valid json}")
result = auditor.audit(str(mpath), str(tmp))
self.assertFalse(result["manifest_valid"])
self.assertGreater(len(result["errors"]), 0)
def test_invalid_missing_manifest_file(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "does_not_exist.json"
result = auditor.audit(str(mpath), str(tmp))
self.assertFalse(result["manifest_valid"])
self.assertGreater(len(result["errors"]), 0)
class TestPathTraversal(unittest.TestCase):
"""INVALID: path traversal attempts must be rejected."""
def test_reject_dotdot_path(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
result = _run_audit(tmp, _manifest([{
"path": "../escape.txt",
"type": "result_record",
}]))
art = result["artifacts"][0]
self.assertEqual(art["status"], "INVALID")
def test_reject_absolute_path(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
result = _run_audit(tmp, _manifest([{
"path": "/etc/passwd",
"type": "result_record",
}]))
art = result["artifacts"][0]
self.assertEqual(art["status"], "INVALID")
def test_reject_nested_dotdot(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
result = _run_audit(tmp, _manifest([{
"path": "subdir/../../etc/passwd",
"type": "result_record",
}]))
art = result["artifacts"][0]
self.assertEqual(art["status"], "INVALID")
class TestSymlinkEscape(unittest.TestCase):
"""UNVERIFIABLE: symlinks that escape the designated root."""
def test_symlink_escape_is_unverifiable(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
link = tmp / "escape_link.txt"
link.symlink_to("/etc/hostname")
result = _run_audit(tmp, _manifest([{
"path": "escape_link.txt",
"type": "result_record",
}]))
art = result["artifacts"][0]
self.assertIn(art["status"], ("UNVERIFIABLE", "INVALID"))
def test_internal_symlink_is_handled(self):
"""A symlink that stays within root is rejected as UNVERIFIABLE under O_NOFOLLOW boundary."""
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
target = tmp / "real.txt"
target.write_bytes(b"data")
link = tmp / "link.txt"
link.symlink_to(target)
result = _run_audit(tmp, _manifest([{
"path": "link.txt",
"type": "result_record",
}]))
art = result["artifacts"][0]
self.assertNotEqual(art["status"], "INVALID")
self.assertEqual(art["status"], "UNVERIFIABLE")
class TestStableRepeatedOutput(unittest.TestCase):
"""Stable: running the audit twice must produce identical output."""
def test_identical_output_on_repeated_runs(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
content = b"stable content"
h = _write(tmp / "a.json", content)
_write(tmp / "b.json", b"other")
manifest = _manifest([
{"path": "a.json", "type": "result_record", "expected_sha256": h},
{"path": "b.json", "type": "campaign_manifest"},
{"path": "missing.json", "type": "trajectory", "expected_sha256": "b" * 64},
])
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(manifest))
r1 = auditor.audit(str(mpath), str(tmp), deterministic=True)
r2 = auditor.audit(str(mpath), str(tmp), deterministic=True)
self.assertEqual(
json.dumps(r1, sort_keys=True),
json.dumps(r2, sort_keys=True),
"Repeated runs produced different output",
)
def test_artifacts_sorted_by_path(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
_write(tmp / "zzz.txt", b"z")
_write(tmp / "aaa.txt", b"a")
result = _run_audit(tmp, _manifest([
{"path": "zzz.txt", "type": "result_record"},
{"path": "aaa.txt", "type": "result_record"},
]))
paths = [a["path"] for a in result["artifacts"]]
self.assertEqual(paths, sorted(paths))
class TestEmptyManifest(unittest.TestCase):
"""Empty artifact list is valid but produces zero results."""
def test_empty_artifacts_list(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
result = _run_audit(tmp, _manifest([]))
self.assertTrue(result["manifest_valid"])
self.assertEqual(result["artifacts"], [])
self.assertEqual(result["totals"]["total"], 0)
class TestMixedOutcomes(unittest.TestCase):
"""Multiple artifacts with mixed verification outcomes."""
def test_mixed_verified_missing_mismatch_observed(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
good_content = b"good"
good_h = _write(tmp / "good.json", good_content)
bad_content = b"actual"
_write(tmp / "bad.json", bad_content)
_write(tmp / "noexpect.json", b"whatever")
wrong_h = _sha256(b"expected but wrong")
result = _run_audit(tmp, _manifest([
{"path": "good.json", "type": "result_record", "expected_sha256": good_h},
{"path": "bad.json", "type": "result_record", "expected_sha256": wrong_h},
{"path": "missing.json", "type": "trajectory", "expected_sha256": "c" * 64},
{"path": "noexpect.json", "type": "campaign_manifest"},
]))
statuses = {a["path"]: a["status"] for a in result["artifacts"]}
self.assertEqual(statuses["good.json"], "VERIFIED")
self.assertEqual(statuses["bad.json"], "MISMATCH")
self.assertEqual(statuses["missing.json"], "MISSING")
self.assertEqual(statuses["noexpect.json"], "OBSERVED_ONLY")
t = result["totals"]
self.assertEqual(t["VERIFIED"], 1)
self.assertEqual(t["MISMATCH"], 1)
self.assertEqual(t["MISSING"], 1)
self.assertEqual(t["OBSERVED_ONLY"], 1)
self.assertEqual(t["total"], 4)
class TestNeverVerifiedFromOwnHash(unittest.TestCase):
"""The utility must not auto-verify by computing and comparing its own hash."""
def test_no_expected_hash_means_not_verified(self):
"""An artifact with no expected_sha256 must never be VERIFIED."""
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
_write(tmp / "auto.txt", b"some data")
result = _run_audit(tmp, _manifest([{
"path": "auto.txt",
"type": "model_artifact",
}]))
art = result["artifacts"][0]
self.assertNotEqual(art["status"], "VERIFIED",
"Artifact must not be VERIFIED without an independently provided expected hash")
self.assertEqual(art["status"], "OBSERVED_ONLY")
class TestReproducibilityPrerequisites(unittest.TestCase):
"""Reproducibility prerequisites section is present and populated."""
def test_reproducibility_keys_present(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
result = _run_audit(tmp, _manifest([]))
prereqs = result.get("reproducibility_prerequisites", {})
expected_keys = {
"model_artifact_hash",
"source_checkpoint_revision",
"quantization_info",
"backend_executable_identity",
"chat_template_identity",
"context_and_decoding_config",
"task_fixture_identities",
"expected_outcomes_and_oracles",
"raw_trajectories",
"result_and_latency_records",
}
self.assertEqual(set(prereqs.keys()), expected_keys)
def test_model_artifact_hash_unknown_without_artifact(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
result = _run_audit(tmp, _manifest([]))
self.assertEqual(
result["reproducibility_prerequisites"]["model_artifact_hash"],
"UNKNOWN",
)
def test_model_artifact_hash_observed_when_type_present(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
_write(tmp / "model.gguf.txt", b"placeholder")
result = _run_audit(tmp, _manifest([{
"path": "model.gguf.txt",
"type": "model_artifact",
}]))
val = result["reproducibility_prerequisites"]["model_artifact_hash"]
self.assertNotEqual(val, "UNKNOWN",
"model_artifact_hash should not be UNKNOWN when a model_artifact is present")
class TestOutputStructure(unittest.TestCase):
"""Output JSON has required top-level fields."""
def test_required_top_level_fields(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
result = _run_audit(tmp, _manifest([]))
for key in ("schema_version", "audited_at", "campaign_id", "root",
"manifest_path", "totals", "artifacts",
"reproducibility_prerequisites", "reproducibility_details",
"errors", "manifest_valid"):
self.assertIn(key, result, f"Missing top-level key: {key}")
def test_schema_version_is_one(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
result = _run_audit(tmp, _manifest([]))
self.assertEqual(result["schema_version"], 1)
# ---------------------------------------------------------------------------
# Finding 1: Output Destination Overwrite & TOCTOU Protection
# ---------------------------------------------------------------------------
class TestFinding1OutputProtection(unittest.TestCase):
"""Regression tests for Finding 1 (P1): Output publication remains vulnerable to TOCTOU."""
def test_output_targeting_manifest_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
content = json.dumps(_manifest([])).encode()
mpath.write_bytes(content)
code = auditor.main([str(mpath), str(tmp), "--output", str(mpath)])
self.assertEqual(code, 2)
self.assertEqual(mpath.read_bytes(), content, "Manifest was modified by output destination")
def test_summary_targeting_audited_artifact_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
art_file = tmp / "evidence.dat"
original_bytes = b"precious_historical_evidence"
art_file.write_bytes(original_bytes)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([{"path": "evidence.dat", "type": "result_record"}])))
code = auditor.main([str(mpath), str(tmp), "--summary", str(art_file)])
self.assertEqual(code, 2)
self.assertEqual(art_file.read_bytes(), original_bytes, "Audited artifact was overwritten")
def test_output_and_summary_same_destination_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
dest = tmp / "collision.txt"
code = auditor.main([str(mpath), str(tmp), "--output", str(dest), "--summary", str(dest)])
self.assertEqual(code, 2)
self.assertFalse(dest.exists(), "File should not be created on destination collision")
def test_existing_symlink_alias_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
original = json.dumps(_manifest([])).encode()
mpath.write_bytes(original)
link_out = tmp / "link_manifest.json"
link_out.symlink_to(mpath)
code = auditor.main([str(mpath), str(tmp), "--output", str(link_out)])
self.assertEqual(code, 2)
self.assertEqual(mpath.read_bytes(), original)
def test_existing_hardlink_alias_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
art_file = tmp / "original.txt"
original_bytes = b"immutable_artifact"
art_file.write_bytes(original_bytes)
hardlink_file = tmp / "hardlink.txt"
os.link(art_file, hardlink_file)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([{"path": "original.txt", "type": "result_record"}])))
code = auditor.main([str(mpath), str(tmp), "--summary", str(hardlink_file)])
self.assertEqual(code, 2)
self.assertEqual(art_file.read_bytes(), original_bytes)
def test_injected_destination_replacement_after_preflight_blocks_overwrite(self):
"""Adversarial TOCTOU test: destination is substituted with symlink after preflight."""
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
art_file = tmp / "protected.dat"
original_bytes = b"IMMUTABLE_HISTORICAL_DATA"
art_file.write_bytes(original_bytes)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([{"path": "protected.dat", "type": "result_record"}])))
target_out = tmp / "safe_destination.json"
# Inject symlink substitution after preflight succeeds
orig_validate = auditor._validate_output_destinations
def injected_validation(*args, **kwargs):
errs = orig_validate(*args, **kwargs)
# Inject malicious symlink pointing to protected artifact after preflight check
if target_out.exists():
target_out.unlink()
target_out.symlink_to(art_file)
return errs
auditor._validate_output_destinations = injected_validation
try:
code = auditor.main([str(mpath), str(tmp), "--output", str(target_out)])
self.assertEqual(code, 2, "CLI should reject publication when destination points to protected artifact")
self.assertEqual(art_file.read_bytes(), original_bytes, "Protected artifact was overwritten!")
finally:
auditor._validate_output_destinations = orig_validate
def test_nested_output_directory_symlink_replacement_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
outside = tmp / "outside"
outside.mkdir()
sub = tmp / "nested_dir"
sub.symlink_to(outside)
code = auditor.main([str(mpath), str(tmp), "--output", str(sub / "report.json")])
self.assertEqual(code, 2)
self.assertFalse((outside / "report.json").exists())
def test_failed_publication_preserves_existing_protected_input_bytes(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
art = tmp / "artifact.dat"
sentinel = b"SENTINEL_BYTES_PRESERVED"
art.write_bytes(sentinel)
mpath = tmp / "manifest.json"
m_bytes = json.dumps(_manifest([{"path": "artifact.dat", "type": "result_record"}])).encode()
mpath.write_bytes(m_bytes)
code = auditor.main([str(mpath), str(tmp), "--output", str(art)])
self.assertEqual(code, 2)
self.assertEqual(art.read_bytes(), sentinel)
self.assertEqual(mpath.read_bytes(), m_bytes)
def test_temporary_files_are_cleaned_up_after_failure(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
art = tmp / "artifact.dat"
art.write_bytes(b"data")
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([{"path": "artifact.dat", "type": "result_record"}])))
out_dir = tmp / "out_dir"
out_dir.mkdir()
out_file = out_dir / "target.json"
out_file.symlink_to(art)
auditor.main([str(mpath), str(tmp), "--output", str(out_file)])
# Verify no .tmp_* files remain in out_dir
leftover_tmps = [p for p in out_dir.iterdir() if p.name.startswith(".tmp_")]
self.assertEqual(leftover_tmps, [], "Temporary files leaked in output directory")
def test_valid_distinct_json_output_destination_works(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
out = tmp / "out.json"
code = auditor.main([str(mpath), str(tmp), "--output", str(out)])
self.assertEqual(code, 0)
self.assertTrue(out.is_file())
parsed = json.loads(out.read_text())
self.assertTrue(parsed["manifest_valid"])
def test_valid_distinct_markdown_summary_destination_works(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
summ = tmp / "summary.md"
code = auditor.main([str(mpath), str(tmp), "--summary", str(summ)])
self.assertEqual(code, 0)
self.assertTrue(summ.is_file())
self.assertIn("Benchmark Evidence Audit Summary", summ.read_text())
def test_repeated_successful_publication_produces_complete_valid_files(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
out = tmp / "out.json"
code1 = auditor.main([str(mpath), str(tmp), "--output", str(out), "--deterministic"])
bytes1 = out.read_bytes()
code2 = auditor.main([str(mpath), str(tmp), "--output", str(out), "--deterministic"])
bytes2 = out.read_bytes()
self.assertEqual(code1, 0)
self.assertEqual(code2, 0)
self.assertEqual(bytes1, bytes2)
# ---------------------------------------------------------------------------
# Finding 2: Conservative Prerequisite Completeness Model
# ---------------------------------------------------------------------------
class TestFinding2PrerequisiteCompleteness(unittest.TestCase):
"""Mandatory regressions for Finding 2 (P2): Campaign prerequisite completeness."""
def test_1_one_verified_trajectory_without_completeness_evidence(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
h = _write(tmp / "t1.json", b"single_trajectory")
res = _run_audit(tmp, _manifest([{"path": "t1.json", "type": "trajectory", "expected_sha256": h}]))
# Prerequisite completeness is NOT verified when expected-set completeness is unknown
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], "PARTIAL")
det = res["reproducibility_details"]["raw_trajectories"]
self.assertEqual(det["artifact_integrity"], "VERIFIED")
self.assertEqual(det["expected_set_status"], "UNKNOWN")
self.assertFalse(det["prerequisite_complete"])
def test_2_two_verified_trajectories_with_unknown_expected_set_completeness(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
h1 = _write(tmp / "t1.json", b"traj1")
h2 = _write(tmp / "t2.json", b"traj2")
res = _run_audit(tmp, _manifest([
{"path": "t1.json", "type": "trajectory", "expected_sha256": h1},
{"path": "t2.json", "type": "trajectory", "expected_sha256": h2},
]))
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], "PARTIAL")
det = res["reproducibility_details"]["raw_trajectories"]
self.assertEqual(det["artifact_integrity"], "VERIFIED")
self.assertEqual(det["expected_set_status"], "UNKNOWN")
self.assertFalse(det["prerequisite_complete"])
def test_3_complete_independently_established_expected_set_all_verify(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
h1 = _write(tmp / "t1.json", b"traj1")
h2 = _write(tmp / "t2.json", b"traj2")
trusted_src = "https://specs.example.org/qwen-e00-trajectories.json"
expected_sets = {
"raw_trajectories": {
"expected_paths": ["t1.json", "t2.json"],
"provenance": trusted_src,
"independent_oracle": True,
}
}
res = _run_audit(
tmp,
_manifest([
{"path": "t1.json", "type": "trajectory", "expected_sha256": h1},
{"path": "t2.json", "type": "trajectory", "expected_sha256": h2},
], expected_sets=expected_sets),
trusted_sources=[trusted_src],
)
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], "VERIFIED")
det = res["reproducibility_details"]["raw_trajectories"]
self.assertEqual(det["artifact_integrity"], "VERIFIED")
self.assertEqual(det["expected_set_status"], "COMPLETE")
self.assertTrue(det["prerequisite_complete"])
self.assertEqual(det["missing_or_unverified"], [])
def test_4_established_expected_set_with_one_missing_artifact(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
h1 = _write(tmp / "t1.json", b"traj1")
trusted_src = "https://specs.example.org/qwen-e00-trajectories.json"
expected_sets = {
"raw_trajectories": {
"expected_paths": ["t1.json", "t2_missing.json"],
"provenance": trusted_src,
"independent_oracle": True,
}
}
res = _run_audit(
tmp,
_manifest([
{"path": "t1.json", "type": "trajectory", "expected_sha256": h1},
{"path": "t2_missing.json", "type": "trajectory", "expected_sha256": "0" * 64},
], expected_sets=expected_sets),
trusted_sources=[trusted_src],
)
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], "INCOMPLETE")
det = res["reproducibility_details"]["raw_trajectories"]
self.assertFalse(det["prerequisite_complete"])
self.assertIn("t2_missing.json", det["missing_or_unverified"])
def test_5_established_expected_set_with_one_mismatch_artifact(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
h1 = _write(tmp / "t1.json", b"traj1")
_write(tmp / "t2.json", b"actual_content")
trusted_src = "https://specs.example.org/qwen-e00-trajectories.json"
expected_sets = {
"raw_trajectories": {
"expected_paths": ["t1.json", "t2.json"],
"provenance": trusted_src,
"independent_oracle": True,
}
}
res = _run_audit(
tmp,
_manifest([
{"path": "t1.json", "type": "trajectory", "expected_sha256": h1},
{"path": "t2.json", "type": "trajectory", "expected_sha256": "f" * 64},
], expected_sets=expected_sets),
trusted_sources=[trusted_src],
)
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], "MISMATCH")
det = res["reproducibility_details"]["raw_trajectories"]
self.assertFalse(det["prerequisite_complete"])
self.assertIn("t2.json", det["missing_or_unverified"])
def test_6_verified_plus_observed_only(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
h1 = _write(tmp / "t1.json", b"traj1")
_write(tmp / "t2.json", b"traj2")
res = _run_audit(tmp, _manifest([
{"path": "t1.json", "type": "trajectory", "expected_sha256": h1},
{"path": "t2.json", "type": "trajectory"},
]))
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], "PARTIAL")
def test_7_optional_verified_artifacts_with_missing_mandatory_artifact(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
h_opt = _write(tmp / "optional.json", b"opt")
res = _run_audit(tmp, _manifest([
{"path": "mandatory.json", "type": "trajectory", "expected_sha256": "1" * 64, "mandatory": True},
{"path": "optional.json", "type": "trajectory", "expected_sha256": h_opt, "mandatory": False},
]))
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], "INCOMPLETE")
def test_8_empty_declared_artifact_set(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
res = _run_audit(tmp, _manifest([]))
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], "UNKNOWN")
def test_9_incomplete_archive_with_self_declared_completeness_flag(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
h1 = _write(tmp / "t1.json", b"traj1")
expected_sets = {
"raw_trajectories": {
"expected_paths": ["t1.json"],
"complete": True,
"provenance": "internal-collector-self-claim",
"independent_oracle": False, # Not independently verified!
}
}
res = _run_audit(tmp, _manifest([
{"path": "t1.json", "type": "trajectory", "expected_sha256": h1},
], expected_sets=expected_sets))
# Unverified self-claim must not be accepted as verified completeness
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], "PARTIAL")
det = res["reproducibility_details"]["raw_trajectories"]
self.assertEqual(det["expected_set_status"], "UNVERIFIED_CLAIM")
self.assertFalse(det["prerequisite_complete"])
def test_10_checksum_matched_summary_document_does_not_prove_task_level_oracles(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
content = b'{"task_specifications": "summary_only"}'
h = _write(tmp / "freeze-manifest.json", content)
res = _run_audit(tmp, _manifest([
{"path": "freeze-manifest.json", "type": "oracle_definition", "expected_sha256": h, "is_summary": True},
]))
art = res["artifacts"][0]
self.assertEqual(art["status"], "VERIFIED", "File checksum integrity verified")
# Prerequisite completeness is NOT verified: summary does not prove task-level oracles
self.assertEqual(res["reproducibility_prerequisites"]["expected_outcomes_and_oracles"], "OBSERVED_ONLY")
det = res["reproducibility_details"]["expected_outcomes_and_oracles"]
self.assertEqual(det["expected_set_status"], "SUMMARY_ONLY")
self.assertFalse(det["prerequisite_complete"])
self.assertIn("summary document does not prove", det["notes"])
def test_11_checksum_matched_aggregate_report_does_not_prove_complete_latency_records(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
content = b"# Aggregate Benchmark Report\nOverall latency: 120ms\n"
h = _write(tmp / "campaign-report.md", content)
res = _run_audit(tmp, _manifest([
{"path": "campaign-report.md", "type": "result_record", "expected_sha256": h, "is_summary": True},
]))
art = res["artifacts"][0]
self.assertEqual(art["status"], "VERIFIED", "Report file checksum integrity verified")
# Prerequisite completeness is NOT verified: aggregate statistics do not prove per-turn latency
self.assertEqual(res["reproducibility_prerequisites"]["result_and_latency_records"], "OBSERVED_ONLY")
det = res["reproducibility_details"]["result_and_latency_records"]
self.assertEqual(det["expected_set_status"], "AGGREGATE_ONLY")
self.assertFalse(det["prerequisite_complete"])
self.assertIn("aggregate statistics do not prove", det["notes"])
def test_12_stable_output_regardless_of_manifest_ordering(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
h1 = _write(tmp / "t1.json", b"traj1")
_write(tmp / "t2.json", b"traj2")
e1 = {"path": "t1.json", "type": "trajectory", "expected_sha256": h1}
e2 = {"path": "t2.json", "type": "trajectory", "expected_sha256": "0" * 64}
res1 = _run_audit(tmp, _manifest([e1, e2], campaign_id="STABLE"))
res2 = _run_audit(tmp, _manifest([e2, e1], campaign_id="STABLE"))
self.assertEqual(
res1["reproducibility_prerequisites"],
res2["reproducibility_prerequisites"],
)
self.assertEqual(
res1["reproducibility_details"],
res2["reproducibility_details"],
)
# ---------------------------------------------------------------------------
# Finding 3: Symlink TOCTOU and O_NOFOLLOW Enforcement
# ---------------------------------------------------------------------------
class TestFinding3SymlinkTOCTOU(unittest.TestCase):
"""Regression tests for Finding 3 (P2): Symlink time-of-check/time-of-use vulnerability."""
def test_ordinary_regular_file_inside_root(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
content = b"regular_inside_root"
h = _write(tmp / "subdir" / "data.txt", content)
res = _run_audit(tmp, _manifest([{
"path": "subdir/data.txt",
"type": "result_record",
"expected_sha256": h,
}]))
art = res["artifacts"][0]
self.assertEqual(art["status"], "VERIFIED")
self.assertEqual(art["observed_sha256"], h)
def test_direct_symlink_escaping_root(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
link = tmp / "escape_passwd"
link.symlink_to("/etc/passwd")
res = _run_audit(tmp, _manifest([{"path": "escape_passwd", "type": "result_record"}]))
art = res["artifacts"][0]
self.assertEqual(art["status"], "UNVERIFIABLE")
self.assertIsNone(art["observed_sha256"])
def test_nested_symlink_escaping_root(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
sub = tmp / "a" / "b"
sub.mkdir(parents=True)
link = sub / "nested_escape"
link.symlink_to("/etc/passwd")
res = _run_audit(tmp, _manifest([{"path": "a/b/nested_escape", "type": "result_record"}]))
art = res["artifacts"][0]
self.assertEqual(art["status"], "UNVERIFIABLE")
self.assertIsNone(art["observed_sha256"])
def test_symlink_directory_component_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
outside = Path(tempfile.mkdtemp())
try:
(outside / "secret.txt").write_bytes(b"secret")
(tmp / "linkdir").symlink_to(outside)
res = _run_audit(tmp, _manifest([{"path": "linkdir/secret.txt", "type": "result_record"}]))
art = res["artifacts"][0]
self.assertEqual(art["status"], "UNVERIFIABLE")
self.assertIsNone(art["observed_sha256"])
finally:
import shutil
shutil.rmtree(outside)
def test_safe_handling_of_missing_or_replaced_files(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
res = _run_audit(tmp, _manifest([{"path": "missing/dir/file.txt", "type": "result_record"}]))
art = res["artifacts"][0]
self.assertEqual(art["status"], "MISSING")
def test_no_outside_root_file_access(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
secret_outside = Path(tempfile.mkdtemp())
try:
secret_file = secret_outside / "secret.dat"
secret_file.write_bytes(b"TOP_SECRET_DATA")
secret_hash = _sha256(b"TOP_SECRET_DATA")
link = tmp / "secret_link"
link.symlink_to(secret_file)
res = _run_audit(tmp, _manifest([{
"path": "secret_link",
"type": "result_record",
"expected_sha256": secret_hash,
}]))
art = res["artifacts"][0]
self.assertEqual(art["status"], "UNVERIFIABLE")
self.assertIsNone(art["observed_sha256"], "Outside-root content was read or hashed")
finally:
import shutil
shutil.rmtree(secret_outside)
def test_no_descriptor_leaks_after_failure(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
(tmp / "bad_link").symlink_to("/etc/passwd")
fd_dir = Path(f"/proc/{os.getpid()}/fd")
if not fd_dir.exists():
self.skipTest("/proc/self/fd not accessible on this platform")
# Warm-up run
_run_audit(tmp, _manifest([{"path": "bad_link", "type": "result_record"}]))
fds_before = len(list(fd_dir.iterdir()))
for _ in range(10):
_run_audit(tmp, _manifest([
{"path": "bad_link", "type": "result_record"},
{"path": "missing.txt", "type": "result_record"},
{"path": "../outside.txt", "type": "result_record"},
]))
fds_after = len(list(fd_dir.iterdir()))
self.assertEqual(fds_before, fds_after, "File descriptor leak detected")
# ---------------------------------------------------------------------------
# Finding 4: Malformed Manifest Handling
# ---------------------------------------------------------------------------
class TestFinding4MalformedManifest(unittest.TestCase):
"""Regression tests for Finding 4 (P2): Malformed manifest handling."""
def test_invalid_list_path(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
res = _run_audit(tmp, _manifest([{"path": ["invalid", "list"], "type": "result_record"}]))
self.assertEqual(res["totals"]["INVALID"], 1)
self.assertEqual(res["artifacts"][0]["status"], "INVALID")
def test_invalid_integer_path(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
res = _run_audit(tmp, _manifest([{"path": 12345, "type": "result_record"}]))
self.assertEqual(res["totals"]["INVALID"], 1)
self.assertEqual(res["artifacts"][0]["status"], "INVALID")
def test_invalid_null_path(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
res = _run_audit(tmp, _manifest([{"path": None, "type": "result_record"}]))
self.assertEqual(res["totals"]["INVALID"], 1)
self.assertEqual(res["artifacts"][0]["status"], "INVALID")
def test_invalid_boolean_expected_hash(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
_write(tmp / "file.txt", b"data")
res_false = _run_audit(tmp, _manifest([{"path": "file.txt", "type": "result_record", "expected_sha256": False}]))
self.assertEqual(res_false["totals"]["INVALID"], 1)
self.assertEqual(res_false["artifacts"][0]["status"], "INVALID")
res_true = _run_audit(tmp, _manifest([{"path": "file.txt", "type": "result_record", "expected_sha256": True}]))
self.assertEqual(res_true["totals"]["INVALID"], 1)
self.assertEqual(res_true["artifacts"][0]["status"], "INVALID")
def test_invalid_numeric_expected_hash(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
_write(tmp / "file.txt", b"data")
res = _run_audit(tmp, _manifest([{"path": "file.txt", "type": "result_record", "expected_sha256": 1234567890}]))
self.assertEqual(res["totals"]["INVALID"], 1)
self.assertEqual(res["artifacts"][0]["status"], "INVALID")
def test_invalid_malformed_hexadecimal_hash(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
_write(tmp / "file.txt", b"data")
res = _run_audit(tmp, _manifest([{"path": "file.txt", "type": "result_record", "expected_sha256": "g" * 64}]))
self.assertEqual(res["totals"]["INVALID"], 1)
self.assertEqual(res["artifacts"][0]["status"], "INVALID")
def test_invalid_wrong_length_hash(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
_write(tmp / "file.txt", b"data")
res = _run_audit(tmp, _manifest([{"path": "file.txt", "type": "result_record", "expected_sha256": "a" * 32}]))
self.assertEqual(res["totals"]["INVALID"], 1)
self.assertEqual(res["artifacts"][0]["status"], "INVALID")
def test_invalid_artifact_record_structure(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
res = _run_audit(tmp, _manifest(["not_a_dict", 42, None]))
self.assertEqual(res["totals"]["INVALID"], 3)
for art in res["artifacts"]:
self.assertEqual(art["status"], "INVALID")
def test_missing_required_path_field(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
res = _run_audit(tmp, _manifest([{"type": "result_record"}]))
self.assertEqual(res["totals"]["INVALID"], 1)
self.assertEqual(res["artifacts"][0]["status"], "INVALID")
def test_mixed_valid_and_invalid_entries(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
h = _write(tmp / "good.txt", b"content")
res = _run_audit(tmp, _manifest([
{"path": "good.txt", "type": "result_record", "expected_sha256": h},
{"path": ["bad", "list"], "type": "result_record"},
{"path": "bad_hash.txt", "type": "result_record", "expected_sha256": False},
]))
self.assertEqual(res["totals"]["VERIFIED"], 1)
self.assertEqual(res["totals"]["INVALID"], 2)
# ---------------------------------------------------------------------------
# Deterministic Output Mode
# ---------------------------------------------------------------------------
class TestDeterministicOutputMode(unittest.TestCase):
"""Test deterministic CLI mode generates identical output bytes."""
def test_deterministic_cli_flag_produces_identical_bytes(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
out1 = tmp / "out1.json"
out2 = tmp / "out2.json"
code1 = auditor.main([str(mpath), str(tmp), "--output", str(out1), "--deterministic"])
code2 = auditor.main([str(mpath), str(tmp), "--output", str(out2), "--deterministic"])
self.assertEqual(code1, 0)
self.assertEqual(code2, 0)
self.assertEqual(out1.read_bytes(), out2.read_bytes(), "Deterministic runs differed in output bytes")
# ---------------------------------------------------------------------------
# Additional Regressions for Final Security & Evidence Findings
# ---------------------------------------------------------------------------
class TestFinding1ParentDirectorySubstitution(unittest.TestCase):
"""P1: Output parent directory substitution protection."""
def test_intermediate_directory_symlink_substitution_blocked_and_target_preserved(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
# Create a protected target directory containing sensitive files
protected_dir = tmp / "protected"
protected_dir.mkdir()
protected_file = protected_dir / "secret_evidence.dat"
original_bytes = b"ORIGINAL PROTECTED EVIDENCE - DO NOT OVERWRITE"
protected_file.write_bytes(original_bytes)
# Create an intermediate directory structure
base_out = tmp / "output_root"
base_out.mkdir()
# Replace intermediate component with a symlink pointing to the protected directory
inter_symlink = base_out / "intermediate"
os.symlink(str(protected_dir), str(inter_symlink))
# Attempt publication targeting a path through the intermediate symlink
dest = inter_symlink / "secret_evidence.dat"
protected_paths, protected_inodes = auditor._collect_protected_targets(
str(tmp / "manifest.json"),
str(tmp),
[{"path": "secret_evidence.dat", "type": "result_record"}],
)
# Explicitly register protected file
protected_paths[protected_file.resolve()] = "protected file"
st = protected_file.stat()
protected_inodes[(st.st_dev, st.st_ino)] = "protected file"
with self.assertRaises(OSError) as ctx:
auditor._publish_file_securely(
str(dest),
"MALICIOUS OVERWRITE CONTENT",
protected_paths,
protected_inodes,
)
self.assertIn("symlink", str(ctx.exception).lower())
# Verify the protected file bytes are completely unchanged
self.assertEqual(protected_file.read_bytes(), original_bytes)
def test_cli_intermediate_directory_symlink_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
outside = tmp / "outside"
outside.mkdir()
canary = outside / "canary.txt"
canary.write_bytes(b"CANARY UNTOUCHED")
out_tree = tmp / "out_tree"
out_tree.mkdir()
sym_dir = out_tree / "sym_sub"
os.symlink(str(outside), str(sym_dir))
target_out = sym_dir / "out.json"
code = auditor.main([str(mpath), str(tmp), "--output", str(target_out)])
self.assertEqual(code, 2)
self.assertEqual(canary.read_bytes(), b"CANARY UNTOUCHED")
class TestFinding2ArtifactRootSubstitution(unittest.TestCase):
"""P2: Artifact root substitution and outside-root read protection."""
def test_root_directory_symlink_rejected_and_outside_file_not_verified(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
# Create outside secret directory
outside_dir = tmp / "outside_secret"
outside_dir.mkdir()
secret_file = outside_dir / "confidential.dat"
secret_bytes = b"CONFIDENTIAL SYSTEM DATA"
secret_file.write_bytes(secret_bytes)
expected_hash = _sha256(secret_bytes)
# Create symlink root pointing to outside directory
symlink_root = tmp / "symlink_root"
os.symlink(str(outside_dir), str(symlink_root))
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([{
"path": "confidential.dat",
"type": "result_record",
"expected_sha256": expected_hash,
}])))
# Audit against symlink root
res = auditor.audit(str(mpath), str(symlink_root))
art = res["artifacts"][0]
self.assertEqual(art["status"], "UNVERIFIABLE")
self.assertFalse(art["present"])
self.assertIsNone(art["observed_sha256"])
self.assertFalse(art["hash_match"])
self.assertIn("root directory is invalid or a symlink", art["notes"])
self.assertEqual(res["totals"]["VERIFIED"], 0)
self.assertEqual(res["totals"]["UNVERIFIABLE"], 1)
def test_root_replaced_with_symlink_during_audit(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
real_root = tmp / "root_dir"
real_root.mkdir()
outside = tmp / "outside"
outside.mkdir()
h = _write(outside / "data.txt", b"outside data")
# Replace real root with symlink
real_root.rmdir()
os.symlink(str(outside), str(real_root))
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([{
"path": "data.txt",
"type": "result_record",
"expected_sha256": h,
}])))
res = auditor.audit(str(mpath), str(real_root))
self.assertEqual(res["artifacts"][0]["status"], "UNVERIFIABLE")
self.assertEqual(res["totals"]["VERIFIED"], 0)
def test_no_descriptor_leaks_after_root_symlink_rejections(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
sym_root = tmp / "sym_root"
os.symlink(str(tmp), str(sym_root))
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([{"path": "file.txt", "type": "result_record"}])))
fd_dir = Path(f"/proc/{os.getpid()}/fd")
if not fd_dir.exists():
self.skipTest("/proc/self/fd not accessible on this platform")
# Warm-up run
auditor.audit(str(mpath), str(sym_root))
fds_before = len(list(fd_dir.iterdir()))
for _ in range(10):
auditor.audit(str(mpath), str(sym_root))
fds_after = len(list(fd_dir.iterdir()))
self.assertEqual(fds_before, fds_after, "Descriptor leak detected after root symlink rejections")
class TestFinding3ProvenanceTrust(unittest.TestCase):
"""P2: Self-attested independent provenance and trusted verification source."""
def test_fabricated_provenance_url_cannot_produce_verified(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
h1 = _write(tmp / "t1.json", b"traj1")
h2 = _write(tmp / "t2.json", b"traj2")
expected_sets = {
"raw_trajectories": {
"expected_paths": ["t1.json", "t2.json"],
"provenance": "https://fabricated-external-oracle.org/claims.json",
"independent_oracle": True,
}
}
# Run without trusted source
res = _run_audit(tmp, _manifest([
{"path": "t1.json", "type": "trajectory", "expected_sha256": h1},
{"path": "t2.json", "type": "trajectory", "expected_sha256": h2},
], expected_sets=expected_sets))
# Must NOT produce VERIFIED
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], "PARTIAL")
det = res["reproducibility_details"]["raw_trajectories"]
self.assertEqual(det["artifact_integrity"], "VERIFIED")
self.assertEqual(det["expected_set_status"], "UNVERIFIED")
self.assertEqual(det["expected_set_source"], "declared")
self.assertFalse(det["prerequisite_complete"])
self.assertIn("lacks separately trusted verification source", det["notes"])
def test_self_declared_completeness_flag_cannot_produce_verified(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
h1 = _write(tmp / "t1.json", b"traj1")
expected_sets = {
"raw_trajectories": {
"expected_paths": ["t1.json"],
"complete": True,
"provenance": "internal-self-assertion",
}
}
res = _run_audit(tmp, _manifest([
{"path": "t1.json", "type": "trajectory", "expected_sha256": h1},
], expected_sets=expected_sets))
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], "PARTIAL")
det = res["reproducibility_details"]["raw_trajectories"]
self.assertEqual(det["expected_set_status"], "UNVERIFIED_CLAIM")
self.assertFalse(det["prerequisite_complete"])
def test_partial_manifest_with_trusted_source_cannot_produce_verified(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
h1 = _write(tmp / "t1.json", b"traj1")
trusted_src = "https://official-specs.org/e00.json"
expected_sets = {
"raw_trajectories": {
"expected_paths": ["t1.json", "t2_missing.json"],
"provenance": trusted_src,
"independent_oracle": True,
}
}
res = _run_audit(
tmp,
_manifest([
{"path": "t1.json", "type": "trajectory", "expected_sha256": h1},
], expected_sets=expected_sets),
trusted_sources=[trusted_src],
)
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], "INCOMPLETE")
det = res["reproducibility_details"]["raw_trajectories"]
self.assertFalse(det["prerequisite_complete"])
self.assertIn("t2_missing.json", det["missing_or_unverified"])
def test_untrusted_provenance_mismatch_cannot_produce_verified(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
h1 = _write(tmp / "t1.json", b"traj1")
expected_sets = {
"raw_trajectories": {
"expected_paths": ["t1.json"],
"provenance": "https://unapproved-oracle.org",
"independent_oracle": True,
}
}
res = _run_audit(
tmp,
_manifest([
{"path": "t1.json", "type": "trajectory", "expected_sha256": h1},
], expected_sets=expected_sets),
trusted_sources=["https://approved-oracle.org"],
)
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], "PARTIAL")
det = res["reproducibility_details"]["raw_trajectories"]
self.assertEqual(det["expected_set_status"], "UNVERIFIED")
self.assertFalse(det["prerequisite_complete"])
def test_external_trusted_expected_sets_file_works(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
h1 = _write(tmp / "t1.json", b"traj1")
h2 = _write(tmp / "t2.json", b"traj2")
trusted_sets_file = tmp / "trusted_sets.json"
trusted_sets_file.write_text(json.dumps({
"raw_trajectories": {
"expected_paths": ["t1.json", "t2.json"],
"provenance": "official-e00-spec",
}
}))
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([
{"path": "t1.json", "type": "trajectory", "expected_sha256": h1},
{"path": "t2.json", "type": "trajectory", "expected_sha256": h2},
])))
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(trusted_sets_file))
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], "VERIFIED")
det = res["reproducibility_details"]["raw_trajectories"]
self.assertEqual(det["expected_set_status"], "COMPLETE")
self.assertEqual(det["expected_set_source"], "externally_verified")
self.assertTrue(det["prerequisite_complete"])
class TestFinding4MalformedExpectedSets(unittest.TestCase):
"""P2: Malformed expected-set definitions and structural validation."""
def test_expected_sets_as_list_handled_without_attribute_error(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mdata = _manifest([])
mdata["expected_sets"] = [] # list instead of dict
mpath.write_text(json.dumps(mdata))
res = auditor.audit(str(mpath), str(tmp))
self.assertFalse(res["manifest_valid"])
self.assertTrue(any("expected_sets must be a JSON object" in e for e in res["errors"]))
# Direct call to _build_prereqs with list must also not raise AttributeError
prereqs, details = auditor._build_prereqs([], [])
self.assertEqual(prereqs["raw_trajectories"], "INVALID")
self.assertEqual(details["raw_trajectories"]["status"], "INVALID")
def test_expected_paths_containing_dict_object_handled_without_type_error(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mdata = _manifest([])
mdata["expected_sets"] = {
"raw_trajectories": {
"expected_paths": [{"nested": "unhashable_dict"}],
}
}
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(mdata))
res = auditor.audit(str(mpath), str(tmp))
self.assertFalse(res["manifest_valid"])
self.assertTrue(any("must be string" in e for e in res["errors"]))
# Direct call to _build_prereqs must also handle safely
prereqs, details = auditor._build_prereqs([], mdata["expected_sets"])
self.assertEqual(prereqs["raw_trajectories"], "INVALID")
self.assertEqual(details["raw_trajectories"]["expected_set_status"], "INVALID")
def test_empty_expected_paths_list_does_not_produce_verified(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
h = _write(tmp / "t1.json", b"content")
trusted_src = "https://specs.example.org/oracle.json"
mdata = _manifest([
{"path": "t1.json", "type": "trajectory", "expected_sha256": h},
])
mdata["expected_sets"] = {
"raw_trajectories": {
"expected_paths": [], # Empty list!
"provenance": trusted_src,
"independent_oracle": True,
}
}
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(mdata))
res = auditor.audit(str(mpath), str(tmp), trusted_sources=[trusted_src])
self.assertNotEqual(res["reproducibility_prerequisites"]["raw_trajectories"], "VERIFIED")
self.assertFalse(res["manifest_valid"])
self.assertTrue(any("cannot be empty" in e for e in res["errors"]))
# Direct call to _build_prereqs must also handle safely without producing VERIFIED
prereqs, details = auditor._build_prereqs(
[{"path": "t1.json", "type": "trajectory", "status": "VERIFIED"}],
mdata["expected_sets"],
trusted_sources=[trusted_src],
)
self.assertNotEqual(prereqs["raw_trajectories"], "VERIFIED")
self.assertEqual(prereqs["raw_trajectories"], "INVALID")
self.assertFalse(details["raw_trajectories"]["prerequisite_complete"])
def test_expected_paths_with_non_string_items_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mdata = _manifest([])
mdata["expected_sets"] = {
"raw_trajectories": {
"expected_paths": [123, True, None],
}
}
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(mdata))
res = auditor.audit(str(mpath), str(tmp))
self.assertFalse(res["manifest_valid"])
def test_expected_paths_with_duplicate_paths_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mdata = _manifest([])
mdata["expected_sets"] = {
"raw_trajectories": {
"expected_paths": ["t1.json", "t1.json"],
}
}
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(mdata))
res = auditor.audit(str(mpath), str(tmp))
self.assertFalse(res["manifest_valid"])
self.assertTrue(any("duplicate path" in e for e in res["errors"]))
def test_expected_count_invalid_type_or_negative_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mdata = _manifest([])
mdata["expected_sets"] = {
"raw_trajectories": {
"expected_count": -5,
}
}
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(mdata))
res = auditor.audit(str(mpath), str(tmp))
self.assertFalse(res["manifest_valid"])
self.assertTrue(any("positive integer" in e for e in res["errors"]))
# ---------------------------------------------------------------------------
# Finding 1: P1, Trusted Input Overwrite Protection
# ---------------------------------------------------------------------------
class TestFinding1TrustedInputProtection(unittest.TestCase):
"""Output publication must never overwrite any trusted input file."""
def test_output_targeting_trusted_expected_sets_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
tpath = tmp / "trusted_sets.json"
tbytes = json.dumps({"raw_trajectories": {"expected_count": 1}}).encode()
tpath.write_bytes(tbytes)
code = auditor.main([
str(mpath), str(tmp),
"--trusted-expected-sets", str(tpath),
"--output", str(tpath),
])
self.assertEqual(code, 2)
self.assertEqual(tpath.read_bytes(), tbytes, "Trusted expected sets file was overwritten")
def test_summary_targeting_trusted_expected_sets_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
tpath = tmp / "trusted_sets.json"
tbytes = json.dumps({"raw_trajectories": {"expected_count": 1}}).encode()
tpath.write_bytes(tbytes)
code = auditor.main([
str(mpath), str(tmp),
"--trusted-expected-sets", str(tpath),
"--summary", str(tpath),
])
self.assertEqual(code, 2)
self.assertEqual(tpath.read_bytes(), tbytes, "Trusted expected sets file was overwritten by summary")
def test_output_symlink_alias_targeting_trusted_expected_sets_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
tpath = tmp / "trusted_sets.json"
tbytes = json.dumps({"raw_trajectories": {"expected_count": 1}}).encode()
tpath.write_bytes(tbytes)
link_out = tmp / "link_trusted.json"
link_out.symlink_to(tpath)
code = auditor.main([
str(mpath), str(tmp),
"--trusted-expected-sets", str(tpath),
"--output", str(link_out),
])
self.assertEqual(code, 2)
self.assertEqual(tpath.read_bytes(), tbytes, "Trusted expected sets overwritten via symlink alias")
def test_output_hardlink_alias_targeting_trusted_expected_sets_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
tpath = tmp / "trusted_sets.json"
tbytes = json.dumps({"raw_trajectories": {"expected_count": 1}}).encode()
tpath.write_bytes(tbytes)
hlink_out = tmp / "hlink_trusted.json"
os.link(tpath, hlink_out)
code = auditor.main([
str(mpath), str(tmp),
"--trusted-expected-sets", str(tpath),
"--output", str(hlink_out),
])
self.assertEqual(code, 2)
self.assertEqual(tpath.read_bytes(), tbytes, "Trusted expected sets overwritten via hardlink alias")
def test_distinct_legitimate_destinations_with_trusted_sets_succeeds(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
content = b'{"task": "c5"}'
chash = hashlib.sha256(content).hexdigest()
(tmp / "t1.json").write_bytes(content)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([{
"path": "t1.json",
"type": "trajectory",
"expected_sha256": chash,
"size_bytes": len(content),
}])))
tpath = tmp / "trusted_sets.json"
tpath.write_text(json.dumps({"raw_trajectories": {"expected_paths": ["t1.json"]}}))
out = tmp / "out.json"
summ = tmp / "summary.md"
code = auditor.main([
str(mpath), str(tmp),
"--trusted-expected-sets", str(tpath),
"--output", str(out),
"--summary", str(summ),
"--deterministic",
])
self.assertEqual(code, 0)
self.assertTrue(out.is_file())
self.assertTrue(summ.is_file())
def test_adversarial_post_preflight_substitution_targeting_trusted_input_blocked(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
tpath = tmp / "trusted_sets.json"
original_bytes = b'{"immutable": "evidence"}'
tpath.write_bytes(original_bytes)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
protected_paths, protected_inodes = auditor._collect_protected_targets(
str(mpath),
str(tmp),
[],
extra_input_paths=[tpath],
)
self.assertIn(tpath.resolve(), protected_paths)
self.assertIn((tpath.stat().st_dev, tpath.stat().st_ino), protected_inodes)
out_dest = tmp / "attack_out.json"
out_dest.symlink_to(tpath)
with self.assertRaises(OSError):
auditor._publish_file_securely(
str(out_dest),
"attacker payload",
protected_paths,
protected_inodes,
)
self.assertEqual(tpath.read_bytes(), original_bytes)
# ---------------------------------------------------------------------------
# Finding 2: P2, Dot-Only Path Crash Rejection
# ---------------------------------------------------------------------------
class TestFinding2DotPathRejection(unittest.TestCase):
"""Dot-only path components must be rejected cleanly as INVALID without IndexError."""
def test_dot_path_in_manifest_classified_as_invalid(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
res = _run_audit(tmp, _manifest([{"path": ".", "type": "trajectory"}]))
self.assertEqual(len(res["artifacts"]), 1)
art = res["artifacts"][0]
self.assertEqual(art["status"], auditor.INVALID)
self.assertEqual(res["totals"][auditor.INVALID], 1)
def test_dot_slash_path_in_manifest_classified_as_invalid(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
res = _run_audit(tmp, _manifest([{"path": "./", "type": "trajectory"}]))
self.assertEqual(len(res["artifacts"]), 1)
art = res["artifacts"][0]
self.assertEqual(art["status"], auditor.INVALID)
def test_dot_slash_dot_path_classified_as_invalid(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
res = _run_audit(tmp, _manifest([{"path": "././", "type": "trajectory"}]))
self.assertEqual(len(res["artifacts"]), 1)
self.assertEqual(res["artifacts"][0]["status"], auditor.INVALID)
def test_multi_dot_slash_path_classified_as_invalid(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
res = _run_audit(tmp, _manifest([{"path": ".///.", "type": "trajectory"}]))
self.assertEqual(len(res["artifacts"]), 1)
self.assertEqual(res["artifacts"][0]["status"], auditor.INVALID)
def test_empty_path_classified_as_invalid(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
res = _run_audit(tmp, _manifest([{"path": "", "type": "trajectory"}]))
self.assertEqual(len(res["artifacts"]), 1)
self.assertEqual(res["artifacts"][0]["status"], auditor.INVALID)
def test_valid_nested_path_accepted(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
sub = tmp / "nested"
sub.mkdir()
content = b"trajectory_content"
(sub / "traj.json").write_bytes(content)
chash = hashlib.sha256(content).hexdigest()
res = _run_audit(tmp, _manifest([{
"path": "nested/traj.json",
"type": "trajectory",
"expected_sha256": chash,
"size_bytes": len(content),
}]))
self.assertEqual(len(res["artifacts"]), 1)
self.assertEqual(res["artifacts"][0]["status"], auditor.VERIFIED)
def test_mixed_manifest_with_dot_path_and_valid_path(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
content = b"valid_data"
(tmp / "valid.json").write_bytes(content)
chash = hashlib.sha256(content).hexdigest()
res = _run_audit(tmp, _manifest([
{"path": ".", "type": "trajectory"},
{"path": "valid.json", "type": "trajectory", "expected_sha256": chash, "size_bytes": len(content)},
]))
self.assertEqual(res["totals"][auditor.INVALID], 1)
self.assertEqual(res["totals"][auditor.VERIFIED], 1)
by_path = {a["path"]: a["status"] for a in res["artifacts"]}
self.assertEqual(by_path["."], auditor.INVALID)
self.assertEqual(by_path["valid.json"], auditor.VERIFIED)
def test_open_and_hash_artifact_direct_dot_calls_never_raise_index_error(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
for bad_path in [".", "./", "././", ".///.", "", " "]:
status, chash, size, note = auditor._open_and_hash_artifact(tmp, bad_path)
self.assertEqual(status, auditor.INVALID)
self.assertIsNone(chash)
self.assertIsNone(size)
self.assertIsNotNone(note)
# ---------------------------------------------------------------------------
# Finding 3: P2, Unchecked Trusted-Expected-Sets Structure
# ---------------------------------------------------------------------------
class TestFinding3MalformedTrustedExpectedSets(unittest.TestCase):
"""External trusted expected-sets configuration must be strictly validated."""
def test_trusted_sets_top_level_list_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
tpath = tmp / "trusted.json"
tpath.write_text("[]")
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
self.assertFalse(res["configuration_valid"])
self.assertTrue(any("must be a JSON object" in e for e in res["errors"]))
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], auditor.INVALID)
code = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath)])
self.assertEqual(code, 2)
def test_trusted_sets_top_level_null_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
tpath = tmp / "trusted.json"
tpath.write_text("null")
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
self.assertFalse(res["configuration_valid"])
self.assertTrue(any("cannot be null" in e for e in res["errors"]))
code = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath)])
self.assertEqual(code, 2)
def test_trusted_sets_top_level_empty_dict_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
tpath = tmp / "trusted.json"
tpath.write_text("{}")
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
self.assertFalse(res["configuration_valid"])
self.assertTrue(any("cannot be an empty object" in e for e in res["errors"]))
code = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath)])
self.assertEqual(code, 2)
def test_trusted_sets_invalid_json_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
tpath = tmp / "trusted.json"
tpath.write_text("THIS IS NOT JSON {{{{")
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
self.assertFalse(res["configuration_valid"])
self.assertTrue(any("cannot load trusted_expected_sets" in e for e in res["errors"]))
code = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath)])
self.assertEqual(code, 2)
def test_trusted_sets_unknown_category_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
tpath = tmp / "trusted.json"
tpath.write_text(json.dumps({"fabricated_unknown_category": {"expected_count": 1}}))
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
self.assertFalse(res["configuration_valid"])
self.assertTrue(any("unrecognized or unsupported prerequisite category" in e for e in res["errors"]))
code = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath)])
self.assertEqual(code, 2)
def test_trusted_sets_empty_expected_paths_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
tpath = tmp / "trusted.json"
tpath.write_text(json.dumps({"raw_trajectories": {"expected_paths": []}}))
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
self.assertFalse(res["configuration_valid"])
self.assertTrue(any("cannot be empty" in e for e in res["errors"]))
code = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath)])
self.assertEqual(code, 2)
def test_trusted_sets_non_string_paths_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
tpath = tmp / "trusted.json"
tpath.write_text(json.dumps({"raw_trajectories": {"expected_paths": [42, False, None]}}))
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
self.assertFalse(res["configuration_valid"])
self.assertTrue(any("must be string" in e for e in res["errors"]))
code = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath)])
self.assertEqual(code, 2)
def test_trusted_sets_duplicate_paths_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
tpath = tmp / "trusted.json"
tpath.write_text(json.dumps({"raw_trajectories": {"expected_paths": ["a.json", "a.json"]}}))
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
self.assertFalse(res["configuration_valid"])
self.assertTrue(any("duplicate path" in e for e in res["errors"]))
code = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath)])
self.assertEqual(code, 2)
def test_trusted_sets_unsafe_path_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
tpath = tmp / "trusted.json"
tpath.write_text(json.dumps({"raw_trajectories": {"expected_paths": ["../escape.json"]}}))
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
self.assertFalse(res["configuration_valid"])
self.assertTrue(any("unsafe or invalid path" in e for e in res["errors"]))
code = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath)])
self.assertEqual(code, 2)
def test_trusted_sets_invalid_expected_count_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
tpath = tmp / "trusted.json"
tpath.write_text(json.dumps({"raw_trajectories": {"expected_count": -3}}))
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
self.assertFalse(res["configuration_valid"])
self.assertTrue(any("positive integer" in e for e in res["errors"]))
code = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath)])
self.assertEqual(code, 2)
def test_trusted_sets_conflicting_paths_and_count_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
tpath = tmp / "trusted.json"
tpath.write_text(json.dumps({
"raw_trajectories": {
"expected_paths": ["a.json", "b.json"],
"expected_count": 5,
}
}))
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
self.assertFalse(res["configuration_valid"])
self.assertTrue(any("conflicting definitions" in e for e in res["errors"]))
code = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath)])
self.assertEqual(code, 2)
def test_trusted_sets_invalid_provenance_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
tpath = tmp / "trusted.json"
tpath.write_text(json.dumps({"raw_trajectories": {"expected_count": 1, "provenance": " "}}))
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
self.assertFalse(res["configuration_valid"])
self.assertTrue(any("invalid provenance" in e for e in res["errors"]))
code = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath)])
self.assertEqual(code, 2)
def test_trusted_sets_unsupported_fields_rejected(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
tpath = tmp / "trusted.json"
tpath.write_text(json.dumps({"raw_trajectories": {"expected_count": 1, "illegal_field": True}}))
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
self.assertFalse(res["configuration_valid"])
self.assertTrue(any("unsupported field(s)" in e for e in res["errors"]))
code = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath)])
self.assertEqual(code, 2)
def test_valid_trusted_sets_with_complete_evidence_verified(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
content = b"evidence_payload"
chash = hashlib.sha256(content).hexdigest()
(tmp / "task1.json").write_bytes(content)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([{
"path": "task1.json",
"type": "trajectory",
"expected_sha256": chash,
"size_bytes": len(content),
}])))
tpath = tmp / "trusted.json"
tpath.write_text(json.dumps({"raw_trajectories": {"expected_paths": ["task1.json"]}}))
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
self.assertTrue(res["configuration_valid"])
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], auditor.VERIFIED)
code = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath)])
self.assertEqual(code, 0)
def test_valid_trusted_sets_with_incomplete_evidence_yields_code_1_not_2(self):
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
content = b"partial_data"
chash = hashlib.sha256(content).hexdigest()
(tmp / "t1.json").write_bytes(content)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([{
"path": "t1.json",
"type": "trajectory",
"expected_sha256": chash,
"size_bytes": len(content),
}])))
# Trusted expected sets requires 5 trajectories, but only 1 is present
tpath = tmp / "trusted.json"
tpath.write_text(json.dumps({"raw_trajectories": {"expected_count": 5}}))
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
self.assertTrue(res["configuration_valid"])
self.assertEqual(len(res["errors"]), 0)
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], auditor.INCOMPLETE)
# Valid configuration with incomplete evidence must return exit code 1, NOT exit code 2
code = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath)])
self.assertEqual(code, 1)
# ---------------------------------------------------------------------------
# P2: Duplicate Evidence and Normalized Path Protection
# ---------------------------------------------------------------------------
class TestP2DuplicateEvidenceProtection(unittest.TestCase):
"""Campaign completeness must never be established by duplicate evidence."""
def test_1_physical_file_declared_twice_with_exact_same_path_cannot_satisfy_count(self):
"""Case A: One physical file declared twice cannot satisfy an expected count of two."""
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
content = b'{"trajectory_id": "traj_01"}'
chash = hashlib.sha256(content).hexdigest()
(tmp / "t1.json").write_bytes(content)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([
{"path": "t1.json", "type": "trajectory", "expected_sha256": chash, "size_bytes": len(content)},
{"path": "t1.json", "type": "trajectory", "expected_sha256": chash, "size_bytes": len(content)},
])))
tpath = tmp / "trusted.json"
tpath.write_text(json.dumps({"raw_trajectories": {"expected_count": 2}}))
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
det = res["reproducibility_details"]["raw_trajectories"]
self.assertFalse(det["prerequisite_complete"])
self.assertEqual(det["expected_set_status"], "INCOMPLETE")
self.assertEqual(det["distinct_verified_count"], 1)
self.assertTrue(len(det["duplicate_artifacts"]) > 0)
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], auditor.INCOMPLETE)
# CLI execution assertion
code = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath)])
self.assertEqual(code, 1, "Duplicate evidence should return exit code 1 (incomplete evidence)")
def test_2_file_declared_as_plain_and_dot_slash_path_cannot_be_counted_separately(self):
"""Case B: 'artifact.bin' and './artifact.bin' cannot be counted separately."""
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
content = b"artifact_binary_payload"
chash = hashlib.sha256(content).hexdigest()
(tmp / "artifact.bin").write_bytes(content)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([
{"path": "artifact.bin", "type": "trajectory", "expected_sha256": chash, "size_bytes": len(content)},
{"path": "./artifact.bin", "type": "trajectory", "expected_sha256": chash, "size_bytes": len(content)},
])))
tpath = tmp / "trusted.json"
tpath.write_text(json.dumps({"raw_trajectories": {"expected_count": 2}}))
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
det = res["reproducibility_details"]["raw_trajectories"]
self.assertFalse(det["prerequisite_complete"])
self.assertEqual(det["expected_set_status"], "INCOMPLETE")
self.assertEqual(det["distinct_verified_count"], 1)
self.assertTrue(any("normalized path alias" in d for d in det["duplicate_artifacts"]))
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], auditor.INCOMPLETE)
code = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath)])
self.assertEqual(code, 1)
def test_3_duplicate_nested_relative_paths_with_redundant_dot_slash(self):
"""Duplicate nested relative paths containing redundant dot components are detected."""
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
sub = tmp / "nested"
sub.mkdir()
content = b"nested_trajectory_data"
chash = hashlib.sha256(content).hexdigest()
(sub / "traj.json").write_bytes(content)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([
{"path": "nested/traj.json", "type": "trajectory", "expected_sha256": chash, "size_bytes": len(content)},
{"path": "./nested/./traj.json", "type": "trajectory", "expected_sha256": chash, "size_bytes": len(content)},
])))
tpath = tmp / "trusted.json"
tpath.write_text(json.dumps({"raw_trajectories": {"expected_count": 2}}))
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
det = res["reproducibility_details"]["raw_trajectories"]
self.assertFalse(det["prerequisite_complete"])
self.assertEqual(det["distinct_verified_count"], 1)
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], auditor.INCOMPLETE)
def test_4_expected_count_of_two_with_only_one_distinct_verified_artifact(self):
"""Expected count of two with only one distinct artifact reports incomplete."""
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
content = b"only_one_file"
chash = hashlib.sha256(content).hexdigest()
(tmp / "single.json").write_bytes(content)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([
{"path": "single.json", "type": "trajectory", "expected_sha256": chash, "size_bytes": len(content)},
])))
tpath = tmp / "trusted.json"
tpath.write_text(json.dumps({"raw_trajectories": {"expected_count": 2}}))
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
det = res["reproducibility_details"]["raw_trajectories"]
self.assertFalse(det["prerequisite_complete"])
self.assertEqual(det["expected_set_status"], "INCOMPLETE")
self.assertEqual(det["distinct_verified_count"], 1)
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], auditor.INCOMPLETE)
code = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath)])
self.assertEqual(code, 1)
def test_5_expected_set_containing_normalized_duplicate_paths_rejected(self):
"""Expected-set definition containing normalized duplicates is rejected as configuration error."""
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([])))
tpath = tmp / "trusted.json"
tpath.write_text(json.dumps({
"raw_trajectories": {
"expected_paths": ["sub/traj.json", "./sub/./traj.json"],
}
}))
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
self.assertFalse(res["configuration_valid"])
self.assertTrue(any("duplicate path in expected_paths" in e for e in res["errors"]))
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], auditor.INVALID)
code = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath)])
self.assertEqual(code, 2, "Normalized duplicate in expected_paths must exit code 2")
def test_6_two_genuinely_distinct_checksum_verified_artifacts_satisfy_count(self):
"""Case C: Two genuinely distinct verified artifacts satisfy an expected count of two."""
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
c1 = b'{"task": "distinct_01"}'
c2 = b'{"task": "distinct_02"}'
h1 = hashlib.sha256(c1).hexdigest()
h2 = hashlib.sha256(c2).hexdigest()
(tmp / "t1.json").write_bytes(c1)
(tmp / "t2.json").write_bytes(c2)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([
{"path": "t1.json", "type": "trajectory", "expected_sha256": h1, "size_bytes": len(c1)},
{"path": "t2.json", "type": "trajectory", "expected_sha256": h2, "size_bytes": len(c2)},
])))
tpath = tmp / "trusted.json"
tpath.write_text(json.dumps({"raw_trajectories": {"expected_count": 2}}))
out = tmp / "out.json"
code = auditor.main([
str(mpath), str(tmp),
"--trusted-expected-sets", str(tpath),
"--output", str(out),
])
self.assertEqual(code, 0)
res = json.loads(out.read_text())
det = res["reproducibility_details"]["raw_trajectories"]
self.assertTrue(det["prerequisite_complete"])
self.assertEqual(det["expected_set_status"], "COMPLETE")
self.assertEqual(det["distinct_verified_count"], 2)
self.assertEqual(det["duplicate_artifacts"], [])
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], auditor.VERIFIED)
def test_7_explicit_expected_paths_where_one_required_artifact_is_absent(self):
"""Explicit expected paths where one required artifact is absent remains incomplete."""
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
c1 = b"present_payload"
h1 = hashlib.sha256(c1).hexdigest()
(tmp / "t1.json").write_bytes(c1)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([
{"path": "t1.json", "type": "trajectory", "expected_sha256": h1, "size_bytes": len(c1)},
])))
tpath = tmp / "trusted.json"
tpath.write_text(json.dumps({
"raw_trajectories": {
"expected_paths": ["t1.json", "t2.json"],
}
}))
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
det = res["reproducibility_details"]["raw_trajectories"]
self.assertFalse(det["prerequisite_complete"])
self.assertEqual(det["expected_set_status"], "INCOMPLETE")
self.assertIn("t2.json", det["missing_or_unverified"])
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], auditor.INCOMPLETE)
code = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath)])
self.assertEqual(code, 1)
def test_8_explicit_expected_paths_where_every_required_artifact_verifies(self):
"""Explicit expected paths where every required distinct artifact verifies produces complete."""
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
c1 = b"payload_01"
c2 = b"payload_02"
h1 = hashlib.sha256(c1).hexdigest()
h2 = hashlib.sha256(c2).hexdigest()
(tmp / "t1.json").write_bytes(c1)
(tmp / "t2.json").write_bytes(c2)
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([
{"path": "./t1.json", "type": "trajectory", "expected_sha256": h1, "size_bytes": len(c1)},
{"path": "t2.json", "type": "trajectory", "expected_sha256": h2, "size_bytes": len(c2)},
])))
tpath = tmp / "trusted.json"
tpath.write_text(json.dumps({
"raw_trajectories": {
"expected_paths": ["t1.json", "t2.json"],
}
}))
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
det = res["reproducibility_details"]["raw_trajectories"]
self.assertTrue(det["prerequisite_complete"])
self.assertEqual(det["expected_set_status"], "COMPLETE")
self.assertEqual(det["missing_or_unverified"], [])
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], auditor.VERIFIED)
code = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath)])
self.assertEqual(code, 0)
def test_9_manifest_entry_ordering_does_not_change_results(self):
"""Manifest entry ordering produces identical deterministic audit outcomes."""
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
c1 = b"first_file"
c2 = b"second_file"
h1 = hashlib.sha256(c1).hexdigest()
h2 = hashlib.sha256(c2).hexdigest()
(tmp / "a1.json").write_bytes(c1)
(tmp / "b2.json").write_bytes(c2)
e1 = {"path": "a1.json", "type": "trajectory", "expected_sha256": h1, "size_bytes": len(c1)}
e2 = {"path": "b2.json", "type": "trajectory", "expected_sha256": h2, "size_bytes": len(c2)}
mpath = tmp / "manifest.json"
tpath = tmp / "trusted.json"
tpath.write_text(json.dumps({"raw_trajectories": {"expected_count": 2}}))
out1 = tmp / "out1.json"
out2 = tmp / "out2.json"
mpath.write_text(json.dumps(_manifest([e1, e2])))
code1 = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath), "--output", str(out1), "--deterministic"])
mpath.write_text(json.dumps(_manifest([e2, e1])))
code2 = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath), "--output", str(out2), "--deterministic"])
self.assertEqual(code1, 0)
self.assertEqual(code2, 0)
self.assertEqual(out1.read_bytes(), out2.read_bytes())
def test_10_duplicate_evidence_never_produces_prerequisite_complete_or_verified(self):
"""Duplicate evidence never produces prerequisite_complete: true or VERIFIED status."""
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
content = b"sole_evidence_payload"
chash = hashlib.sha256(content).hexdigest()
(tmp / "sole.json").write_bytes(content)
# Even if expected_count is 1, a manifest with duplicate entries must not report prerequisite_complete
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([
{"path": "sole.json", "type": "trajectory", "expected_sha256": chash, "size_bytes": len(content)},
{"path": "sole.json", "type": "trajectory", "expected_sha256": chash, "size_bytes": len(content)},
])))
tpath = tmp / "trusted.json"
tpath.write_text(json.dumps({"raw_trajectories": {"expected_count": 1}}))
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
det = res["reproducibility_details"]["raw_trajectories"]
self.assertFalse(det["prerequisite_complete"], "Duplicate evidence must not produce prerequisite_complete: true")
self.assertNotEqual(res["reproducibility_prerequisites"]["raw_trajectories"], auditor.VERIFIED)
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], auditor.INCOMPLETE)
def test_11_hardlink_alias_detected_and_cannot_satisfy_expected_count(self):
"""Filesystem hardlink alias to the same inode cannot satisfy an expected count of two."""
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
content = b"hardlink_target_bytes"
chash = hashlib.sha256(content).hexdigest()
(tmp / "orig.json").write_bytes(content)
os.link(tmp / "orig.json", tmp / "hardlink_alias.json")
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([
{"path": "orig.json", "type": "trajectory", "expected_sha256": chash, "size_bytes": len(content)},
{"path": "hardlink_alias.json", "type": "trajectory", "expected_sha256": chash, "size_bytes": len(content)},
])))
tpath = tmp / "trusted.json"
tpath.write_text(json.dumps({"raw_trajectories": {"expected_count": 2}}))
res = auditor.audit(str(mpath), str(tmp), trusted_expected_sets=str(tpath))
det = res["reproducibility_details"]["raw_trajectories"]
self.assertFalse(det["prerequisite_complete"])
self.assertEqual(det["expected_set_status"], "INCOMPLETE")
self.assertEqual(det["distinct_verified_count"], 1)
self.assertTrue(any("hardlinks" in d for d in det["duplicate_artifacts"]))
self.assertEqual(res["reproducibility_prerequisites"]["raw_trajectories"], auditor.INCOMPLETE)
code = auditor.main([str(mpath), str(tmp), "--trusted-expected-sets", str(tpath)])
self.assertEqual(code, 1)
# ---------------------------------------------------------------------------
# P2: Malformed Filename Rejection (Embedded NUL and Unpaired Unicode Surrogates)
# ---------------------------------------------------------------------------
class TestMalformedFilenameRejection(unittest.TestCase):
"""Malformed filesystem filenames must be rejected cleanly without traceback."""
def test_1_filename_containing_nul_classified_invalid(self):
"""Case 1: Filename containing embedded NUL is classified as INVALID without crash."""
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
bad_path = "artifact\x00.txt"
mpath.write_text(json.dumps(_manifest([
{"path": bad_path, "type": "result_record"}
])))
res = auditor.audit(str(mpath), str(tmp))
self.assertEqual(res["totals"][auditor.INVALID], 1)
self.assertEqual(len(res["artifacts"]), 1)
art = res["artifacts"][0]
self.assertEqual(art["status"], auditor.INVALID)
self.assertFalse(art["present"])
self.assertEqual(art["path"], bad_path)
def test_2_filename_containing_unpaired_high_surrogate_classified_invalid(self):
"""Case 2: Filename containing unpaired high surrogate U+D800 is classified as INVALID."""
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
bad_path = f"artifact{chr(0xd800)}.txt"
mpath.write_text(json.dumps(_manifest([
{"path": bad_path, "type": "result_record"}
])))
res = auditor.audit(str(mpath), str(tmp))
self.assertEqual(res["totals"][auditor.INVALID], 1)
art = res["artifacts"][0]
self.assertEqual(art["status"], auditor.INVALID)
self.assertFalse(art["present"])
def test_3_filename_containing_unpaired_low_surrogate_classified_invalid(self):
"""Case 3: Filename containing unpaired low surrogate (U+DC00 / U+DFFF) is classified as INVALID."""
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
for surrogate_cp in (0xdc00, 0xdc80, 0xdfff):
mpath = tmp / f"manifest_{surrogate_cp}.json"
bad_name = f"artifact{chr(surrogate_cp)}.txt"
mpath.write_text(json.dumps(_manifest([
{"path": bad_name, "type": "result_record"}
])))
res = auditor.audit(str(mpath), str(tmp))
self.assertEqual(res["totals"][auditor.INVALID], 1)
self.assertEqual(res["artifacts"][0]["status"], auditor.INVALID)
def test_4_nul_in_nested_relative_path_component(self):
"""Case 4: NUL in nested directory or filename relative path component is classified as INVALID."""
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
bad_path = "nested/dir\x00component/artifact.json"
mpath.write_text(json.dumps(_manifest([
{"path": bad_path, "type": "result_record"}
])))
res = auditor.audit(str(mpath), str(tmp))
self.assertEqual(res["totals"][auditor.INVALID], 1)
self.assertEqual(res["artifacts"][0]["status"], auditor.INVALID)
def test_5_valid_unicode_filename_with_non_ascii_characters(self):
"""Case 5: Valid Unicode filename with non-ASCII characters is accepted and verified."""
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
valid_name = "café_測試_файл_🚀.json"
content = b'{"status": "ok", "experiment": "valid_unicode"}'
(tmp / valid_name).write_bytes(content)
chash = hashlib.sha256(content).hexdigest()
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([
{"path": valid_name, "type": "result_record", "expected_sha256": chash, "size_bytes": len(content)}
])))
res = auditor.audit(str(mpath), str(tmp))
self.assertEqual(res["totals"][auditor.VERIFIED], 1)
self.assertEqual(res["totals"][auditor.INVALID], 0)
art = res["artifacts"][0]
self.assertEqual(art["status"], auditor.VERIFIED)
self.assertTrue(art["present"])
self.assertTrue(art["hash_match"])
self.assertEqual(art["observed_sha256"], chash)
def test_6_mixed_manifest_containing_one_valid_and_one_malformed_artifact(self):
"""Case 6: Mixed manifest continues processing other entries when one is invalid."""
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
valid_name = "valid_evidence.txt"
content = b"clean_verified_evidence_data"
(tmp / valid_name).write_bytes(content)
chash = hashlib.sha256(content).hexdigest()
bad_nul = "malformed\x00_entry.dat"
bad_surrogate = f"malformed{chr(0xd800)}_entry.dat"
mpath = tmp / "manifest.json"
mpath.write_text(json.dumps(_manifest([
{"path": valid_name, "type": "trajectory", "expected_sha256": chash, "size_bytes": len(content)},
{"path": bad_nul, "type": "result_record"},
{"path": bad_surrogate, "type": "result_record"},
])))
res = auditor.audit(str(mpath), str(tmp))
self.assertEqual(res["totals"][auditor.VERIFIED], 1)
self.assertEqual(res["totals"][auditor.INVALID], 2)
by_path = {a["path"]: a["status"] for a in res["artifacts"]}
self.assertEqual(by_path[valid_name], auditor.VERIFIED)
self.assertEqual(by_path[bad_nul], auditor.INVALID)
self.assertEqual(by_path[bad_surrogate], auditor.INVALID)
def test_7_invalid_paths_never_reach_filesystem_calls(self):
"""Case 7: Invalid paths with NUL or surrogates never reach filesystem stat/open calls."""
from unittest.mock import patch
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
mpath = tmp / "manifest.json"
bad_paths = ["file\x00.txt", f"file{chr(0xd800)}.txt", "nested\x00/file.txt"]
mpath.write_text(json.dumps(_manifest([
{"path": p, "type": "result_record"} for p in bad_paths
])))
with patch("os.lstat", wraps=os.lstat) as mock_lstat, patch("os.open", wraps=os.open) as mock_open:
res = auditor.audit(str(mpath), str(tmp))
for bad_p in bad_paths:
for c in mock_lstat.call_args_list:
self.assertNotIn(bad_p, str(c))
for c in mock_open.call_args_list:
self.assertNotIn(bad_p, str(c))
self.assertEqual(res["totals"][auditor.INVALID], len(bad_paths))
# Direct reader invocation also avoids filesystem calls
with patch("os.lstat", wraps=os.lstat) as mock_lstat, patch("os.open", wraps=os.open) as mock_open:
for bad_p in bad_paths:
status, chash, size, note = auditor._open_and_hash_artifact(tmp, bad_p)
self.assertEqual(status, auditor.INVALID)
for c in mock_lstat.call_args_list:
self.assertNotIn(bad_p, str(c))
for c in mock_open.call_args_list:
self.assertNotIn(bad_p, str(c))
def test_8_direct_invocation_of_path_validator_and_artifact_reader(self):
"""Case 8: Path validator and reader return safe results when invoked directly."""
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
bad_nul = "file\x00.txt"
bad_high = f"file{chr(0xd800)}.txt"
bad_low1 = f"file{chr(0xdc00)}.txt"
bad_low_esc = f"file{chr(0xdc80)}.txt"
bad_low2 = f"file{chr(0xdfff)}.txt"
bad_nested_nul = "dir/sub\x00/file.txt"
bad_nested_surr = f"dir/sub{chr(0xd800)}/file.txt"
# Validator returns False
self.assertFalse(auditor._is_safe_relative_path(bad_nul))
self.assertFalse(auditor._is_safe_relative_path(bad_high))
self.assertFalse(auditor._is_safe_relative_path(bad_low1))
self.assertFalse(auditor._is_safe_relative_path(bad_low_esc))
self.assertFalse(auditor._is_safe_relative_path(bad_low2))
self.assertFalse(auditor._is_safe_relative_path(bad_nested_nul))
self.assertFalse(auditor._is_safe_relative_path(bad_nested_surr))
# Normalizer returns None
self.assertIsNone(auditor._normalize_relative_path(bad_nul))
self.assertIsNone(auditor._normalize_relative_path(bad_high))
self.assertIsNone(auditor._normalize_relative_path(bad_low1))
self.assertIsNone(auditor._normalize_relative_path(bad_low_esc))
# Valid Unicode paths accepted
self.assertTrue(auditor._is_safe_relative_path("café_測試.json"))
self.assertEqual(auditor._normalize_relative_path("./café_測試.json"), "café_測試.json")
# Direct reader returns INVALID
for bad in [bad_nul, bad_high, bad_low1, bad_nested_nul]:
status, chash, size, note = auditor._open_and_hash_artifact(tmp, bad)
self.assertEqual(status, auditor.INVALID)
self.assertIsNone(chash)
self.assertIsNone(size)
self.assertIsNotNone(note)
def test_9_actual_cli_execution_with_malformed_paths(self):
"""Case 9: CLI execution returns exit code 2 without traceback for malformed paths."""
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
for bad_name in ["file\x00.txt", f"file{chr(0xd800)}.txt", "nested\x00/file.txt"]:
mpath = tmp / "manifest.json"
out_path = tmp / "out.json"
sum_path = tmp / "summary.md"
mpath.write_text(json.dumps(_manifest([
{"path": bad_name, "type": "result_record"}
])))
code = auditor.main([
str(mpath), str(tmp),
"--output", str(out_path),
"--summary", str(sum_path),
])
self.assertEqual(code, 2, f"Expected exit code 2 for malformed path: {bad_name!r}")
self.assertTrue(out_path.exists())
self.assertTrue(sum_path.exists())
out_path.unlink()
sum_path.unlink()
def test_10_no_traceback_correct_classification_and_expected_exit_code(self):
"""Case 10: Subprocess CLI execution produces no traceback, controlled INVALID, and exit code 2."""
import subprocess
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
cases = [
("embedded_nul", "bad\x00filename.json"),
("unpaired_high_surrogate", f"bad{chr(0xd800)}filename.json"),
("unpaired_low_surrogate", f"bad{chr(0xdc00)}filename.json"),
]
for case_label, bad_name in cases:
mpath = tmp / f"manifest_{case_label}.json"
mpath.write_text(json.dumps(_manifest([
{"path": bad_name, "type": "result_record"}
])))
proc = subprocess.run(
[sys.executable, str(_ROOT / "scripts" / "audit_c5_benchmark_evidence.py"), str(mpath), str(tmp)],
capture_output=True,
text=True,
)
self.assertEqual(proc.returncode, 2, f"Case {case_label} must exit with code 2")
self.assertNotIn("Traceback", proc.stderr, f"Case {case_label} stderr must not contain traceback")
res = json.loads(proc.stdout)
self.assertEqual(res["totals"][auditor.INVALID], 1)
self.assertEqual(res["artifacts"][0]["status"], auditor.INVALID)
# ---------------------------------------------------------------------------
# Security: command-line diagnostics must not disclose untrusted input values
# ---------------------------------------------------------------------------
class TestCliDiagnosticConfidentiality(unittest.TestCase):
"""Keep detailed diagnostics in the structured API, not in terminal logs."""
def test_invalid_manifest_category_does_not_leak_into_stderr(self):
import subprocess
marker = "SENSITIVE_MARKER_CATEGORY_0183"
with tempfile.TemporaryDirectory() as td:
root = Path(td)
manifest = root / "manifest.json"
manifest.write_text(json.dumps(_manifest([], expected_sets={marker: {"expected_count": 1}})))
result = auditor.audit(str(manifest), str(root))
self.assertTrue(any(marker in err for err in result["errors"]))
proc = subprocess.run(
[sys.executable, str(_ROOT / "scripts" / "audit_c5_benchmark_evidence.py"), str(manifest), str(root)],
capture_output=True, text=True,
)
self.assertEqual(proc.returncode, 2)
self.assertIn("audit error: manifest is unreadable or invalid", proc.stderr)
self.assertNotIn(marker, proc.stderr)
self.assertNotIn("Traceback", proc.stderr)
def test_unreadable_trusted_config_path_does_not_leak_into_stderr(self):
import subprocess
marker = "SENSITIVE_MARKER_TRUSTED_PATH_0294"
with tempfile.TemporaryDirectory() as td:
root = Path(td)
manifest = root / "manifest.json"
manifest.write_text(json.dumps(_manifest([])))
trusted_path = root / (marker + ".json")
proc = subprocess.run(
[sys.executable, str(_ROOT / "scripts" / "audit_c5_benchmark_evidence.py"), str(manifest), str(root),
"--trusted-expected-sets", str(trusted_path)],
capture_output=True, text=True,
)
self.assertEqual(proc.returncode, 2)
self.assertIn("audit error: invalid trusted expected-sets configuration", proc.stderr)
self.assertNotIn(marker, proc.stderr)
self.assertNotIn("Traceback", proc.stderr)
def test_preflight_conflict_does_not_leak_path_or_modify_manifest(self):
import subprocess
marker = "SENSITIVE_MARKER_DESTINATION_0312"
with tempfile.TemporaryDirectory() as td:
root = Path(td)
manifest = root / (marker + ".json")
manifest.write_text(json.dumps(_manifest([])))
original = manifest.read_bytes()
proc = subprocess.run(
[sys.executable, str(_ROOT / "scripts" / "audit_c5_benchmark_evidence.py"), str(manifest), str(root),
"--output", str(manifest)],
capture_output=True, text=True,
)
self.assertEqual(proc.returncode, 2)
self.assertIn("preflight error: unsafe or conflicting output destination", proc.stderr)
self.assertNotIn(marker, proc.stderr)
self.assertNotIn("Traceback", proc.stderr)
self.assertEqual(manifest.read_bytes(), original)
def test_publication_error_does_not_leak_exception_text(self):
from contextlib import redirect_stderr
from io import StringIO
from unittest.mock import patch
marker = "SENSITIVE_MARKER_PUBLISH_0489"
with tempfile.TemporaryDirectory() as td:
root = Path(td)
manifest = root / "manifest.json"
manifest.write_text(json.dumps(_manifest([])))
for option, expected in (
("--output", "publication error: unable to write output"),
("--summary", "publication error: unable to write summary"),
):
stderr = StringIO()
with patch.object(auditor, "_publish_file_securely", side_effect=OSError(marker)):
with redirect_stderr(stderr):
code = auditor.main([str(manifest), str(root), option, str(root / "output.txt")])
self.assertEqual(code, 2)
self.assertIn(expected, stderr.getvalue())
self.assertNotIn(marker, stderr.getvalue())
self.assertNotIn("Traceback", stderr.getvalue())
# ---------------------------------------------------------------------------
# Markdown report integrity: untrusted values must remain within their cells.
# ---------------------------------------------------------------------------
class TestMarkdownReportIntegrity(unittest.TestCase):
def test_newline_and_pipe_in_missing_path_cannot_forge_verified_row(self):
with tempfile.TemporaryDirectory() as td:
root = Path(td)
bad_name = "not-found\n| apparent-success | result_record | **VERIFIED** | yes | 20 |"
manifest = root / "manifest.json"
manifest.write_text(json.dumps(_manifest([{
"path": bad_name, "type": "result_record"
}])))
result = auditor.audit(str(manifest), str(root), deterministic=True)
self.assertEqual(result["artifacts"][0]["status"], auditor.MISSING)
summary = auditor._markdown_summary(result)
artifact_section = summary.split("## Artifacts\n", 1)[1].split("## Reproducibility Prerequisites", 1)[0]
rows = [row for row in artifact_section.splitlines() if row.startswith("|")]
self.assertEqual(len(rows), 3)
self.assertNotIn("\n| apparent-success", summary)
self.assertIn(r"\| apparent-success", summary)
self.assertIn("**MISSING**", summary)
def test_code_delimiters_and_html_are_escaped(self):
value = "bad`</code><img src=x onerror=alert(1)>|name"
safe = auditor._markdown_code(value)
self.assertEqual(safe, '` bad `&#96;` </code><img src=x onerror=alert(1)>|name `')
self.assertEqual(auditor._markdown_code(value, table_cell=True),
'` bad `&#96;` </code><img src=x onerror=alert(1)>\\|name `')
def test_campaign_and_notes_cannot_insert_headings_or_columns(self):
result = {
"campaign_id": "benchmark\n## Forged status",
"root": "/tmp/a|b",
"manifest_valid": True,
"totals": {status: 0 for status in auditor.ALL_STATUSES} | {"total": 0},
"reproducibility_prerequisites": {"raw_trajectories": auditor.INCOMPLETE},
"reproducibility_details": {"raw_trajectories": {"notes": "missing\n| VERIFIED | yes |"}},
}
summary = auditor._markdown_summary(result)
self.assertNotIn("\n## Forged status", summary)
prerequisite_section = summary.split("## Reproducibility Prerequisites", 1)[1]
self.assertNotIn("\n| VERIFIED", prerequisite_section)
self.assertIn("benchmark\\n## Forged status", summary)
self.assertIn(r"missing\n\| VERIFIED", summary)
def test_cli_published_summary_does_not_forge_missing_artifact(self):
with tempfile.TemporaryDirectory() as td:
root = Path(td)
missing = "missing\n| forged | result_record | **VERIFIED** | yes | 99 |"
manifest = root / "manifest.json"
manifest.write_text(json.dumps(_manifest([{"path": missing, "type": "result_record"}])))
output = root / "audit.json"
summary = root / "audit.md"
code = auditor.main([str(manifest), str(root), "--output", str(output), "--summary", str(summary), "--deterministic"])
self.assertEqual(code, 1)
self.assertEqual(json.loads(output.read_text())["artifacts"][0]["status"], auditor.MISSING)
text = summary.read_text()
section = text.split("## Artifacts\n", 1)[1].split("## Reproducibility Prerequisites", 1)[0]
self.assertEqual(sum(line.startswith("|") for line in section.splitlines()), 3)
self.assertNotIn("\n| forged", text)
self.assertIn("**MISSING**", text)
def test_unicode_line_separators_do_not_create_new_rows(self):
for separator in (chr(0x85), chr(0x2028), chr(0x2029)):
safe = auditor._markdown_display_value("before" + separator + "after")
self.assertNotIn(separator, safe)
self.assertIn("after", safe)
def test_unicode_and_surrogates_remain_publishable(self):
text = auditor._markdown_code("café_測試_🚀" + chr(0xd800))
self.assertIn("café", text)
self.assertIn("測試", text)
self.assertIn("\\ud800", text)
text.encode("utf-8")
# ---------------------------------------------------------------------------
# Markdown inline safety: untrusted text uses native code spans.
# ---------------------------------------------------------------------------
class TestMarkdownInlineSafety(unittest.TestCase):
def test_code_field_escapes_link_image_emphasis_and_backticks(self):
malicious = (
"[**VERIFIED**](https://example.invalid/track) "
"![beacon](https://example.invalid/beacon.png) "
"`fake_code`"
)
safe = auditor._markdown_code(malicious)
self.assertEqual(safe, "` " + malicious.split("`")[0] + " `&#96;` fake_code `&#96;")
def test_report_renders_potential_links_as_literal_syntax(self):
with tempfile.TemporaryDirectory() as td:
root = Path(td)
malicious_path = "[VERIFIED](https://example.invalid/track)"
malicious_campaign = "![beacon](https://example.invalid/collect.png)"
manifest = root / "manifest.json"
manifest.write_text(json.dumps(_manifest(
[{"path": malicious_path, "type": "result_record"}],
campaign_id=malicious_campaign,
)))
result = auditor.audit(str(manifest), str(root), deterministic=True)
self.assertEqual(result["artifacts"][0]["status"], auditor.MISSING)
summary = auditor._markdown_summary(result)
self.assertIn("` " + malicious_path + " `", summary)
self.assertIn("` " + malicious_campaign + " `", summary)
self.assertIn("**MISSING**", summary)
def test_raw_url_email_and_strikethrough_are_not_active_markdown(self):
value = "https://example.invalid/track www.example.invalid mail@example.invalid ~~VERIFIED~~"
safe = auditor._markdown_code(value)
self.assertEqual(safe, "` " + value + " `")
def test_bidi_formatting_controls_cannot_reorder_display(self):
for codepoint in (0x061C, 0x200E, 0x200F, 0x202A, 0x202B, 0x202C,
0x202D, 0x202E, 0x2066, 0x2067, 0x2068, 0x2069):
value = "start" + chr(codepoint) + "finish"
escaped = auditor._markdown_display_value(value)
self.assertNotIn(chr(codepoint), escaped)
self.assertIn(f"\\u{codepoint:04x}", escaped)
self.assertIn("finish", escaped)
_MARKDOWN_CASES = (
("[VERIFIED](https://example.invalid)", "[VERIFIED](https://example.invalid)"),
("![image](https://example.invalid/i.png)", "![image](https://example.invalid/i.png)"),
("https://example.invalid/a", "https://example.invalid/a"),
("http://example.invalid/a", "http://example.invalid/a"),
("www.example.invalid", "www.example.invalid"),
("eval_user@example.invalid", "eval_user@example.invalid"),
("<mailto:user@example.invalid>", "<mailto:user@example.invalid>"),
("mailto:user@example.invalid", "mailto:user@example.invalid"),
("&#64; &#46; &#124; &#96;", "&#64; &#46; &#124; &#96;"),
("&#x40; &#x2e; &#x7c; &#x60;", "&#x40; &#x2e; &#x7c; &#x60;"),
("user&#64;example&#46;invalid", "user&#64;example&#46;invalid"),
("&lt;img&gt; &amp; &commat; &vert;", "&lt;img&gt; &amp; &commat; &vert;"),
("**VERIFIED** *em* _em_ __strong__", "**VERIFIED** *em* _em_ __strong__"),
("~~VERIFIED~~", "~~VERIFIED~~"),
("` `` ``` **VERIFIED**", "` `` ``` **VERIFIED**"),
("`", "`"),
("````", "````"),
(r"a|b\|c\\|d|", r"a|b\|c\\|d|"),
("a\n| forged |\r\n## Forged\rheading", r"a\n| forged |\r\n## Forged\rheading"),
("a\u0085b\u2028c\u2029d", r"a\u0085b\u2028c\u2029d"),
("a\u202eb\u2066c\u2069d", r"a\u202eb\u2066c\u2069d"),
("a\ud800\udcffz", r"a\ud800\udcffz"),
('</code><img src="x" onerror="alert(1)"><span>fake</span>',
'</code><img src="x" onerror="alert(1)"><span>fake</span>'),
("a\x00b\t\x1b\x7f", r"a\x00b\t\x1b\x7f"),
(" leading and trailing ", " leading and trailing "),
(" ", " "),
("", ""),
("\\[link](https://example.invalid)\\", "\\[link](https://example.invalid)\\"),
("café_測試_" + "long." * 250, "café_測試_" + "long." * 250),
)
def _markdown_fixture(payload: str) -> dict:
return {
"campaign_id": payload, "root": payload,
"audited_at": "1970-01-01T00:00:00Z", "manifest_valid": True,
"timestamp_kind": "deterministic_placeholder",
"totals": {s: 0 for s in auditor.ALL_STATUSES} | {"total": 1, auditor.MISSING: 1},
"errors": [payload],
"artifacts": [{"path": payload, "type": payload, "status": auditor.MISSING,
"present": False, "size_bytes": None}],
"reproducibility_prerequisites": {"raw_trajectories": auditor.INCOMPLETE},
"reproducibility_details": {"raw_trajectories": {
"artifact_integrity": auditor.MISSING, "expected_set_status": "INCOMPLETE",
"prerequisite_complete": False, "notes": payload,
}},
}
class TestMarkdownNativeSpans(unittest.TestCase):
def test_display_values_preserve_punctuation_and_expose_controls(self):
for value, display in _MARKDOWN_CASES:
with self.subTest(value=value):
self.assertEqual(auditor._markdown_display_value(value), display)
def test_code_and_text_use_the_same_quoting_in_each_context(self):
for value, _ in _MARKDOWN_CASES:
for table_cell in (False, True):
with self.subTest(value=value, table_cell=table_cell):
self.assertEqual(auditor._markdown_text(value, table_cell=table_cell),
auditor._markdown_code(value, table_cell=table_cell))
def test_backticks_are_literal_entities_between_short_spans(self):
for length in (1, 2, 3, 8, 64, 256, 10000):
value = "`" * length + " text " + "`" * length
self.assertEqual(auditor._markdown_code(value),
"&#96;" * length + "` text `" + "&#96;" * length)
def test_table_pipe_escape_preserves_existing_backslashes(self):
for length in range(16):
value = "a" + "\\" * length + "|b"
self.assertEqual(auditor._markdown_code(value), "` " + value + " `")
self.assertEqual(auditor._markdown_code(value, table_cell=True),
"` a" + "\\" * (length + 1) + "|b `")
def test_empty_and_all_space_values_do_not_gain_padding(self):
self.assertEqual(auditor._markdown_code(""), "")
self.assertEqual(auditor._markdown_code(" "), "` `")
self.assertEqual(auditor._markdown_code(" x "), "` x `")
def test_reports_quote_each_untrusted_field_without_mutating_json(self):
for value, _ in _MARKDOWN_CASES:
result = _markdown_fixture(value)
before = json.dumps(result, sort_keys=True)
summary = auditor._markdown_summary(result)
self.assertIn("- **Campaign**: " + auditor._markdown_code(value), summary)
self.assertIn("- **Root**: " + auditor._markdown_code(value), summary)
self.assertIn("- " + auditor._markdown_text(value), summary)
self.assertIn("| " + auditor._markdown_code(value, table_cell=True) + " | "
+ auditor._markdown_text(value, table_cell=True) + " | **MISSING** | no | - |", summary)
self.assertEqual(json.dumps(result, sort_keys=True), before)
def test_cli_json_and_markdown_are_deterministic(self):
with tempfile.TemporaryDirectory() as td:
root = Path(td)
manifest = root / "manifest.json"
manifest.write_text(json.dumps(_manifest([
{"path": "missing|user@example.invalid", "type": "~~VERIFIED~~"},
], campaign_id="user@example.invalid")))
outputs = []
for index in range(2):
output, summary = root / f"{index}.json", root / f"{index}.md"
self.assertEqual(auditor.main([str(manifest), str(root), "--output", str(output),
"--summary", str(summary), "--deterministic"]), 1)
outputs.append((output.read_bytes(), summary.read_bytes()))
self.assertEqual(outputs[0], outputs[1])
def _run_gfm_checks() -> None:
# Kept explicit because cmarkgfm is a verification tool, not an app dependency.
# Import failure must fail this command, rather than silently skip security tests.
from cmarkgfm import github_flavored_markdown_to_html
from cmarkgfm.cmark import Options
from xml.etree import ElementTree as ET
def render(markdown):
# Allow raw HTML so a broken escape cannot be hidden by sanitization.
html = github_flavored_markdown_to_html(markdown, options=Options.CMARK_OPT_UNSAFE)
return ET.fromstring("<report>" + html + "</report>")
class TestMarkdownGFM(unittest.TestCase):
def test_renderer_positive_controls(self):
dom = render("https://example.invalid user@example.invalid ~~deleted~~ **bold** *em*\n\n"
'![image](https://example.invalid/i) <span title="raw">HTML</span>\n\n'
"| A | B |\n|---|---|\n| x | y |")
for tag in ("a", "del", "strong", "em", "img", "span", "table"):
self.assertIsNotNone(dom.find(".//" + tag), tag)
self.assertTrue(any(a.get("href", "").startswith("mailto:") for a in dom.iter("a")))
# Reproduce the original decoded-entity autolink, not just bare URLs.
original = render("<code>eval&#95;user&#64;example&#46;invalid</code>")
self.assertEqual(original.find(".//code/a").get("href"), "mailto:eval_user@example.invalid")
def test_helpers_render_as_literal_text(self):
for value, display in _MARKDOWN_CASES:
for helper in (auditor._markdown_code, auditor._markdown_text):
for table_cell in (False, True):
with self.subTest(value=value, helper=helper.__name__, table_cell=table_cell):
quoted = helper(value, table_cell=table_cell)
markdown = "| Value |\n|---|\n| " + quoted + " |" if table_cell else quoted
dom = render(markdown)
parent = dom.find(".//td") if table_cell else dom.find("p")
self.assertEqual("".join(parent.itertext()) if parent is not None else "", display)
self.assertTrue(all(len(code) == 0 for code in dom.iter("code")))
expected_tags = (["report", "table", "thead", "tr", "th", "tbody", "tr", "td"]
if table_cell else (["report", "p"] if display else ["report"]))
self.assertEqual([node.tag for node in dom.iter() if node.tag != "code"], expected_tags)
def test_backtick_lengths_and_backslashes_before_table_pipes(self):
for length in list(range(65)) + [80, 81, 128, 256, 1000, 10000]:
value = "`" * length + "a" + "\\" * length + "| **fake** |" + "`" * length
for table_cell in (False, True):
quoted = auditor._markdown_code(value, table_cell=table_cell)
markdown = "| A | B |\n|---|---|\n| " + quoted + " | end |" if table_cell else quoted
dom = render(markdown)
parent = dom.find(".//td") if table_cell else dom.find("p")
self.assertEqual("".join(parent.itertext()), value)
self.assertTrue(all(len(code) == 0 for code in dom.iter("code")))
for tag in ("strong", "em", "a", "del"):
self.assertIsNone(dom.find(".//" + tag), tag)
if table_cell:
self.assertEqual(len(dom.findall(".//tbody/tr")), 1)
self.assertEqual(len(dom.findall(".//td")), 2)
self.assertEqual(dom.findall(".//td")[1].text, "end")
def test_every_short_backtick_length_and_very_long_runs(self):
for value in (
" ".join("`" * n for n in range(1, 130)) + " https://example.invalid **fake**",
"`" * 100000 + " user@example.invalid ~~fake~~ " + "`" * 100000,
):
for table_cell in (False, True):
quoted = auditor._markdown_code(value, table_cell=table_cell)
markdown = "| A |\n|---|\n| " + quoted + " |" if table_cell else quoted
dom = render(markdown)
parent = dom.find(".//td") if table_cell else dom.find("p")
self.assertEqual("".join(parent.itertext()), value)
self.assertTrue(all(n.tag in {"report", "p", "code", "table", "thead",
"tbody", "tr", "th", "td"} for n in dom.iter()))
def assert_report(self, result):
summary = auditor._markdown_summary(result)
dom = render(summary)
# Compare the entire element structure with the same report using safe text.
baseline = render(auditor._markdown_summary(_markdown_fixture("safe")))
self.assertEqual([n.tag for n in dom.iter() if n.tag != "code"],
[n.tag for n in baseline.iter() if n.tag != "code"])
self.assertTrue(all(len(code) == 0 for code in dom.iter("code")))
tables = dom.findall(".//table")
self.assertEqual([len(t.findall(".//tbody/tr")) for t in tables], [7, 1, 1])
self.assertEqual([[len(row) for row in t.findall(".//tr")] for t in tables],
[[2] * 8, [5] * 2, [6] * 2])
self.assertEqual([n.text for n in dom.iter("strong")],
["Campaign", "Audited at", "Timestamp note", "Root", "Manifest valid",
auditor.MISSING, auditor.INCOMPLETE])
return dom
def test_complete_reports_keep_classification_and_structure(self):
for value, display in _MARKDOWN_CASES:
if not value:
continue # Empty cells are checked by the helper test.
with self.subTest(value=value):
dom = self.assert_report(_markdown_fixture(value))
items = dom.findall(".//li")
self.assertEqual("".join(items[0].itertext()), "Campaign: " + display)
self.assertEqual("".join(items[3].itertext()), "Root: " + display)
self.assertEqual("".join(items[5].itertext()), display)
tables = dom.findall(".//table")
cells = tables[1].findall(".//td")
self.assertEqual(["".join(c.itertext()) for c in cells],
[display, display, auditor.MISSING, "no", "-"])
self.assertEqual("".join(tables[2].findall(".//td")[-1].itertext()), display)
def test_actual_cli_reports_match_authoritative_json(self):
with tempfile.TemporaryDirectory() as td:
root = Path(td) / "`root`|admin@example.invalid"
root.mkdir()
manifest = root / "manifest.json"
path = "missing`|user@example.invalid\n## Forged"
manifest.write_text(json.dumps(_manifest([
{"path": path, "type": "https://example.invalid ~~VERIFIED~~"},
], campaign_id="admin@example.invalid")))
output, summary = root / "audit.json", root / "audit.md"
self.assertEqual(auditor.main([str(manifest), str(root), "--output", str(output),
"--summary", str(summary), "--deterministic"]), 1)
result = json.loads(output.read_text())
self.assertEqual(result["artifacts"][0]["status"], auditor.MISSING)
dom = render(summary.read_text())
for tag in ("a", "img", "del", "em", "span", "script"):
self.assertIsNone(dom.find(".//" + tag), tag)
rows = dom.findall(".//table")[1].findall(".//tbody/tr")
self.assertEqual(len(rows), 1)
self.assertEqual(["".join(cell.itertext()) for cell in rows[0]],
[r"missing`|user@example.invalid\n## Forged",
result["artifacts"][0]["type"], auditor.MISSING, "no", "-"])
self.assertEqual(len(dom.findall(".//h1")), 1)
self.assertEqual(len(dom.findall(".//h2")), 3)
items = ["".join(n.itertext()) for n in dom.iter("li")]
self.assertIn("Root: " + str(root), items)
self.assertIn("Campaign: " + result["campaign_id"], items)
def test_real_duplicate_diagnostics_and_validation_errors(self):
with tempfile.TemporaryDirectory() as td:
root = Path(td)
path = "user@example.invalid|~~VERIFIED~~"
entry = {"path": path, "type": "trajectory"}
result = _run_audit(root, _manifest([entry, entry]), deterministic=True)
notes = result["reproducibility_details"]["raw_trajectories"]["notes"]
self.assertIn("duplicate", notes)
self.assertIn(path, notes)
dom = render(auditor._markdown_summary(result))
self.assertIn(notes, [n.text for n in dom.iter("code")])
bad = _manifest([], expected_sets={"https://example.invalid ~~VERIFIED~~": {}})
result = _run_audit(root, bad, deterministic=True)
self.assertTrue(result["errors"])
dom = render(auditor._markdown_summary(result))
self.assertIn(result["errors"][0], [n.text for n in dom.iter("code")])
for tag in ("a", "img", "del", "em"):
self.assertIsNone(dom.find(".//" + tag), tag)
suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestMarkdownGFM)
result = unittest.TextTestRunner(verbosity=2).run(suite)
raise SystemExit(not result.wasSuccessful())
if __name__ == "__main__":
if sys.argv[1:] == ["--gfm"]:
_run_gfm_checks()
else:
unittest.main()