test(infra): bind historical evidence to its original snapshot
Build and Test Quality Gate / Contract Web typecheck and build (push) Successful in 6m0s
Build and Test Quality Gate / Isolated Alibaba and Tencent KMS gateway (push) Failing after 1m7s
Security Quality Gate / npm audit, Bandit, pip-audit, detect-secrets (push) Failing after 11m20s
Build and Test Quality Gate / Python tests and Contract API migration (push) Failing after 41m48s

Keep historical RC03 hashes independent of later source changes while verifying every current manifest item against its committed blob.
This commit is contained in:
2026-10-08 23:08:08 +08:00
parent 3f2271095d
commit ca24748dfc
@@ -42,9 +42,9 @@ def _git(repo: Path, *args: str) -> str:
return completed.stdout.strip()
def _git_blob(repo: Path, path: str) -> bytes:
def _git_blob(repo: Path, path: str, revision: str = "HEAD") -> bytes:
completed = subprocess.run(
["git", "-C", str(repo), "cat-file", "blob", f"HEAD:{path}"],
["git", "-C", str(repo), "cat-file", "blob", f"{revision}:{path}"],
check=True,
capture_output=True,
)
@@ -411,53 +411,6 @@ def test_manifest_is_deterministic_and_summarizes_complete_committed_graph(tmp_p
"**/*.sqlite3",
} <= dockerignore_rules
current_index = json.loads(
(
REPO_ROOT
/ "docs/qa/multiscene-closeout-20260910/rc03-current-candidate-evidence-index-v3.json"
).read_text(encoding="utf-8")
)
assert current_index["validation"]["self_contained"] is True
assert current_index["validation"]["predecessor_required_for_interpretation"] is False
assert current_index["validation"]["listed_file_count"] == 54
assert current_index["validation"]["accepted_current_evidence_count"] == 50
assert current_index["validation"]["excluded_invalid_lineage_count"] == 4
assert all(item["normative_for_v3"] is False for item in current_index["lineage"])
indexed_paths = [item["path"] for item in current_index["files"]]
assert len(indexed_paths) == len(set(indexed_paths)) == 54
for item in current_index["files"]:
evidence = REPO_ROOT / item["path"]
category, _, _ = ownership.classify_path(item["path"], size=item["size_bytes"])
if category == "generated_evidence_retain_exclude":
# Raw and invalid-lineage QA outputs are intentionally retained outside
# the immutable source candidate. When they remain in a development
# workspace, still verify that the compact index recorded their bytes
# correctly; a clean release checkout must not require them to exist.
if not evidence.exists():
continue
evidence_bytes = evidence.read_bytes()
else:
assert category in {"release_source_include", "release_test_include"}
assert evidence.is_file()
# Verify the immutable Git bytes instead of checkout bytes: Windows may
# materialize text files with CRLF. The RC-03 index was created from
# worktree bytes, so accept only an exact LF/CRLF rendering of the same
# immutable blob; the candidate manifest/archive bind the raw blob.
evidence_bytes = _git_blob(REPO_ROOT, item["path"])
variants = _text_eol_variants(evidence_bytes)
assert any(
len(candidate) == item["size_bytes"]
and hashlib.sha256(candidate).hexdigest() == item["sha256"]
for candidate in variants
)
if item["path"].endswith(".json"):
json.loads(evidence_bytes)
continue
assert len(evidence_bytes) == item["size_bytes"]
assert hashlib.sha256(evidence_bytes).hexdigest() == item["sha256"]
if item["path"].endswith(".json"):
json.loads(evidence_bytes)
repo, commit = _candidate_repo(tmp_path)
output = tmp_path / "manifest.json"
@@ -474,6 +427,10 @@ def test_manifest_is_deterministic_and_summarizes_complete_committed_graph(tmp_p
assert first["summaries"]["migrations"][0]["heads"] == ["contract-head"]
assert first["summaries"]["migrations"][1]["heads"] == ["ai-head"]
recorded_paths = {item["path"] for item in first["files"]["items"]}
for item in first["files"]["items"]:
content = _git_blob(repo, item["path"], commit)
assert item["size"] == len(content)
assert item["sha256"] == hashlib.sha256(content).hexdigest()
assert set(manifest.RELEASE_CONTROL_PATHS) <= recorded_paths
configuration_paths = {item["path"] for item in first["summaries"]["configuration"]}
assert set(manifest.RELEASE_CONTROL_PATHS) <= configuration_paths
@@ -490,6 +447,49 @@ def test_manifest_is_deterministic_and_summarizes_complete_committed_graph(tmp_p
assert "No image was built or assigned a digest" in first["claims_not_made"][0]
def test_historical_rc03_index_matches_original_committed_snapshot() -> None:
if _git(REPO_ROOT, "rev-parse", "--is-shallow-repository") == "true":
pytest.skip("historical RC03 byte verification requires complete Git history")
index_path = "docs/qa/multiscene-closeout-20260910/rc03-current-candidate-evidence-index-v3.json"
index_commit = _git(REPO_ROOT, "log", "-1", "--diff-filter=A", "--format=%H", "--", index_path)
assert index_commit
historical_index = json.loads((REPO_ROOT / index_path).read_text(encoding="utf-8"))
assert historical_index == json.loads(_git_blob(REPO_ROOT, index_path, index_commit))
assert historical_index["release_claim"] is False
assert historical_index["validation"]["self_contained"] is True
assert historical_index["validation"]["predecessor_required_for_interpretation"] is False
assert historical_index["validation"]["listed_file_count"] == 54
assert historical_index["validation"]["accepted_current_evidence_count"] == 50
assert historical_index["validation"]["excluded_invalid_lineage_count"] == 4
assert all(item["normative_for_v3"] is False for item in historical_index["lineage"])
indexed_paths = [item["path"] for item in historical_index["files"]]
assert len(indexed_paths) == len(set(indexed_paths)) == 54
for item in historical_index["files"]:
evidence = REPO_ROOT / item["path"]
category, _, _ = ownership.classify_path(item["path"], size=item["size_bytes"])
if category == "generated_evidence_retain_exclude":
if not evidence.exists():
continue
evidence_bytes = evidence.read_bytes()
else:
assert category in {"release_source_include", "release_test_include"}
evidence_bytes = _git_blob(REPO_ROOT, item["path"], index_commit)
# The historical index recorded worktree bytes; bind its own source snapshot, not today's HEAD.
variants = _text_eol_variants(evidence_bytes)
assert any(
len(candidate) == item["size_bytes"]
and hashlib.sha256(candidate).hexdigest() == item["sha256"]
for candidate in variants
)
if item["path"].endswith(".json"):
json.loads(evidence_bytes)
continue
assert len(evidence_bytes) == item["size_bytes"]
assert hashlib.sha256(evidence_bytes).hexdigest() == item["sha256"]
if item["path"].endswith(".json"):
json.loads(evidence_bytes)
def test_manifest_refuses_ambiguous_dirty_missing_and_secret_candidates(tmp_path: Path) -> None:
repo, commit = _candidate_repo(tmp_path)
external_output = tmp_path / "manifest.json"