personal memory agent
1# SPDX-License-Identifier: AGPL-3.0-only
2# Copyright (c) 2026 sol pbc
3
4from __future__ import annotations
5
6import fcntl
7import hashlib
8import json
9import os
10import re
11import subprocess
12import sys
13import tomllib
14from dataclasses import replace
15from pathlib import Path
16from typing import Any
17
18import pytest
19
20import scripts.check_rust_release_manifest as checker
21import scripts.release_tool_pins as pins
22
23SCRIPT = (
24 Path(__file__).resolve().parents[1] / "scripts" / "check_rust_release_manifest.py"
25)
26VALID_COMMIT = checker.fixture_source_commit()
27PYTHON_WHITESPACE_CODE_POINTS: tuple[int, ...] = (
28 0x09,
29 0x0A,
30 0x0B,
31 0x0C,
32 0x0D,
33 0x1C,
34 0x1D,
35 0x1E,
36 0x1F,
37 0x20,
38 0x85,
39 0xA0,
40 0x1680,
41 0x2000,
42 0x2001,
43 0x2002,
44 0x2003,
45 0x2004,
46 0x2005,
47 0x2006,
48 0x2007,
49 0x2008,
50 0x2009,
51 0x200A,
52 0x2028,
53 0x2029,
54 0x202F,
55 0x205F,
56 0x3000,
57)
58RUSTC_REJECTED_SEPARATOR_CODE_POINTS: tuple[int, ...] = tuple(
59 code_point for code_point in PYTHON_WHITESPACE_CODE_POINTS if code_point != 0x20
60)
61
62
63def _errors(failures: list[checker.Failure]) -> set[str]:
64 return {failure.error for failure in failures}
65
66
67def _assert_error(failures: list[checker.Failure], error: str) -> None:
68 assert error in _errors(failures)
69
70
71def _assert_redacted(
72 failures: list[checker.Failure], forbidden: tuple[str, ...]
73) -> None:
74 for failure in failures:
75 fields = (failure.error, failure.expected, failure.actual, failure.repair)
76 for needle in forbidden:
77 assert all(needle not in field for field in fields)
78
79
80def _assert_formatted_redacted(
81 failures: list[checker.Failure],
82 forbidden: tuple[str, ...],
83 capsys: pytest.CaptureFixture[str],
84) -> None:
85 checker._format_failures(failures)
86 stderr = capsys.readouterr().err
87 for needle in forbidden:
88 assert needle not in stderr
89
90
91def _repo_root() -> Path:
92 return Path(__file__).resolve().parents[1]
93
94
95def _rustc_lines(host: str = "x86_64-unknown-linux-gnu") -> list[str]:
96 return checker.fixture_rustc_verbose(host).split("\n")
97
98
99def _rustc_line_mutant(canonical: str, line_index: int, replacement: str) -> str:
100 lines = canonical.split("\n")
101 lines[line_index] = replacement
102 return "\n".join(lines)
103
104
105def _candidate(
106 tmp_path: Path,
107 *,
108 include_models: bool = False,
109 source_commit: str = VALID_COMMIT,
110) -> Path:
111 release_dir = tmp_path / ("candidate-models" if include_models else "candidate")
112 failures = checker.write_inert_candidate(
113 release_dir,
114 include_models=include_models,
115 source_commit=source_commit,
116 )
117 assert failures == []
118 return release_dir
119
120
121def test_release_manifest_imports_tool_pins_from_authoritative_module() -> None:
122 assert checker.RUSTC_VERSION_BANNER == pins.RUSTC_VERSION_BANNER
123 assert checker.RUSTC_BINARY_PIN == pins.RUSTC_BINARY_PIN
124 assert checker.RUSTC_COMMIT_HASH_PIN == pins.RUSTC_COMMIT_HASH_PIN
125 assert checker.RUSTC_COMMIT_DATE_PIN == pins.RUSTC_COMMIT_DATE_PIN
126 assert checker.RUSTC_RELEASE_PIN == pins.RUSTC_RELEASE_PIN
127 assert checker.RUSTC_LLVM_PIN == pins.RUSTC_LLVM_PIN
128 assert checker.CARGO_VERSION_PIN == pins.CARGO_VERSION_PIN
129 assert checker.CARGO_RELEASE_PIN == pins.CARGO_RELEASE_PIN
130 assert checker.CARGO_DENY_PIN == pins.CARGO_DENY_PIN
131
132 source = Path(checker.__file__).read_text(encoding="utf-8")
133 assert "RUSTC_VERSION_BANNER =" not in source
134 assert "CARGO_DENY_PIN =" not in source
135
136
137def test_macos_swift_pin_requires_exact_canonical_grounded_output() -> None:
138 exact = "Apple Swift version 6.3.3 (swiftlang-6.3.3.1.3 clang-2100.1.1.101)"
139
140 assert pins.MACOS_SWIFT_PIN == exact
141 assert checker.validate_public_evidence_text("swift", pins.MACOS_SWIFT_PIN) == []
142 assert (
143 checker.validate_public_evidence_text("swift", pins.MACOS_SWIFT_RAW_BANNER)
144 == []
145 )
146 assert (
147 checker.validate_public_evidence_text(
148 "swift", pins.MACOS_SWIFT_FLATTENED_BANNER
149 )
150 == []
151 )
152 assert not any(
153 line.startswith("MACOS_SWIFT_VERSION")
154 for line in Path(pins.__file__).read_text(encoding="utf-8").splitlines()
155 )
156
157 skewed_observations = (
158 "6.3.3",
159 "swift 6.3.3",
160 "Apple Swift 6.3.3",
161 "Apple Swift 6.3.3 (swiftlang-6.3.3.1.3 clang-2100.1.1.102)",
162 "Apple Swift 6.3.3 (swiftlang-6.3.3.1.4 clang-2100.1.1.101)",
163 "Apple Swift version 6.3.4 (swiftlang-6.3.3.1.3 clang-2100.1.1.101)",
164 "Apple Swift version 6.3.3 (swiftlang-6.3.3.1.4 clang-2100.1.1.101)",
165 "Apple Swift version 6.3.3 (swiftlang-6.3.3.1.3 clang-2100.1.1.102)",
166 f" {exact}",
167 f"{exact} ",
168 )
169 assert all(observed != pins.MACOS_SWIFT_PIN for observed in skewed_observations)
170
171
172def test_build_system_pins_match_release_tool_pins() -> None:
173 root = _repo_root()
174 setuptools_projects = (
175 root / "pyproject.toml",
176 root / "packages" / "solstone-journal" / "pyproject.toml",
177 root / "packages" / "solstone-journal-cuda" / "pyproject.toml",
178 root / "packages" / "solstone-journal-models" / "pyproject.toml",
179 )
180 for path in setuptools_projects:
181 data = tomllib.loads(path.read_text(encoding="utf-8"))
182 assert data["build-system"]["requires"] == list(pins.SETUPTOOLS_BUILD_REQUIRES)
183
184 core_data = tomllib.loads(
185 (root / "packages" / "solstone-core" / "pyproject.toml").read_text(
186 encoding="utf-8"
187 )
188 )
189 assert core_data["build-system"]["requires"] == [pins.MATURIN_REQUIREMENT]
190
191
192def test_all_macos_maturin_invocations_are_locked() -> None:
193 makefile = (_repo_root() / "Makefile").read_text(encoding="utf-8")
194 assignments = re.findall(
195 r'MATURIN_PEP517_ARGS="([^"]*aarch64-apple-darwin[^"]*)"', makefile
196 )
197
198 assert assignments
199 assert all("--locked" in args.split() for args in assignments)
200
201
202def _manifest_for_lane(release_dir: Path, lane: checker.LaneName) -> Path:
203 for artifact_name, (
204 artifact_lane,
205 _target,
206 ) in checker.rust_artifact_targets().items():
207 if artifact_lane == lane:
208 return release_dir / f"{artifact_name}.rust-release-manifest.json"
209 raise AssertionError(f"no artifact for lane {lane}")
210
211
212def _artifact_for_lane(release_dir: Path, lane: checker.LaneName) -> Path:
213 manifest = _manifest_for_lane(release_dir, lane)
214 return release_dir / manifest.name.removesuffix(".rust-release-manifest.json")
215
216
217def _source_artifact(tmp_path: Path) -> Path:
218 release_dir = tmp_path / "source-artifact"
219 checker.write_inert_packages(release_dir, include_models=False)
220 return _artifact_for_lane(release_dir, "source")
221
222
223def _assert_malformed_redacted(
224 failures: list[checker.Failure],
225 forbidden: tuple[str, ...],
226 capsys: pytest.CaptureFixture[str],
227) -> None:
228 assert failures
229 _assert_error(failures, "rustc_verbose is malformed")
230 for failure in failures:
231 assert failure.actual == "redacted"
232 _assert_redacted(failures, forbidden)
233 _assert_formatted_redacted(failures, forbidden, capsys)
234
235
236def _assert_rustc_mutant_rejected(
237 artifact_path: Path,
238 capsys: pytest.CaptureFixture[str],
239 *,
240 mutant: str,
241 forbidden: tuple[str, ...],
242) -> None:
243 parsed, parse_failures = checker.parse_rustc_verbose(mutant)
244 assert parsed is None
245 _assert_malformed_redacted(parse_failures, forbidden, capsys)
246
247 evidence = checker.fixture_evidence_by_lane()["source"]
248 generated, generate_failures = checker.generate_manifest(
249 artifact_path,
250 lane="source",
251 evidence=replace(evidence, rustc_verbose=mutant),
252 cohort=checker._default_cohort(VALID_COMMIT),
253 )
254 assert generated is None
255 _assert_malformed_redacted(generate_failures, forbidden, capsys)
256
257
258def _assert_rustc_line_mutant_rejected(
259 artifact_path: Path,
260 capsys: pytest.CaptureFixture[str],
261 *,
262 canonical: str,
263 mutant: str,
264 line_index: int,
265) -> None:
266 canonical_lines = canonical.split("\n")
267 mutant_lines = mutant.split("\n")
268 assert len(mutant_lines) == len(canonical_lines)
269 assert mutant_lines[line_index] != canonical_lines[line_index]
270 for index, line in enumerate(canonical_lines):
271 if index != line_index:
272 assert mutant_lines[index] == line
273 _assert_rustc_mutant_rejected(
274 artifact_path,
275 capsys,
276 mutant=mutant,
277 forbidden=(mutant, mutant_lines[line_index]),
278 )
279
280
281def _assert_rustc_lf_separator_mutant_rejected(
282 artifact_path: Path,
283 capsys: pytest.CaptureFixture[str],
284 *,
285 canonical: str,
286 mutant: str,
287 line_index: int,
288) -> None:
289 canonical_lines = canonical.split("\n")
290 label, value = canonical_lines[line_index].split(": ", 1)
291 mutant_lines = mutant.split("\n")
292 assert len(mutant_lines) == len(canonical_lines) + 1
293 assert mutant_lines[:line_index] == canonical_lines[:line_index]
294 assert mutant_lines[line_index : line_index + 2] == [f"{label}:", value]
295 assert mutant_lines[line_index + 2 :] == canonical_lines[line_index + 1 :]
296 _assert_rustc_mutant_rejected(
297 artifact_path,
298 capsys,
299 mutant=mutant,
300 forbidden=(mutant, f"{label}:\n{value}"),
301 )
302
303
304def _load_manifest(path: Path) -> dict:
305 return json.loads(path.read_text(encoding="utf-8"))
306
307
308def _write_manifest(path: Path, payload: dict) -> None:
309 path.write_bytes(checker.canonical_json_bytes(payload))
310
311
312def _replace_manifest_artifact(manifest_path: Path, artifact_name: str) -> None:
313 artifact = manifest_path.parent / artifact_name
314 digest = hashlib.sha256(artifact.read_bytes()).hexdigest()
315 payload = _load_manifest(manifest_path)
316 payload["artifacts"] = [
317 {
318 "path": artifact_name,
319 "sha256": digest,
320 "bytes": artifact.stat().st_size,
321 }
322 ]
323 _write_manifest(manifest_path, payload)
324
325
326def _source_dist(tmp_path: Path, *, include_models: bool = False) -> Path:
327 dist = tmp_path / "dist"
328 checker.write_inert_packages(dist, include_models=include_models)
329 return dist
330
331
332def _build_ready(
333 tmp_path: Path,
334 *,
335 include_models: bool = False,
336 hook=None,
337) -> tuple[Path, list[checker.Failure]]:
338 ready = tmp_path / "ready"
339 failures = checker.build_and_promote_candidate(
340 _source_dist(tmp_path, include_models=include_models),
341 ready,
342 source_commit=VALID_COMMIT,
343 evidence_by_lane=checker.fixture_evidence_by_lane(),
344 include_models=include_models,
345 _post_promote_hook=hook,
346 )
347 return ready, failures
348
349
350def test_python_whitespace_code_point_table_is_explicit() -> None:
351 assert len(PYTHON_WHITESPACE_CODE_POINTS) == 29
352 assert set(PYTHON_WHITESPACE_CODE_POINTS) == {
353 0x09,
354 0x0A,
355 0x0B,
356 0x0C,
357 0x0D,
358 0x1C,
359 0x1D,
360 0x1E,
361 0x1F,
362 0x20,
363 0x85,
364 0xA0,
365 0x1680,
366 0x2000,
367 0x2001,
368 0x2002,
369 0x2003,
370 0x2004,
371 0x2005,
372 0x2006,
373 0x2007,
374 0x2008,
375 0x2009,
376 0x200A,
377 0x2028,
378 0x2029,
379 0x202F,
380 0x205F,
381 0x3000,
382 }
383
384
385def test_script_runs_without_site_packages_from_outside_repo(tmp_path: Path) -> None:
386 env = os.environ.copy()
387 env.pop("PYTHONPATH", None)
388 env.pop("VIRTUAL_ENV", None)
389
390 result = subprocess.run(
391 [sys.executable, "-S", "-E", str(SCRIPT), "--help"],
392 cwd=tmp_path,
393 env=env,
394 capture_output=True,
395 text=True,
396 check=False,
397 timeout=15,
398 )
399
400 assert result.returncode == 0
401 assert "Rust release manifests" in result.stdout
402
403
404def test_vendored_schema_digest_and_trailing_newline() -> None:
405 data = checker.SCHEMA_PATH.read_bytes()
406
407 assert len(data) == 4416
408 assert data.endswith(b"\n")
409 assert hashlib.sha256(data).hexdigest() == checker.SCHEMA_SHA256
410
411
412def test_load_schema_checks_draft_2020_12_and_format_checker() -> None:
413 schema = checker.load_schema()
414
415 assert schema["$id"] == checker.SCHEMA_ID
416 assert schema["$schema"] == checker.SCHEMA_DRAFT
417
418
419def test_validate_manifest_rejects_schema_level_invalid_payload(
420 tmp_path: Path,
421) -> None:
422 release_dir = _candidate(tmp_path)
423 manifest = _manifest_for_lane(release_dir, "source")
424 payload = _load_manifest(manifest)
425 payload["unexpected"] = "not in schema"
426 _write_manifest(manifest, payload)
427
428 failures = checker.validate_manifest_file(manifest)
429
430 _assert_error(failures, "manifest does not match Rust release manifest schema")
431
432
433def test_main_mode_selection_fixtures_manifest_release_dir(tmp_path: Path) -> None:
434 release_dir = _candidate(tmp_path)
435 manifest = _manifest_for_lane(release_dir, "source")
436
437 assert checker.main([], env={}) == 0
438 assert checker.main([], env={"MANIFEST": str(manifest)}) == 0
439 assert (
440 checker.main(
441 [],
442 env={"RELEASE_DIR": str(release_dir), "SOURCE_COMMIT": VALID_COMMIT},
443 )
444 == 0
445 )
446
447
448def test_main_rejects_conflicting_env_modes(tmp_path: Path) -> None:
449 assert (
450 checker.main(
451 [],
452 env={
453 "MANIFEST": str(tmp_path / "manifest.json"),
454 "RELEASE_DIR": str(tmp_path),
455 },
456 )
457 == 1
458 )
459 assert (
460 checker.main(
461 [],
462 env={
463 "RELEASE_DIR": str(tmp_path),
464 "SOURCE_COMMIT": "abc",
465 },
466 )
467 == 1
468 )
469 assert (
470 checker.main(
471 [],
472 env={
473 "MANIFEST": str(tmp_path / "manifest.json"),
474 "SOURCE_COMMIT": VALID_COMMIT,
475 },
476 )
477 == 1
478 )
479
480
481@pytest.mark.parametrize(
482 "lane",
483 ["source", "linux-x86_64-musl", "linux-aarch64-musl", "macos-arm64"],
484)
485def test_generate_manifest_valid_lane_shapes(
486 tmp_path: Path, lane: checker.LaneName
487) -> None:
488 artifact_name = next(
489 name
490 for name, (artifact_lane, _target) in checker.rust_artifact_targets().items()
491 if artifact_lane == lane
492 )
493 artifact_path = tmp_path / artifact_name
494 artifact_path.write_bytes(b"artifact bytes\n")
495
496 generated, failures = checker.generate_manifest(
497 artifact_path,
498 lane=lane,
499 evidence=checker.fixture_evidence_by_lane()[lane],
500 cohort=checker.CohortInputs(
501 product=checker.PRODUCT,
502 version=checker._current_version(),
503 source_commit=VALID_COMMIT,
504 source_dirty=False,
505 active_exceptions=(),
506 ),
507 )
508
509 assert failures == []
510 assert generated is not None
511 assert generated.bytes.endswith(b"\n")
512 assert (
513 generated.payload["target"] == checker.rust_artifact_targets()[artifact_name][1]
514 )
515
516
517def test_release_dir_accepts_exact_15_without_models(tmp_path: Path) -> None:
518 release_dir = _candidate(tmp_path)
519
520 assert len(list(release_dir.iterdir())) == 15
521 assert (
522 checker.validate_release_dir(release_dir, expected_source_commit=VALID_COMMIT)
523 == []
524 )
525
526
527def test_release_dir_accepts_exact_17_with_models(tmp_path: Path) -> None:
528 release_dir = _candidate(tmp_path, include_models=True)
529
530 assert len(list(release_dir.iterdir())) == 17
531 assert (
532 checker.validate_release_dir(release_dir, expected_source_commit=VALID_COMMIT)
533 == []
534 )
535
536
537def test_release_dir_rejects_one_file_models_set(tmp_path: Path) -> None:
538 release_dir = _candidate(tmp_path)
539 model_name = sorted(checker._models_expected_names())[0]
540 (release_dir / model_name).write_bytes(b"leftover model\n")
541
542 failures = checker.validate_release_dir(
543 release_dir, expected_source_commit=VALID_COMMIT
544 )
545
546 _assert_error(failures, "release directory contains exactly one models archive")
547
548
549def test_release_dir_rejects_wrong_model_version_pair(tmp_path: Path) -> None:
550 release_dir = _candidate(tmp_path)
551 (release_dir / "solstone_journal_models-0.0.0.tar.gz").write_bytes(b"wrong\n")
552 (release_dir / "solstone_journal_models-0.0.0-py3-none-any.whl").write_bytes(
553 b"wrong\n"
554 )
555
556 failures = checker.validate_release_dir(
557 release_dir, expected_source_commit=VALID_COMMIT
558 )
559
560 _assert_error(
561 failures, "models archive names do not match current models version pair"
562 )
563
564
565def test_release_dir_rejects_skipped_model_leftover(tmp_path: Path) -> None:
566 release_dir = _candidate(tmp_path)
567 for name in list(checker.expected_package_names(include_models=False))[:2]:
568 (release_dir / name).unlink()
569 for name in checker._models_expected_names():
570 (release_dir / name).write_bytes(b"skipped model\n")
571
572 failures = checker.validate_release_dir(
573 release_dir, expected_source_commit=VALID_COMMIT
574 )
575
576 _assert_error(failures, "15-file candidate contains models archive leftover")
577
578
579def test_release_dir_rejects_unknown_missing_extra_assets_and_case_collision(
580 tmp_path: Path,
581) -> None:
582 release_dir = _candidate(tmp_path)
583 (release_dir / "unknown.whl").write_bytes(b"unknown\n")
584 (release_dir / checker.expected_package_names(include_models=False)[0]).unlink()
585 for name in checker._models_expected_names():
586 (release_dir / name).write_bytes(b"extra\n")
587 (release_dir / "CASE.txt").write_bytes(b"a\n")
588 (release_dir / "case.TXT").write_bytes(b"b\n")
589
590 failures = checker.validate_release_dir(
591 release_dir, expected_source_commit=VALID_COMMIT
592 )
593
594 _assert_error(failures, "release directory contains unknown asset")
595 _assert_error(failures, "release directory is missing required assets")
596 _assert_error(failures, "release directory contains extra assets")
597 _assert_error(failures, "release directory contains case-colliding filenames")
598
599
600def test_release_dir_rejects_special_file_entry(tmp_path: Path) -> None:
601 release_dir = _candidate(tmp_path)
602 package = release_dir / checker.expected_package_names(include_models=False)[0]
603 package.unlink()
604 package.mkdir()
605
606 failures = checker.validate_release_dir(
607 release_dir, expected_source_commit=VALID_COMMIT
608 )
609
610 _assert_error(failures, "release file is not a regular non-symlink file")
611
612
613def test_release_dir_rejects_extra_or_pure_package_manifest(tmp_path: Path) -> None:
614 release_dir = _candidate(tmp_path)
615 pure_artifact = next(
616 name
617 for name in checker.expected_package_names(include_models=False)
618 if name.startswith("solstone-")
619 )
620 manifest = release_dir / f"{pure_artifact}.rust-release-manifest.json"
621 source_payload = _load_manifest(_manifest_for_lane(release_dir, "source"))
622 source_payload["target"] = {"kind": "source"}
623 digest = hashlib.sha256((release_dir / pure_artifact).read_bytes()).hexdigest()
624 source_payload["artifacts"] = [
625 {
626 "path": pure_artifact,
627 "sha256": digest,
628 "bytes": (release_dir / pure_artifact).stat().st_size,
629 }
630 ]
631 _write_manifest(manifest, source_payload)
632
633 failures = checker.validate_release_dir(
634 release_dir, expected_source_commit=VALID_COMMIT
635 )
636
637 _assert_error(failures, "manifest covers a non-Rust release artifact")
638 _assert_error(
639 failures, "release directory must contain exactly four Rust manifests"
640 )
641
642
643def test_release_dir_rejects_duplicate_coverage(tmp_path: Path) -> None:
644 release_dir = _candidate(tmp_path)
645 original = _manifest_for_lane(release_dir, "source")
646 duplicate = release_dir / "duplicate.rust-release-manifest.json"
647 duplicate.write_bytes(original.read_bytes())
648
649 failures = checker.validate_release_dir(
650 release_dir, expected_source_commit=VALID_COMMIT
651 )
652
653 _assert_error(failures, "Rust artifact is covered by multiple manifests")
654
655
656def test_release_dir_rejects_unmanifested_rust_artifact(tmp_path: Path) -> None:
657 release_dir = _candidate(tmp_path)
658 _manifest_for_lane(release_dir, "macos-arm64").unlink()
659
660 failures = checker.validate_release_dir(
661 release_dir, expected_source_commit=VALID_COMMIT
662 )
663
664 _assert_error(failures, "Rust artifact is not covered by any manifest")
665
666
667def test_release_dir_rejects_artifact_target_swap(tmp_path: Path) -> None:
668 release_dir = _candidate(tmp_path)
669 manifest = _manifest_for_lane(release_dir, "linux-x86_64-musl")
670 payload = _load_manifest(manifest)
671 payload["target"] = checker.rust_artifact_targets()[
672 _artifact_for_lane(release_dir, "macos-arm64").name
673 ][1]
674 _write_manifest(manifest, payload)
675
676 failures = checker.validate_release_dir(
677 release_dir, expected_source_commit=VALID_COMMIT
678 )
679
680 _assert_error(failures, "artifact target does not match release lane")
681
682
683def test_release_dir_rejects_mixed_cohort_including_advisory_time(
684 tmp_path: Path,
685) -> None:
686 release_dir = _candidate(tmp_path)
687 manifest = _manifest_for_lane(release_dir, "source")
688 payload = _load_manifest(manifest)
689 payload["dependency_policy"]["advisory_checked_at"] = "2026-07-21T00:00:00Z"
690 _write_manifest(manifest, payload)
691
692 failures = checker.validate_release_dir(
693 release_dir, expected_source_commit=VALID_COMMIT
694 )
695
696 _assert_error(failures, "Rust release manifests do not agree on cohort fields")
697
698
699def test_release_dir_rejects_false_source_commit(tmp_path: Path) -> None:
700 release_dir = _candidate(tmp_path)
701
702 failures = checker.validate_release_dir(
703 release_dir, expected_source_commit="b" * 40
704 )
705
706 _assert_error(failures, "source_commit does not match SOURCE_COMMIT")
707
708
709def test_rustc_verbose_allows_only_lane_bound_host_difference(tmp_path: Path) -> None:
710 release_dir = _candidate(tmp_path)
711
712 assert (
713 checker.validate_release_dir(release_dir, expected_source_commit=VALID_COMMIT)
714 == []
715 )
716
717 source_manifest = _manifest_for_lane(release_dir, "source")
718 payload = _load_manifest(source_manifest)
719 payload["rust"]["rustc_verbose"] = checker.fixture_rustc_verbose(
720 "aarch64-apple-darwin"
721 )
722 _write_manifest(source_manifest, payload)
723 failures = checker.validate_release_dir(
724 release_dir, expected_source_commit=VALID_COMMIT
725 )
726 _assert_error(failures, "rustc host is not an allowed build host")
727
728
729def test_rustc_host_mismatch_redacts_host_value(
730 tmp_path: Path, capsys: pytest.CaptureFixture[str]
731) -> None:
732 host = "buildhost01"
733 release_dir = _candidate(tmp_path)
734 manifest = _manifest_for_lane(release_dir, "source")
735 payload = _load_manifest(manifest)
736 payload["rust"]["rustc_verbose"] = checker.fixture_rustc_verbose(host)
737 _write_manifest(manifest, payload)
738
739 failures = checker.validate_manifest_file(manifest)
740
741 _assert_error(failures, "rustc host is not an allowed build host")
742 _assert_redacted(failures, (host,))
743 _assert_formatted_redacted(failures, (host,), capsys)
744
745
746@pytest.mark.parametrize("code_point", RUSTC_REJECTED_SEPARATOR_CODE_POINTS)
747def test_rustc_verbose_rejects_non_space_separator_code_points(
748 tmp_path: Path,
749 capsys: pytest.CaptureFixture[str],
750 code_point: int,
751) -> None:
752 canonical = checker.fixture_rustc_verbose("x86_64-unknown-linux-gnu")
753 canonical_lines = canonical.split("\n")
754 artifact_path = _source_artifact(tmp_path)
755
756 for line_index in range(1, len(canonical_lines)):
757 label, value = canonical_lines[line_index].split(": ", 1)
758 mutant_line = f"{label}:{chr(code_point)}{value}"
759 mutant = _rustc_line_mutant(canonical, line_index, mutant_line)
760 if code_point == 0x0A:
761 _assert_rustc_lf_separator_mutant_rejected(
762 artifact_path,
763 capsys,
764 canonical=canonical,
765 mutant=mutant,
766 line_index=line_index,
767 )
768 else:
769 _assert_rustc_line_mutant_rejected(
770 artifact_path,
771 capsys,
772 canonical=canonical,
773 mutant=mutant,
774 line_index=line_index,
775 )
776
777
778@pytest.mark.parametrize(
779 "spacing_case", ("zero", "two", "three", "pre_colon", "trailing")
780)
781def test_rustc_verbose_rejects_noncanonical_space_counts(
782 tmp_path: Path,
783 capsys: pytest.CaptureFixture[str],
784 spacing_case: str,
785) -> None:
786 canonical = checker.fixture_rustc_verbose("x86_64-unknown-linux-gnu")
787 canonical_lines = canonical.split("\n")
788 artifact_path = _source_artifact(tmp_path)
789
790 for line_index in range(1, len(canonical_lines)):
791 label, value = canonical_lines[line_index].split(": ", 1)
792 if spacing_case == "zero":
793 mutant_line = f"{label}:{value}"
794 elif spacing_case == "two":
795 mutant_line = f"{label}: {value}"
796 elif spacing_case == "three":
797 mutant_line = f"{label}: {value}"
798 elif spacing_case == "pre_colon":
799 mutant_line = f"{label} : {value}"
800 else:
801 mutant_line = f"{label}: {value} "
802 mutant = _rustc_line_mutant(canonical, line_index, mutant_line)
803 _assert_rustc_line_mutant_rejected(
804 artifact_path,
805 capsys,
806 canonical=canonical,
807 mutant=mutant,
808 line_index=line_index,
809 )
810
811
812def test_rustc_verbose_rejects_crlf_line_boundary(
813 tmp_path: Path, capsys: pytest.CaptureFixture[str]
814) -> None:
815 canonical = checker.fixture_rustc_verbose("x86_64-unknown-linux-gnu")
816 lines = canonical.split("\n")
817 mutant = canonical.replace("\n", "\r\n", 1)
818 assert "\r\n" in mutant
819 assert mutant.replace("\r\n", "\n", 1) == canonical
820 _assert_rustc_mutant_rejected(
821 _source_artifact(tmp_path),
822 capsys,
823 mutant=mutant,
824 forbidden=(mutant, f"{lines[0]}\r\n{lines[1]}"),
825 )
826
827
828def test_rustc_verbose_rejects_lone_cr_line_boundary(
829 tmp_path: Path, capsys: pytest.CaptureFixture[str]
830) -> None:
831 canonical = checker.fixture_rustc_verbose("x86_64-unknown-linux-gnu")
832 lines = canonical.split("\n")
833 mutant = canonical.replace("\n", "\r", 1)
834 assert "\r" in mutant
835 assert mutant.replace("\r", "\n", 1) == canonical
836 _assert_rustc_mutant_rejected(
837 _source_artifact(tmp_path),
838 capsys,
839 mutant=mutant,
840 forbidden=(mutant, f"{lines[0]}\r{lines[1]}"),
841 )
842
843
844@pytest.mark.parametrize("separator", ("\u0085", "\u2028", "\u2029"))
845def test_rustc_verbose_rejects_unicode_line_boundary_replacements(
846 tmp_path: Path,
847 capsys: pytest.CaptureFixture[str],
848 separator: str,
849) -> None:
850 canonical = checker.fixture_rustc_verbose("x86_64-unknown-linux-gnu")
851 lines = canonical.split("\n")
852 mutant = canonical.replace("\n", separator, 1)
853 assert separator in mutant
854 assert mutant.replace(separator, "\n", 1) == canonical
855 _assert_rustc_mutant_rejected(
856 _source_artifact(tmp_path),
857 capsys,
858 mutant=mutant,
859 forbidden=(mutant, f"{lines[0]}{separator}{lines[1]}"),
860 )
861
862
863def test_rustc_verbose_rejects_doubled_lf_line_boundary(
864 tmp_path: Path, capsys: pytest.CaptureFixture[str]
865) -> None:
866 canonical = checker.fixture_rustc_verbose("x86_64-unknown-linux-gnu")
867 lines = canonical.split("\n")
868 mutant = canonical.replace("\n", "\n\n", 1)
869 assert mutant.count("\n") == canonical.count("\n") + 1
870 assert mutant.replace("\n\n", "\n", 1) == canonical
871 _assert_rustc_mutant_rejected(
872 _source_artifact(tmp_path),
873 capsys,
874 mutant=mutant,
875 forbidden=(mutant, f"{lines[0]}\n\n{lines[1]}"),
876 )
877
878
879def test_rustc_verbose_rejects_leading_lf(
880 tmp_path: Path, capsys: pytest.CaptureFixture[str]
881) -> None:
882 canonical = checker.fixture_rustc_verbose("x86_64-unknown-linux-gnu")
883 lines = canonical.split("\n")
884 mutant = "\n" + canonical
885 assert mutant.startswith("\n")
886 assert mutant.count("\n") == canonical.count("\n") + 1
887 assert mutant.removeprefix("\n") == canonical
888 _assert_rustc_mutant_rejected(
889 _source_artifact(tmp_path),
890 capsys,
891 mutant=mutant,
892 forbidden=(mutant, f"\n{lines[0]}"),
893 )
894
895
896def test_rustc_verbose_rejects_trailing_lf(
897 tmp_path: Path, capsys: pytest.CaptureFixture[str]
898) -> None:
899 canonical = checker.fixture_rustc_verbose("x86_64-unknown-linux-gnu")
900 lines = canonical.split("\n")
901 mutant = canonical + "\n"
902 assert mutant.endswith("\n")
903 assert mutant.count("\n") == canonical.count("\n") + 1
904 assert mutant.removesuffix("\n") == canonical
905 _assert_rustc_mutant_rejected(
906 _source_artifact(tmp_path),
907 capsys,
908 mutant=mutant,
909 forbidden=(mutant, f"{lines[-1]}\n"),
910 )
911
912
913@pytest.mark.parametrize(
914 ("name", "separator"), (("nbsp", "\u00a0"), ("zero", ""), ("two", " "))
915)
916def test_rustc_verbose_separator_rejections_cover_file_and_candidate_channels(
917 tmp_path: Path,
918 capsys: pytest.CaptureFixture[str],
919 name: str,
920 separator: str,
921) -> None:
922 canonical = checker.fixture_rustc_verbose("x86_64-unknown-linux-gnu")
923 lines = canonical.split("\n")
924 label, value = lines[1].split(": ", 1)
925 mutant_line = f"{label}:{separator}{value}"
926 mutant = _rustc_line_mutant(canonical, 1, mutant_line)
927
928 release_dir = _candidate(tmp_path / f"file-{name}")
929 manifest = _manifest_for_lane(release_dir, "source")
930 payload = _load_manifest(manifest)
931 payload["rust"]["rustc_verbose"] = mutant
932 _write_manifest(manifest, payload)
933 failures = checker.validate_manifest_file(manifest)
934 _assert_malformed_redacted(failures, (mutant, mutant_line), capsys)
935
936 evidence = checker.fixture_evidence_by_lane()
937 mutated_evidence = dict(evidence)
938 mutated_evidence["source"] = replace(evidence["source"], rustc_verbose=mutant)
939 failures = checker.write_inert_candidate(
940 tmp_path / f"generated-{name}",
941 include_models=False,
942 evidence_by_lane=mutated_evidence,
943 )
944 _assert_malformed_redacted(failures, (mutant, mutant_line), capsys)
945
946
947@pytest.mark.parametrize(
948 ("lane", "host"),
949 (
950 ("source", "x86_64-unknown-linux-gnu"),
951 ("macos-arm64", "aarch64-apple-darwin"),
952 ),
953)
954def test_rustc_verbose_canonical_evidence_is_byte_exact(
955 tmp_path: Path,
956 lane: str,
957 host: str,
958) -> None:
959 canonical = checker.fixture_rustc_verbose(host)
960 parsed, parse_failures = checker.parse_rustc_verbose(canonical)
961 assert parse_failures == []
962 assert parsed is not None
963
964 release_dir = tmp_path / lane
965 checker.write_inert_packages(release_dir, include_models=False)
966 artifact_path = _artifact_for_lane(release_dir, lane)
967 evidence = checker.fixture_evidence_by_lane()[lane]
968 assert evidence.rustc_verbose == canonical
969
970 generated, generate_failures = checker.generate_manifest(
971 artifact_path,
972 lane=lane,
973 evidence=evidence,
974 cohort=checker._default_cohort(VALID_COMMIT),
975 )
976 assert generate_failures == []
977 assert generated is not None
978 manifest_bytes = checker.canonical_json_bytes(generated.payload)
979 assert manifest_bytes == generated.bytes
980
981 decoded = json.loads(manifest_bytes)
982 rustc_verbose = decoded["rust"]["rustc_verbose"]
983 assert rustc_verbose == canonical
984 assert rustc_verbose.encode("utf-8") == canonical.encode("utf-8")
985
986 manifest_path = release_dir / generated.manifest_name
987 manifest_path.write_bytes(manifest_bytes)
988 assert checker.validate_manifest_file(manifest_path) == []
989
990
991def test_rustc_verbose_rejects_malformed_spoof_and_mixed_labeled_lines(
992 tmp_path: Path,
993) -> None:
994 release_dir = _candidate(tmp_path)
995 manifest = _manifest_for_lane(release_dir, "macos-arm64")
996 payload = _load_manifest(manifest)
997 payload["rust"]["rustc_verbose"] = checker.fixture_rustc_verbose(
998 "x86_64-unknown-linux-gnu"
999 )
1000 _write_manifest(manifest, payload)
1001 failures = checker.validate_release_dir(
1002 release_dir, expected_source_commit=VALID_COMMIT
1003 )
1004 _assert_error(failures, "rustc host is not an allowed build host")
1005
1006 release_dir = _candidate(tmp_path / "malformed")
1007 manifest = _manifest_for_lane(release_dir, "source")
1008 payload = _load_manifest(manifest)
1009 payload["rust"]["rustc_verbose"] = "rustc nope"
1010 _write_manifest(manifest, payload)
1011 failures = checker.validate_release_dir(
1012 release_dir, expected_source_commit=VALID_COMMIT
1013 )
1014 _assert_error(failures, "rustc_verbose is malformed")
1015
1016 release_dir = _candidate(tmp_path / "mixed")
1017 manifest = _manifest_for_lane(release_dir, "source")
1018 payload = _load_manifest(manifest)
1019 payload["rust"]["rustc_verbose"] = payload["rust"]["rustc_verbose"].replace(
1020 f"LLVM version: {checker.RUSTC_LLVM_PIN}", "LLVM version: 22.0.0"
1021 )
1022 _write_manifest(manifest, payload)
1023 failures = checker.validate_release_dir(
1024 release_dir, expected_source_commit=VALID_COMMIT
1025 )
1026 _assert_error(failures, "rustc_verbose is malformed")
1027
1028
1029def test_rust_evidence_rejects_uniformly_wrong_toolchain_pins(tmp_path: Path) -> None:
1030 release_dir = _candidate(tmp_path)
1031 wrong_rustc = "\n".join(
1032 [
1033 "rustc 1.96.0 (111111111 2026-01-01)",
1034 "binary: rustc",
1035 "commit-hash: 1111111111111111111111111111111111111111",
1036 "commit-date: 2026-01-01",
1037 "host: x86_64-unknown-linux-gnu",
1038 "release: 1.96.0",
1039 "LLVM version: 21.0.0",
1040 ]
1041 )
1042 for lane in checker.LANES:
1043 manifest = _manifest_for_lane(release_dir, lane)
1044 payload = _load_manifest(manifest)
1045 payload["rust"]["rustc_verbose"] = wrong_rustc.replace(
1046 "x86_64-unknown-linux-gnu", checker.LANE_HOSTS[lane]
1047 )
1048 payload["rust"]["cargo_version"] = "cargo 1.96.0 (222222222 2026-01-01)"
1049 payload["dependency_policy"]["cargo_deny_version"] = "cargo-deny 0.1.0"
1050 _write_manifest(manifest, payload)
1051
1052 failures = checker.validate_release_dir(
1053 release_dir, expected_source_commit=VALID_COMMIT
1054 )
1055
1056 _assert_error(failures, "rustc_verbose is malformed")
1057 _assert_error(failures, "cargo_version is malformed")
1058 _assert_error(failures, "cargo_deny_version is not pinned")
1059
1060
1061def test_rustc_verbose_rejects_wrong_binary(tmp_path: Path) -> None:
1062 release_dir = _candidate(tmp_path)
1063 manifest = _manifest_for_lane(release_dir, "source")
1064 payload = _load_manifest(manifest)
1065 payload["rust"]["rustc_verbose"] = payload["rust"]["rustc_verbose"].replace(
1066 f"binary: {checker.RUSTC_BINARY_PIN}", "binary: rustdoc"
1067 )
1068 _write_manifest(manifest, payload)
1069
1070 failures = checker.validate_manifest_file(manifest)
1071
1072 _assert_error(failures, "rustc_verbose is malformed")
1073
1074
1075def test_rustc_verbose_rejects_missing_duplicate_unknown_labels(
1076 tmp_path: Path,
1077) -> None:
1078 cases: tuple[tuple[str, list[str]], ...] = (
1079 ("missing", _rustc_lines()[:3] + _rustc_lines()[4:]),
1080 (
1081 "duplicate",
1082 [
1083 *_rustc_lines()[:4],
1084 f"commit-date: {checker.RUSTC_COMMIT_DATE_PIN}",
1085 *_rustc_lines()[5:],
1086 ],
1087 ),
1088 (
1089 "unknown",
1090 [
1091 *_rustc_lines()[:5],
1092 "channel: stable",
1093 _rustc_lines()[6],
1094 ],
1095 ),
1096 )
1097 for name, lines in cases:
1098 release_dir = _candidate(tmp_path / name)
1099 manifest = _manifest_for_lane(release_dir, "source")
1100 payload = _load_manifest(manifest)
1101 payload["rust"]["rustc_verbose"] = "\n".join(lines)
1102 _write_manifest(manifest, payload)
1103
1104 failures = checker.validate_manifest_file(manifest)
1105
1106 _assert_error(failures, "rustc_verbose is malformed")
1107
1108
1109def test_rustc_verbose_rejects_wrong_commit_date_release_llvm_and_bad_host(
1110 tmp_path: Path,
1111) -> None:
1112 replacements = (
1113 (
1114 "commit",
1115 f"commit-hash: {checker.RUSTC_COMMIT_HASH_PIN}",
1116 "commit-hash: " + "b" * 40,
1117 ),
1118 (
1119 "date",
1120 f"commit-date: {checker.RUSTC_COMMIT_DATE_PIN}",
1121 "commit-date: 2026-01-01",
1122 ),
1123 ("release", f"release: {checker.RUSTC_RELEASE_PIN}", "release: 1.96.0"),
1124 ("llvm", f"LLVM version: {checker.RUSTC_LLVM_PIN}", "LLVM version: 21.0.0"),
1125 )
1126 for name, old, new in replacements:
1127 release_dir = _candidate(tmp_path / name)
1128 manifest = _manifest_for_lane(release_dir, "source")
1129 payload = _load_manifest(manifest)
1130 payload["rust"]["rustc_verbose"] = payload["rust"]["rustc_verbose"].replace(
1131 old, new
1132 )
1133 _write_manifest(manifest, payload)
1134
1135 failures = checker.validate_manifest_file(manifest)
1136
1137 _assert_error(failures, "rustc_verbose is malformed")
1138
1139 release_dir = _candidate(tmp_path / "host")
1140 manifest = _manifest_for_lane(release_dir, "source")
1141 payload = _load_manifest(manifest)
1142 payload["rust"]["rustc_verbose"] = checker.fixture_rustc_verbose("localhost")
1143 _write_manifest(manifest, payload)
1144 failures = checker.validate_manifest_file(manifest)
1145 _assert_error(failures, "rustc_verbose contains disallowed content")
1146 _assert_error(failures, "rustc host is not an allowed build host")
1147
1148
1149def test_rustc_verbose_rejects_blank_interstitial_reordered_and_extra_lines(
1150 tmp_path: Path,
1151) -> None:
1152 lines = _rustc_lines()
1153 cases: tuple[tuple[str, list[str]], ...] = (
1154 ("blank", [*lines[:3], "", *lines[3:]]),
1155 ("reordered", [lines[0], lines[2], lines[1], *lines[3:]]),
1156 ("extra", [*lines, "extra: public"]),
1157 )
1158 for name, rustc_lines in cases:
1159 release_dir = _candidate(tmp_path / name)
1160 manifest = _manifest_for_lane(release_dir, "source")
1161 payload = _load_manifest(manifest)
1162 payload["rust"]["rustc_verbose"] = "\n".join(rustc_lines)
1163 _write_manifest(manifest, payload)
1164
1165 failures = checker.validate_manifest_file(manifest)
1166
1167 _assert_error(failures, "rustc_verbose is malformed")
1168
1169
1170def test_rust_evidence_redacts_canaries_from_failures_and_formatted_output(
1171 tmp_path: Path, capsys: pytest.CaptureFixture[str]
1172) -> None:
1173 token = "sk-abcdefghijklmnopqrstuvwx"
1174 private_path = "/Users/jer/.cargo/bin"
1175 release_dir = _candidate(tmp_path)
1176 manifest = _manifest_for_lane(release_dir, "source")
1177 payload = _load_manifest(manifest)
1178 payload["rust"]["rustc_verbose"] = "\n".join(
1179 [*_rustc_lines(), f"leak: {token} {private_path}"]
1180 )
1181 _write_manifest(manifest, payload)
1182
1183 failures = checker.validate_release_dir(
1184 release_dir, expected_source_commit=VALID_COMMIT
1185 )
1186
1187 assert failures
1188 _assert_error(failures, "rustc_verbose contains disallowed content")
1189 _assert_redacted(failures, (token, private_path))
1190 _assert_formatted_redacted(failures, (token, private_path), capsys)
1191
1192
1193def test_cargo_and_cargo_deny_pins_are_enforced_without_echoing_input(
1194 tmp_path: Path, capsys: pytest.CaptureFixture[str]
1195) -> None:
1196 token = "sk-abcdefghijklmnopqrstuvwx"
1197 private_path = "/Users/jer/.cargo/bin"
1198 release_dir = _candidate(tmp_path)
1199 manifest = _manifest_for_lane(release_dir, "source")
1200 payload = _load_manifest(manifest)
1201 payload["rust"]["cargo_version"] = f"cargo 1.96.0 ({token} 2026-01-01)"
1202 payload["dependency_policy"]["cargo_deny_version"] = (
1203 f"cargo-deny 0.1.0 {private_path} {token}"
1204 )
1205 _write_manifest(manifest, payload)
1206
1207 failures = checker.validate_manifest_file(manifest)
1208
1209 _assert_error(failures, "cargo_version is malformed")
1210 _assert_error(failures, "cargo_deny_version is not pinned")
1211 _assert_error(failures, "cargo_version contains disallowed content")
1212 _assert_error(failures, "cargo_deny_version contains disallowed content")
1213 _assert_redacted(failures, (token, private_path))
1214 _assert_formatted_redacted(failures, (token, private_path), capsys)
1215
1216
1217def test_cargo_and_cargo_deny_reject_surrounding_whitespace_and_control(
1218 tmp_path: Path,
1219) -> None:
1220 cargo_variants = (
1221 " " + checker.CARGO_VERSION_PIN,
1222 checker.CARGO_VERSION_PIN + " ",
1223 checker.CARGO_VERSION_PIN + "\n",
1224 checker.CARGO_VERSION_PIN + "\t",
1225 checker.CARGO_VERSION_PIN + "\x00",
1226 )
1227 for index, variant in enumerate(cargo_variants):
1228 release_dir = _candidate(tmp_path / f"cargo-{index}")
1229 manifest = _manifest_for_lane(release_dir, "source")
1230 payload = _load_manifest(manifest)
1231 payload["rust"]["cargo_version"] = variant
1232 _write_manifest(manifest, payload)
1233
1234 failures = checker.validate_manifest_file(manifest)
1235
1236 _assert_error(failures, "cargo_version is malformed")
1237 _assert_redacted(failures, (variant,))
1238
1239 cargo_deny_variants = (
1240 " " + checker.CARGO_DENY_PIN,
1241 checker.CARGO_DENY_PIN + " ",
1242 checker.CARGO_DENY_PIN + "\n",
1243 checker.CARGO_DENY_PIN + "\t",
1244 checker.CARGO_DENY_PIN + "\x00",
1245 )
1246 for index, variant in enumerate(cargo_deny_variants):
1247 release_dir = _candidate(tmp_path / f"deny-{index}")
1248 manifest = _manifest_for_lane(release_dir, "source")
1249 payload = _load_manifest(manifest)
1250 payload["dependency_policy"]["cargo_deny_version"] = variant
1251 _write_manifest(manifest, payload)
1252
1253 failures = checker.validate_manifest_file(manifest)
1254
1255 _assert_error(failures, "cargo_deny_version is not pinned")
1256 _assert_redacted(failures, (variant,))
1257
1258
1259def test_generate_rejects_cargo_and_cargo_deny_surrounding_whitespace_and_redacts(
1260 tmp_path: Path, capsys: pytest.CaptureFixture[str]
1261) -> None:
1262 evidence = checker.fixture_evidence_by_lane()
1263 cargo_evidence = dict(evidence)
1264 cargo_evidence["source"] = replace(
1265 evidence["source"], cargo_version=checker.CARGO_VERSION_PIN + " "
1266 )
1267
1268 failures = checker.write_inert_candidate(
1269 tmp_path / "gen-cargo",
1270 include_models=False,
1271 evidence_by_lane=cargo_evidence,
1272 )
1273
1274 assert failures
1275 _assert_error(failures, "cargo_version is malformed")
1276
1277 deny_evidence = dict(evidence)
1278 deny_evidence["source"] = replace(
1279 evidence["source"], cargo_deny_version=" " + checker.CARGO_DENY_PIN
1280 )
1281
1282 failures = checker.write_inert_candidate(
1283 tmp_path / "gen-deny",
1284 include_models=False,
1285 evidence_by_lane=deny_evidence,
1286 )
1287
1288 assert failures
1289 _assert_error(failures, "cargo_deny_version is not pinned")
1290
1291 private_path = "/Users/jer/.cargo"
1292 token = "sk-abcdefghijklmnopqrstuvwx"
1293 deny_canary_evidence = dict(evidence)
1294 deny_canary_evidence["source"] = replace(
1295 evidence["source"],
1296 cargo_deny_version=f"{checker.CARGO_DENY_PIN} {private_path} {token}",
1297 )
1298
1299 failures = checker.write_inert_candidate(
1300 tmp_path / "gen-deny-canary",
1301 include_models=False,
1302 evidence_by_lane=deny_canary_evidence,
1303 )
1304
1305 assert failures
1306 _assert_error(failures, "cargo_deny_version is not pinned")
1307 _assert_error(failures, "cargo_deny_version contains disallowed content")
1308 _assert_redacted(failures, (private_path, token))
1309 _assert_formatted_redacted(failures, (private_path, token), capsys)
1310
1311
1312def test_rust_evidence_accepts_pinned_linux_and_macos_hosts() -> None:
1313 cases: tuple[tuple[checker.LaneName, str], ...] = (
1314 ("source", "x86_64-unknown-linux-gnu"),
1315 ("macos-arm64", "aarch64-apple-darwin"),
1316 )
1317 for lane, host in cases:
1318 rustc, cargo, failures = checker._validate_rust_for_lane(
1319 lane,
1320 {
1321 "rustc_verbose": checker.fixture_rustc_verbose(host),
1322 "cargo_version": checker.CARGO_VERSION_PIN,
1323 },
1324 )
1325
1326 assert failures == []
1327 assert rustc is not None
1328 assert rustc.host == host
1329 assert cargo == checker.CARGO_RELEASE_PIN
1330
1331
1332def test_native_tools_allowlists_by_lane() -> None:
1333 evidence = checker.fixture_evidence_by_lane()
1334
1335 for lane, lane_evidence in evidence.items():
1336 assert checker.validate_native_tools(lane, lane_evidence.native_tools) == []
1337
1338 failures = checker.validate_native_tools(
1339 "source",
1340 {"uv": pins.UV_PIN, "maturin": pins.MATURIN_PIN, "zig": pins.ZIG_PIN},
1341 )
1342 _assert_error(failures, "native_tools keys do not match lane allowlist")
1343
1344 failures = checker.validate_native_tools("source", {"uv": pins.UV_PIN})
1345 _assert_error(failures, "native_tools keys do not match lane allowlist")
1346
1347 failures = checker.validate_native_tools(
1348 "macos-arm64",
1349 {
1350 "uv": pins.UV_PIN,
1351 "maturin": pins.MATURIN_PIN,
1352 "xcode": pins.MACOS_XCODE_PIN,
1353 "codesign": pins.MACOS_CODESIGN_PUBLIC_PIN,
1354 "notarytool": pins.MACOS_NOTARYTOOL_PIN,
1355 "signing_mode": "unsigned",
1356 },
1357 )
1358 _assert_error(failures, "macOS signing_mode is not signed-verified")
1359
1360
1361@pytest.mark.parametrize(
1362 ("value", "error"),
1363 [
1364 (
1365 f"{pins.UV_PIN}\nPATH=/tmp/bin",
1366 "native_tools value is not a normalized public single-line string",
1367 ),
1368 (
1369 "TOKEN=abc123",
1370 "native_tools value is not a normalized public single-line string",
1371 ),
1372 ("secret token abc123", "native_tools value contains secret/token canary"),
1373 (
1374 "built on build-host.local",
1375 "native_tools value contains private host, IP, or path",
1376 ),
1377 (
1378 "reachable at 192.168.1.10",
1379 "native_tools value contains private host, IP, or path",
1380 ),
1381 (
1382 "installed in /Users/jer/bin",
1383 "native_tools value contains private host, IP, or path",
1384 ),
1385 ("owner@example.com", "native_tools value contains email address"),
1386 (
1387 "Developer ID Application: sol pbc",
1388 "native_tools value contains signing identity",
1389 ),
1390 (
1391 "submission 123e4567-e89b-12d3-a456-426614174000",
1392 "native_tools value contains notarization submission ID",
1393 ),
1394 ],
1395)
1396def test_native_tools_rejects_canaries(value: str, error: str) -> None:
1397 tools = {"uv": value, "maturin": pins.MATURIN_PIN}
1398
1399 failures = checker.validate_native_tools("source", tools)
1400
1401 _assert_error(failures, error)
1402
1403
1404@pytest.mark.parametrize(
1405 "bad_path", ["../artifact.whl", "/tmp/artifact.whl", "a\\b.whl"]
1406)
1407def test_validate_manifest_rejects_path_traversal_absolute_backslash(
1408 tmp_path: Path, bad_path: str
1409) -> None:
1410 release_dir = _candidate(tmp_path)
1411 manifest = _manifest_for_lane(release_dir, "source")
1412 payload = _load_manifest(manifest)
1413 payload["artifacts"][0]["path"] = bad_path
1414 _write_manifest(manifest, payload)
1415
1416 failures = checker.validate_manifest_file(manifest)
1417
1418 _assert_error(failures, "artifact path is not a safe relative basename")
1419
1420
1421def test_validate_manifest_rejects_control_character_artifact_path(
1422 tmp_path: Path,
1423) -> None:
1424 release_dir = _candidate(tmp_path)
1425 manifest = _manifest_for_lane(release_dir, "source")
1426 payload = _load_manifest(manifest)
1427 payload["artifacts"][0]["path"] = "bad" + chr(10) + ".whl"
1428 _write_manifest(manifest, payload)
1429
1430 failures = checker.validate_manifest_file(manifest)
1431
1432 _assert_error(failures, "artifact path is not a safe relative basename")
1433
1434
1435def test_validate_manifest_rejects_symlink_missing_empty_and_hash_mismatch(
1436 tmp_path: Path,
1437) -> None:
1438 release_dir = _candidate(tmp_path / "missing")
1439 manifest = _manifest_for_lane(release_dir, "source")
1440 _artifact_for_lane(release_dir, "source").unlink()
1441 failures = checker.validate_manifest_file(manifest)
1442 _assert_error(failures, "manifest artifact is missing")
1443
1444 release_dir = _candidate(tmp_path / "empty")
1445 manifest = _manifest_for_lane(release_dir, "source")
1446 _artifact_for_lane(release_dir, "source").write_bytes(b"")
1447 failures = checker.validate_manifest_file(manifest)
1448 _assert_error(failures, "manifest artifact is empty")
1449
1450 release_dir = _candidate(tmp_path / "hash")
1451 manifest = _manifest_for_lane(release_dir, "source")
1452 _artifact_for_lane(release_dir, "source").write_bytes(b"mutated\n")
1453 failures = checker.validate_manifest_file(manifest)
1454 _assert_error(failures, "artifact sha256 does not match manifest")
1455
1456 release_dir = _candidate(tmp_path / "symlink")
1457 manifest = _manifest_for_lane(release_dir, "source")
1458 artifact = _artifact_for_lane(release_dir, "source")
1459 artifact.unlink()
1460 artifact.symlink_to(
1461 release_dir / checker.expected_package_names(include_models=False)[0]
1462 )
1463 failures = checker.validate_manifest_file(manifest)
1464 _assert_error(failures, "release file is not a regular non-symlink file")
1465
1466
1467def test_validate_manifest_rejects_invalid_time_hash_commit_target_features(
1468 tmp_path: Path,
1469) -> None:
1470 release_dir = _candidate(tmp_path / "time")
1471 manifest = _manifest_for_lane(release_dir, "source")
1472 payload = _load_manifest(manifest)
1473 payload["dependency_policy"]["advisory_checked_at"] = "2026-07-20T00:00:00-06:00"
1474 _write_manifest(manifest, payload)
1475 failures = checker.validate_manifest_file(manifest)
1476 _assert_error(failures, "advisory timestamp is not RFC3339 UTC")
1477
1478 release_dir = _candidate(tmp_path / "hash")
1479 manifest = _manifest_for_lane(release_dir, "source")
1480 payload = _load_manifest(manifest)
1481 payload["artifacts"][0]["sha256"] = "ABC"
1482 _write_manifest(manifest, payload)
1483 failures = checker.validate_manifest_file(manifest)
1484 _assert_error(failures, "sha256 is not lowercase hex")
1485
1486 release_dir = _candidate(tmp_path / "commit")
1487 manifest = _manifest_for_lane(release_dir, "source")
1488 payload = _load_manifest(manifest)
1489 payload["source_commit"] = "abc"
1490 _write_manifest(manifest, payload)
1491 failures = checker.validate_manifest_file(manifest)
1492 _assert_error(failures, "source_commit is not a full lowercase commit")
1493
1494 release_dir = _candidate(tmp_path / "target")
1495 manifest = _manifest_for_lane(release_dir, "linux-x86_64-musl")
1496 payload = _load_manifest(manifest)
1497 payload["target"]["profile"] = "debug"
1498 _write_manifest(manifest, payload)
1499 failures = checker.validate_manifest_file(manifest)
1500 _assert_error(failures, "artifact target does not match release lane")
1501
1502 release_dir = _candidate(tmp_path / "features")
1503 manifest = _manifest_for_lane(release_dir, "linux-x86_64-musl")
1504 payload = _load_manifest(manifest)
1505 payload["target"]["features"] = ["extra"]
1506 _write_manifest(manifest, payload)
1507 failures = checker.validate_manifest_file(manifest)
1508 _assert_error(failures, "artifact target does not match release lane")
1509
1510
1511def test_validate_manifest_rejects_non_finite_json(tmp_path: Path) -> None:
1512 release_dir = _candidate(tmp_path)
1513 manifest = _manifest_for_lane(release_dir, "source")
1514 text = manifest.read_text(encoding="utf-8").replace(
1515 '"schema_version":1', '"schema_version":NaN'
1516 )
1517 manifest.write_text(text, encoding="utf-8")
1518
1519 failures = checker.validate_manifest_file(manifest)
1520
1521 _assert_error(failures, "manifest JSON is invalid or non-finite")
1522
1523
1524def test_validate_manifest_accepts_historical_utc_timestamp(tmp_path: Path) -> None:
1525 release_dir = _candidate(tmp_path)
1526 manifest = _manifest_for_lane(release_dir, "source")
1527 payload = _load_manifest(manifest)
1528 payload["dependency_policy"]["advisory_checked_at"] = "2020-01-01T00:00:00+00:00"
1529 _write_manifest(manifest, payload)
1530
1531 failures = checker.validate_manifest_file(manifest)
1532
1533 assert failures == []
1534
1535
1536def test_canonical_json_fixed_input_bytes_are_deterministic() -> None:
1537 payload = {
1538 "b": {"features": ["z", "a"]},
1539 "active_exceptions": ["z", "a"],
1540 "a": 1,
1541 }
1542
1543 first = checker.canonical_json_bytes(payload)
1544 second = checker.canonical_json_bytes(payload)
1545
1546 assert first == second
1547 assert first.endswith(b"\n")
1548 assert b'"active_exceptions":["a","z"]' in first
1549 with pytest.raises(ValueError, match="non-finite"):
1550 checker.canonical_json_bytes({"x": float("nan")})
1551
1552
1553def test_build_and_promote_candidate_success_is_whole_directory_rename(
1554 tmp_path: Path,
1555) -> None:
1556 ready, failures = _build_ready(tmp_path)
1557
1558 assert failures == []
1559 assert ready.is_dir()
1560 assert not (tmp_path / "ready.staging").exists()
1561 assert len(list(ready.iterdir())) == 15
1562 assert (
1563 checker.validate_release_dir(ready, expected_source_commit=VALID_COMMIT) == []
1564 )
1565
1566
1567def test_build_and_promote_candidate_rejects_lock_contention(tmp_path: Path) -> None:
1568 dist = _source_dist(tmp_path)
1569 ready = tmp_path / "ready"
1570 lock = (tmp_path / ".rust-release-candidate.lock").open("a+")
1571 try:
1572 fcntl.flock(lock.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
1573 failures = checker.build_and_promote_candidate(
1574 dist,
1575 ready,
1576 source_commit=VALID_COMMIT,
1577 evidence_by_lane=checker.fixture_evidence_by_lane(),
1578 include_models=False,
1579 )
1580 finally:
1581 fcntl.flock(lock.fileno(), fcntl.LOCK_UN)
1582 lock.close()
1583
1584 _assert_error(failures, "release candidate lock is already held")
1585 assert not ready.exists()
1586 assert not (tmp_path / "ready.staging").exists()
1587
1588
1589def test_build_and_promote_candidate_rolls_back_staging_on_pre_promotion_failure(
1590 tmp_path: Path,
1591) -> None:
1592 dist = _source_dist(tmp_path)
1593 (dist / checker.expected_package_names(include_models=False)[0]).unlink()
1594 ready = tmp_path / "ready"
1595
1596 failures = checker.build_and_promote_candidate(
1597 dist,
1598 ready,
1599 source_commit=VALID_COMMIT,
1600 evidence_by_lane=checker.fixture_evidence_by_lane(),
1601 include_models=False,
1602 )
1603
1604 _assert_error(failures, "manifest artifact is missing")
1605 assert not ready.exists()
1606 assert not (tmp_path / "ready.staging").exists()
1607
1608
1609def test_build_and_promote_candidate_removes_ready_on_post_promotion_failure(
1610 tmp_path: Path,
1611) -> None:
1612 def mutate(path: Path) -> None:
1613 artifact = next(iter(sorted(checker._rust_artifact_names())))
1614 (path / artifact).write_bytes(b"mutated\n")
1615
1616 ready, failures = _build_ready(tmp_path, hook=mutate)
1617
1618 _assert_error(failures, "artifact sha256 does not match manifest")
1619 assert not ready.exists()
1620 assert not (tmp_path / "ready.quarantine").exists()
1621
1622
1623def test_build_and_promote_candidate_quarantines_ready_when_post_promote_hook_raises(
1624 tmp_path: Path,
1625) -> None:
1626 ready = tmp_path / "ready"
1627
1628 def fail_after_promote(_path: Path) -> None:
1629 raise RuntimeError("hook boom")
1630
1631 with pytest.raises(RuntimeError, match="hook boom"):
1632 _build_ready(tmp_path, hook=fail_after_promote)
1633
1634 assert not ready.exists()
1635 assert not (tmp_path / "ready.staging").exists()
1636 assert not (tmp_path / "ready.quarantine").exists()
1637
1638 ready, failures = _build_ready(tmp_path)
1639 assert failures == []
1640 assert ready.is_dir()
1641
1642
1643def test_build_and_promote_candidate_quarantines_ready_when_final_validator_raises(
1644 tmp_path: Path, monkeypatch: pytest.MonkeyPatch
1645) -> None:
1646 ready = tmp_path / "ready"
1647
1648 def fail_final_validator(
1649 _release_dir: Path,
1650 *,
1651 expected_source_commit: str | None,
1652 schema_path: Path = checker.SCHEMA_PATH,
1653 ) -> list[checker.Failure]:
1654 raise RuntimeError("validator boom")
1655
1656 monkeypatch.setattr(checker, "_final_validate_release_dir", fail_final_validator)
1657 with pytest.raises(RuntimeError, match="validator boom"):
1658 _build_ready(tmp_path)
1659
1660 assert not ready.exists()
1661 assert not (tmp_path / "ready.staging").exists()
1662 assert not (tmp_path / "ready.quarantine").exists()
1663
1664 monkeypatch.undo()
1665 ready, failures = _build_ready(tmp_path)
1666 assert failures == []
1667 assert ready.is_dir()
1668
1669
1670def test_build_and_promote_candidate_leaves_quarantine_not_ready_when_quarantine_delete_fails(
1671 tmp_path: Path, monkeypatch: pytest.MonkeyPatch
1672) -> None:
1673 ready = tmp_path / "ready"
1674 quarantine = tmp_path / "ready.quarantine"
1675 hook_error = RuntimeError("hook boom")
1676 real_rmtree = checker.shutil.rmtree
1677
1678 def fail_after_promote(_path: Path) -> None:
1679 raise hook_error
1680
1681 def rmtree(path: Path, *args: Any, **kwargs: Any) -> None:
1682 if Path(path) == quarantine:
1683 raise OSError("delete failed")
1684 real_rmtree(path, *args, **kwargs)
1685
1686 monkeypatch.setattr(checker.shutil, "rmtree", rmtree)
1687 with pytest.raises(
1688 RuntimeError, match="release candidate quarantine could not be removed"
1689 ) as exc_info:
1690 _build_ready(tmp_path, hook=fail_after_promote)
1691
1692 assert exc_info.value.__cause__ is hook_error
1693 assert not ready.exists()
1694 assert not (tmp_path / "ready.staging").exists()
1695 assert quarantine.is_dir()
1696 assert checker.validate_release_dir(ready, expected_source_commit=VALID_COMMIT)
1697 new_ready = tmp_path / "new-ready"
1698 failures = checker.build_and_promote_candidate(
1699 _source_dist(tmp_path / "retry"),
1700 new_ready,
1701 source_commit=VALID_COMMIT,
1702 evidence_by_lane=checker.fixture_evidence_by_lane(),
1703 include_models=False,
1704 )
1705 assert failures == []
1706 assert new_ready.is_dir()
1707
1708
1709def test_fixtures_mode_runs_without_tree_artifacts() -> None:
1710 before = {path.name for path in checker.ROOT.iterdir()}
1711
1712 failures = checker.run_fixtures_mode()
1713
1714 after = {path.name for path in checker.ROOT.iterdir()}
1715 assert failures == []
1716 assert after == before