4"""Enforce the repository's single uv dependency and environment authority."""
6from __future__
import annotations
18from collections.abc
import Mapping
19from dataclasses
import dataclass
20from pathlib
import Path
22sys.path.insert(0, str(Path(__file__).resolve().parent))
25from python_lock_policy_scan
import (
26 SECONDARY_AUTHORITY_NAMES,
28 adjacent_import_closure_selftest,
29 cli_consumer_findings,
30 first_party_import_closure,
31 hil_preflight_findings,
32 hil_preflight_selftest,
37 scanner_selection_selftest,
38 unsafe_install_findings,
40from python_lock_policy_uv_cache
import uv_cache_policy_findings, uv_cache_policy_selftest
41from python_lock_policy_uv_execution
import (
42 uv_execution_policy_findings,
43 uv_execution_policy_selftest,
45from python_lock_policy_uv_runner
import (
47 execution_attack_selftest,
52ROOT = Path(__file__).resolve().parents[2]
53PYPROJECT = ROOT /
"pyproject.toml"
54MANIFEST = ROOT /
"scripts" /
"dev" /
"uv_release.json"
55BOOTSTRAP = ROOT /
"scripts" /
"dev" /
"bootstrap_uv.py"
56MIN_DIRECT_DEPENDENCIES = 15
57MIN_FIRST_PARTY_PYTHON_FILES = 250
59 "Darwin|aarch64":
"uv-aarch64-apple-darwin.tar.gz",
60 "Darwin|x86_64":
"uv-x86_64-apple-darwin.tar.gz",
61 "Windows|aarch64":
"uv-aarch64-pc-windows-msvc.zip",
62 "Windows|x86_64":
"uv-x86_64-pc-windows-msvc.zip",
63 "Linux|aarch64|gnu":
"uv-aarch64-unknown-linux-gnu.tar.gz",
64 "Linux|aarch64|musl":
"uv-aarch64-unknown-linux-musl.tar.gz",
65 "Linux|x86_64|gnu":
"uv-x86_64-unknown-linux-gnu.tar.gz",
66 "Linux|x86_64|musl":
"uv-x86_64-unknown-linux-musl.tar.gz",
69 "k3s": Path(
"infra/ansible/roles/k3s_node/files/requirements.lock"),
70 "hil": Path(
"infra/ansible/roles/hil_bench/files/requirements.lock"),
72GALAXY_MANIFEST = Path(
"infra/ansible/requirements.yml")
73INTERPRETER_IMPORT_ROOTS: frozenset[str] = frozenset({
"__main__"})
76@dataclass(frozen=True)
78 """Describe one direct dependency's owning group and repository consumer."""
85@dataclass(frozen=True)
87 """Bind consumer proofs, import mappings, and a non-vacuity scan floor."""
89 proofs: Mapping[str, ConsumerProof]
90 external_imports: Mapping[str, str]
91 minimum_python_files: int
92 cli_census: bool =
True
95CONSUMER_PROOF_ROWS = {
96 "pillow": (
"hil",
"scripts/hil/camera_livestream.sh",
"from PIL import Image"),
99 "infra/network/fg_bringup.py",
100 'importlib.import_module("serial")',
102 "pyusb": (
"hil",
"scripts/hil/usb/libusb_bench.py",
"import usb.core"),
105 "scripts/hil/hil_secrets.py",
106 "from dotenv import load_dotenv",
110 "scripts/hil/tapo_control.py",
111 "from kasa import Credentials",
113 "pyyaml": (
"runtime",
"scripts/ci/check_ci_parity.py",
"import yaml"),
114 "cmakelang": (
"dev",
"scripts/ci/gates/lint.sh",
"cmake-format"),
115 "gcovr": (
"dev",
"scripts/ci/gates/tests.sh",
"require_cmd gcovr"),
118 "scripts/ci/gates/checks.sh",
119 "require_python_mod clang.cindex",
121 "ruff": (
"dev",
"scripts/ci/gates/lint.sh",
"require_tool_versions ruff"),
122 "yamllint": (
"dev",
"scripts/ci/gates/lint.sh",
"require_cmd yamllint"),
123 "ansible-core": (
"infra",
"scripts/dev/infra.sh",
"ansible-playbook"),
126 "infra/ansible/group_vars/all.example.yml",
127 "community.hashi_vault",
131 "infra/ansible/roles/k3s_node/tasks/main.yml",
134 "ethos-u-vela": (
"vela",
"tools/vela/src/vela_gen.py",
'shutil.which("vela")'),
137 package: ConsumerProof(*values)
for package, values
in CONSUMER_PROOF_ROWS.items()
142 "dotenv":
"python-dotenv",
143 "kasa":
"python-kasa",
144 "serial":
"pyserial",
148CONSUMER_CATALOG = ConsumerCatalog(CONSUMER_PROOFS, EXTERNAL_IMPORTS, MIN_FIRST_PARTY_PYTHON_FILES)
151def canonical(name: str) -> str:
152 """Canonicalize one Python distribution name."""
153 return re.sub(
r"[-_.]+",
"-", name).lower()
156def parse_dependency_entry(entry: object) -> tuple[str |
None, str]:
157 """Return a canonical pin/version or an included group marker."""
158 if isinstance(entry, dict):
159 if set(entry) != {
"include-group"}:
160 message = f
"unsupported dependency-group record: {entry}"
161 raise ValueError(message)
162 included = entry[
"include-group"]
163 if not isinstance(included, str):
164 message = f
"included dependency group must be a string: {entry}"
165 raise TypeError(message)
166 return None, included
167 if not isinstance(entry, str):
168 message = f
"dependency entry must be a string: {entry!r}"
169 raise TypeError(message)
170 match = re.fullmatch(
r"([A-Za-z0-9][A-Za-z0-9._-]*)==([0-9][A-Za-z0-9.!+_-]*)", entry)
172 message = f
"direct dependency is not exactly pinned: {entry!r}"
173 raise ValueError(message)
174 name, version = match.groups()
175 return canonical(name), version
178def direct_declarations(path: Path) -> tuple[dict[str, str], dict[str, str]]:
179 """Return exact pins and owning groups, rejecting duplicate or loose entries."""
180 document = tomllib.loads(path.read_text(encoding=
"utf-8"))
181 groups = document.get(
"dependency-groups")
182 if not isinstance(groups, dict):
183 message =
"missing dependency-groups table"
184 raise TypeError(message)
185 pins: dict[str, str] = {}
186 owners: dict[str, str] = {}
187 includes: set[str] = set()
188 for group, entries
in groups.items():
189 if not isinstance(group, str)
or not isinstance(entries, list):
190 message =
"dependency group must have a string name and list value"
191 raise TypeError(message)
192 for entry
in entries:
193 package, value = parse_dependency_entry(entry)
196 elif package
in pins:
197 message = f
"duplicate direct dependency: {package}"
198 raise ValueError(message)
200 pins[package] = value
201 owners[package] = group
202 missing_groups = includes - set(groups)
204 message = f
"included dependency groups do not exist: {sorted(missing_groups)}"
205 raise ValueError(message)
206 if len(pins) < MIN_DIRECT_DEPENDENCIES:
207 message = f
"only {len(pins)} direct dependencies; policy floor is stale"
208 raise ValueError(message)
212def direct_pins(path: Path) -> dict[str, str]:
213 """Return direct exact pins for callers that do not need owning groups."""
214 return direct_declarations(path)[0]
217def imported_roots(path: Path) -> tuple[set[str], list[str]]:
218 """Return absolute import roots, including literal dynamic imports."""
219 source, error = read_authored_text(path,
"Python import policy input")
220 if error
is not None:
221 return set(), [error]
223 tree = ast.parse(source
or "", filename=str(path))
224 except SyntaxError
as error:
225 return set(), [f
"{path}: cannot inspect Python imports: {error}"]
226 roots: set[str] = set()
227 importlib_modules = {
"importlib"}
228 import_functions = {
"__import__"}
229 for node
in ast.walk(tree):
230 if isinstance(node, ast.Import):
231 roots.update(alias.name.partition(
".")[0]
for alias
in node.names)
232 importlib_modules.update(
233 alias.asname
or alias.name
for alias
in node.names
if alias.name ==
"importlib"
235 elif isinstance(node, ast.ImportFrom)
and node.level == 0
and node.module:
236 roots.add(node.module.partition(
".")[0])
237 if node.module ==
"importlib":
238 import_functions.update(
239 alias.asname
or alias.name
240 for alias
in node.names
241 if alias.name ==
"import_module"
243 for node
in ast.walk(tree):
244 if isinstance(node, ast.Call)
and node.args:
246 is_dynamic = (isinstance(function, ast.Name)
and function.id
in import_functions)
or (
247 isinstance(function, ast.Attribute)
248 and isinstance(function.value, ast.Name)
249 and function.value.id
in importlib_modules
250 and function.attr ==
"import_module"
252 argument = node.args[0]
255 and isinstance(argument, ast.Constant)
256 and isinstance(argument.value, str)
258 roots.add(argument.value.partition(
".")[0])
262def import_consumer_findings(
264 pins: Mapping[str, str],
265 catalog: ConsumerCatalog,
267 """Find unclassified imports and imports without direct dependency proofs."""
268 findings: list[str] = []
269 sources, closure_errors = first_party_import_closure(
270 root, python_source_paths(root), imported_roots
272 findings.extend(closure_errors)
273 if len(sources) < catalog.minimum_python_files:
275 f
"only {len(sources)} first-party Python files; import-consumer scan floor is stale"
277 local_roots = {path.stem
for path
in sources}
278 local_roots.update(path.parent.name
for path
in sources
if path.name ==
"__init__.py")
279 local_roots.update(path.relative_to(root).parts[0]
for path
in sources)
280 used_packages: set[str] = set()
282 imported, errors = imported_roots(path)
283 findings.extend(errors)
284 for root_name
in imported:
285 package = catalog.external_imports.get(root_name)
286 if package
is not None:
287 used_packages.add(package)
289 root_name
not in INTERPRETER_IMPORT_ROOTS
290 and root_name
not in sys.stdlib_module_names
291 and root_name
not in local_roots
294 f
"{path.relative_to(root)}: unclassified third-party import root {root_name!r}"
296 for package
in sorted(used_packages):
297 if package
not in pins:
298 findings.append(f
"imported dependency {package} is not directly pinned")
299 if package
not in catalog.proofs:
300 findings.append(f
"imported dependency {package} has no consumer/group proof")
301 unused_mappings = set(catalog.external_imports.values()) - used_packages
303 findings.append(f
"external import map has no live imports: {sorted(unused_mappings)}")
304 orphan_mappings = set(catalog.external_imports.values()) - set(catalog.proofs)
306 findings.append(f
"external import map has no consumer proofs: {sorted(orphan_mappings)}")
312 pins: dict[str, str],
313 owners: dict[str, str],
314 catalog: ConsumerCatalog = CONSUMER_CATALOG,
316 """Prove dependency pins, groups, consumers, and Python imports in both directions."""
317 findings: list[str] = []
318 if set(pins) != set(catalog.proofs):
320 f
"direct dependency/consumer map differs: pins={sorted(pins)}, "
321 f
"consumers={sorted(catalog.proofs)}"
323 if set(pins) != set(owners):
324 findings.append(
"direct dependency owner map differs from direct pins")
325 for package, proof
in catalog.proofs.items():
326 if owners.get(package) != proof.group:
328 f
"{package}: expected direct group {proof.group}, found {owners.get(package)!r}"
330 path = root / proof.relative
331 source, error = read_authored_text(path,
"dependency consumer proof")
332 if error
is not None:
333 findings.append(error)
334 elif proof.needle
not in (source
or ""):
335 findings.append(f
"{package}: consumer proof missing from {proof.relative}")
336 findings.extend(import_consumer_findings(root, pins, catalog))
337 if catalog.cli_census:
338 findings.extend(cli_consumer_findings(root, pins))
342def check_manifest(path: Path) -> list[str]:
343 """Validate the one official uv version/checksum platform manifest."""
344 findings: list[str] = []
345 document = json.loads(path.read_text(encoding=
"ascii"))
346 if document.get(
"schema") != 1
or document.get(
"repository") !=
"astral-sh/uv":
347 findings.append(
"uv release manifest identity/schema is invalid")
348 version = document.get(
"version")
349 if not isinstance(version, str)
or re.fullmatch(
r"[0-9]+\.[0-9]+\.[0-9]+", version)
is None:
350 findings.append(
"uv release version is not exact semver")
351 assets = document.get(
"assets")
352 if not isinstance(assets, dict)
or set(assets) != set(EXPECTED_ASSETS):
353 return [*findings,
"uv release platform matrix is not exact"]
354 for key, expected_name
in EXPECTED_ASSETS.items():
355 record = assets.get(key)
356 if not isinstance(record, dict)
or set(record) != {
"name",
"sha256"}:
357 findings.append(f
"{key}: malformed uv asset record")
359 if record[
"name"] != expected_name:
360 findings.append(f
"{key}: expected asset name {expected_name}")
361 digest = record[
"sha256"]
362 if not isinstance(digest, str)
or re.fullmatch(
r"[0-9a-f]{64}", digest)
is None:
363 findings.append(f
"{key}: invalid uv asset SHA-256")
369 environment: Mapping[str, str] |
None =
None,
370 executable: str |
None =
None,
371) -> tuple[Path, ...]:
372 """Return explicit authenticated-cache locations for source and snapshots."""
373 env = os.environ
if environment
is None else environment
374 candidates = [root /
".tools" /
"uv"]
375 configured = env.get(
"RA8_UV_CACHE_ROOT")
377 candidates.append(Path(configured))
378 history_root = env.get(
"RA8_CI_HISTORY_REPO")
380 candidates.append(Path(history_root) /
".tools" /
"uv")
381 if env.get(
"RA8_STAGED_HOOK_SNAPSHOT") ==
"1":
383 Path(executable
or "/usr/bin/python3"),
384 *(Path(item)
for item
in env[
"PATH"].split(
":")),
386 for source_path
in source_paths:
387 candidate = source_path.absolute()
388 bin_dir = candidate
if candidate.name ==
"bin" else candidate.parent
389 if bin_dir.name ==
"bin" and bin_dir.parent.name ==
".venv":
390 candidates.append(bin_dir.parents[1] /
".tools" /
"uv")
391 return tuple(dict.fromkeys(path.absolute()
for path
in candidates))
394def cache_routing_selftest(root: Path) -> list[str]:
395 """Prove snapshots and managed environments retain an explicit cache route."""
396 failures: list[str] = []
397 local_cache = root /
".tools" /
"uv"
398 source_root = root /
"source"
399 snapshot_root = root /
"snapshot"
400 staged = uv_cache_roots(
403 "RA8_STAGED_HOOK_SNAPSHOT":
"1",
404 "PATH": f
"{source_root / '.venv' / 'bin'}:/usr/bin",
408 if staged != (snapshot_root /
".tools" /
"uv", source_root /
".tools" /
"uv"):
409 failures.append(f
"staged cache routing failed: {staged}")
410 configured = uv_cache_roots(
413 "RA8_UV_CACHE_ROOT": str(root /
"configured"),
414 "RA8_CI_HISTORY_REPO": str(root /
"history"),
420 root /
"history" /
".tools" /
"uv",
422 failures.append(f
"explicit cache routing failed: {configured}")
426def consumer_selftest(root: Path) -> list[str]:
427 """Prove consumer and import coverage detects omissions and wrong groups."""
428 failures: list[str] = []
429 root.mkdir(parents=
True, exist_ok=
True)
430 source = root /
"consumer.py"
433 "import importlib as loader\n"
435 "loader.import_module('yaml')\n",
438 pins = {
"pyyaml":
"6.0.3"}
439 owners = {
"pyyaml":
"runtime"}
440 proofs = {
"pyyaml": ConsumerProof(
"runtime",
"consumer.py",
"loader.import_module('yaml')")}
441 catalog = ConsumerCatalog(proofs, {
"yaml":
"pyyaml"}, 1, cli_census=
False)
442 if check_consumers(root, pins, owners, catalog):
443 failures.append(
"valid consumer/group/import fixture failed")
444 if not check_consumers(root, pins, {
"pyyaml":
"hil"}, catalog):
445 failures.append(
"wrong direct dependency group passed")
446 omitted_catalog = ConsumerCatalog({}, {
"yaml":
"pyyaml"}, 1, cli_census=
False)
447 if not check_consumers(root, {}, {}, omitted_catalog):
448 failures.append(
"dependency omitted from both pins and proofs passed")
449 if not check_consumers(root, {}, {}, ConsumerCatalog({}, {}, 1, cli_census=
False)):
450 failures.append(
"unclassified imported dependency passed")
451 source.write_text(
"import pathlib\n", encoding=
"utf-8")
452 if not check_consumers(root, pins, owners, catalog):
453 failures.append(
"consumer proof with no matching source passed")
454 source.write_bytes(b
"# invalid utf-8: \xa3\n")
455 if not any(
"not valid UTF-8" in item
for item
in check_consumers(root, pins, owners, catalog)):
456 failures.append(
"non-UTF-8 Python consumer did not fail clearly")
457 failures.extend(adjacent_import_closure_selftest(root, source, imported_roots))
461def cli_consumer_selftest(root: Path) -> list[str]:
462 """Prove every CLI-only package survives an omit-pin/owner/proof attack."""
463 failures: list[str] = []
464 root.mkdir(parents=
True, exist_ok=
True)
465 (root /
"consumers.sh").write_text(
467 "cmake-format --version\n"
469 "yamllint --version\n"
470 "ansible-playbook --version\n",
473 python = root /
"consumer.py"
475 'import shutil\nfilesystem = shutil\nlocator = filesystem.which\ncommand = "vela"\n'
476 "locator(command)\n",
480 "ansible-core":
"infra",
482 "ethos-u-vela":
"vela",
488 "ansible-core":
"ansible-playbook --version",
489 "cmakelang":
"cmake-format --version",
490 "ethos-u-vela":
"locator(command)",
491 "gcovr":
"gcovr --version",
492 "ruff":
"ruff --version",
493 "yamllint":
"yamllint --version",
496 package: ConsumerProof(
498 "consumer.py" if package ==
"ethos-u-vela" else "consumers.sh",
501 for package, group
in groups.items()
503 pins = dict.fromkeys(groups,
"1.0")
504 catalog = ConsumerCatalog(proofs, {}, 1)
505 if check_consumers(root, pins, groups, catalog):
506 failures.append(
"valid independent CLI consumer census failed")
507 for package
in groups:
508 reduced_pins = {name: pin
for name, pin
in pins.items()
if name != package}
509 reduced_owners = {name: group
for name, group
in groups.items()
if name != package}
510 reduced_proofs = {name: proof
for name, proof
in proofs.items()
if name != package}
511 findings = check_consumers(
515 ConsumerCatalog(reduced_proofs, {}, 1),
517 expected = f
"CLI dependency {package} is invoked but not directly pinned"
518 if expected
not in findings:
519 failures.append(f
"CLI omit-pin/owner/proof attack passed: {package}")
523def authority_selftest(root: Path) -> list[str]:
524 """Prove allowed derived/vendor metadata is quiet and parallel authorities fail."""
525 failures: list[str] = []
526 root.mkdir(parents=
True, exist_ok=
True)
527 (root /
"pyproject.toml").write_text(
"[dependency-groups]\n", encoding=
"utf-8")
528 (root /
"uv.lock").write_text(
"version = 1\n", encoding=
"utf-8")
529 (root / GALAXY_MANIFEST).parent.mkdir(parents=
True, exist_ok=
True)
530 (root / GALAXY_MANIFEST).write_text(
"collections: []\n", encoding=
"utf-8")
531 for relative
in EXPORTS.values():
532 path = root / relative
533 path.parent.mkdir(parents=
True, exist_ok=
True)
534 path.write_text(
"# derived\n", encoding=
"utf-8")
535 vendor = root / VENDOR_BOUNDARIES[0]
536 vendor.mkdir(parents=
True, exist_ok=
True)
541 *sorted(SECONDARY_AUTHORITY_NAMES),
543 for name
in vendor_names:
544 (vendor / name).write_text(
"# upstream\n", encoding=
"utf-8")
545 prose = root /
"docs" /
"product-requirements" /
"notes.txt"
546 prose.parent.mkdir(parents=
True, exist_ok=
True)
547 prose.write_text(
"Operational requirements are described in prose.\n", encoding=
"utf-8")
548 constraints_prose = root /
"docs" /
"product-constraints" /
"notes.txt"
549 constraints_prose.parent.mkdir(parents=
True, exist_ok=
True)
550 constraints_prose.write_text(
"Product constraints are described in prose.\n", encoding=
"utf-8")
551 data = root /
"data" /
"requirements.json"
552 data.parent.mkdir(parents=
True, exist_ok=
True)
553 data.write_text(
'{"labels": ["alpha", "beta"]}\n', encoding=
"utf-8")
554 constraints_data = root /
"data" /
"constraints.json"
555 constraints_data.write_text(
'{"limits": ["alpha", "beta"]}\n', encoding=
"utf-8")
556 if requirement_findings(root):
557 failures.append(
"allowed derived, vendor, prose, or data metadata failed")
560 (root /
"requirements.txt",
"split==1\n"),
561 (root /
"constraints-dev.txt",
"split==1\n"),
562 *((root / name,
"# split authority\n")
for name
in sorted(SECONDARY_AUTHORITY_NAMES)),
563 (root /
"tools" /
"nested" /
"pyproject.toml",
"# split authority\n"),
564 (root /
"tools" /
"nested" /
"uv.lock",
"# split authority\n"),
565 (root /
"config" /
"requirements" /
"dev.txt",
"nested-package\n"),
566 (root /
"config" /
"constraints" /
"dev.txt",
"nested-package\n"),
568 for stale, content
in stale_paths:
569 stale.parent.mkdir(parents=
True, exist_ok=
True)
570 stale.write_text(content, encoding=
"utf-8")
571 if not any(str(stale.relative_to(root))
in item
for item
in requirement_findings(root)):
572 failures.append(f
"secondary dependency authority passed: {stale.relative_to(root)}")
577def unsafe_installer_fixtures() -> dict[str, str]:
578 """Return adversarial installer snippets that the policy must reject."""
581 "import subprocess, sys\n"
582 "subprocess.run([sys.executable, '-m', 'pip', 'install', 'rogue'], check=True)\n"
585 "import subprocess\n"
586 "subprocess.run(['/opt/bin/uv', 'pip', 'install', 'rogue'], check=True)\n"
589 "import sys\nfrom subprocess import run as launch\n"
590 "launch([sys.executable, '-m', 'pip', 'install', 'rogue'], check=True)\n"
592 "alias-keyword.py": (
593 "import subprocess as runner, sys as runtime\n"
595 "args=[runtime.executable, '-m', 'pip', 'install', 'rogue'], check=True)\n"
597 "from-alias-keyword.py": (
598 "from subprocess import run as launch\n"
599 "from sys import executable as interpreter\n"
600 "launch(args=[interpreter, '-m', 'pip', 'install', 'rogue'], check=True)\n"
603 "import os as host_os\nhost_os.system('python3.11 -m pip3.11 install rogue')\n"
605 "assigned-argv.py": (
606 "import subprocess, sys\n"
607 "command = [sys.executable, '-m', 'pip', 'install', 'rogue']\n"
608 "subprocess.run(command, check=True)\n"
610 "assigned-launcher.py": (
611 "import subprocess, sys\nprocess = subprocess\nlauncher = process.run\n"
612 "interpreter = sys.executable\n"
613 "launcher([interpreter, '-m', 'pip', 'install', 'rogue'], check=True)\n"
615 "assigned-tuple.py": (
616 "from subprocess import run\ncommand = ('uvx', 'rogue')\nrun(command, check=True)\n"
618 "assigned-shell.py": (
619 "import os\ncommand = 'python3 -m pip install rogue'\nos.system(command)\n"
621 "concatenated-shell.py": (
"import os\nos.system('python3 -m pip ' + 'install rogue')\n"),
622 "formatted-shell.py": (
623 "import subprocess\npackage = 'rogue'\n"
624 "subprocess.run(f'python3 -m pip install {package}', shell=True)\n"
626 "shell.sh":
"python3 -m pip install rogue\n",
627 "uvx.sh":
"uvx rogue\n",
628 "windows.cmd":
"py.exe -m pip.exe install rogue\n",
632def unsafe_installer_selftest(root: Path) -> list[str]:
633 """Prove shell and Python process installers fail while non-installs remain valid."""
634 failures: list[str] = []
635 root.mkdir(parents=
True, exist_ok=
True)
636 safe = root /
"safe.py"
638 "import subprocess as runner, sys as runtime\n"
639 "command = [runtime.executable, '-m', 'pip', 'check']\n"
640 "runner.run(args=command, check=True)\n",
643 if unsafe_install_findings(root):
644 failures.append(
"safe Python dependency graph check was rejected")
645 for name, content
in unsafe_installer_fixtures().items():
646 fixture = root / name
647 fixture.write_text(content, encoding=
"utf-8")
648 if not any(name
in item
for item
in unsafe_install_findings(root)):
649 failures.append(f
"unsafe installer passed: {name}")
651 vendor = root /
"libs" /
"third_party" /
"upstream" /
"install.sh"
652 vendor.parent.mkdir(parents=
True, exist_ok=
True)
653 vendor.write_text(
"pip install upstream-build-helper\n", encoding=
"utf-8")
654 if unsafe_install_findings(root):
655 failures.append(
"vendored installer was treated as first-party policy")
659def export_freshness_selftest(uv: AuthenticatedUv) -> list[str]:
660 """Prove current lock/exports pass and mutations fail with authenticated uv."""
661 failures: list[str] = []
662 with tempfile.TemporaryDirectory(prefix=
"ra8-uv-export-test-")
as raw:
664 shutil.copy2(PYPROJECT, fixture /
"pyproject.toml")
665 shutil.copy2(ROOT /
"uv.lock", fixture /
"uv.lock")
666 for relative
in EXPORTS.values():
667 target = fixture / relative
668 target.parent.mkdir(parents=
True, exist_ok=
True)
669 shutil.copy2(ROOT / relative, target)
670 if export_findings(fixture, EXPORTS, uv):
671 failures.append(
"current lock/export freshness fixture failed")
673 stale_relative = next(iter(EXPORTS.values()))
674 stale_export = fixture / stale_relative
675 stale_export.write_text(
676 stale_export.read_text(encoding=
"utf-8") +
"# stale\n", encoding=
"utf-8"
679 "is stale versus uv.lock" in item
for item
in export_findings(fixture, EXPORTS, uv)
681 failures.append(
"mutated derived export passed freshness check")
682 shutil.copy2(ROOT / stale_relative, stale_export)
684 project = fixture /
"pyproject.toml"
685 content = project.read_text(encoding=
"utf-8")
686 project.write_text(content.replace(
"PyYAML==6.0.3",
"PyYAML==6.0.2"), encoding=
"utf-8")
687 if not any(
"uv.lock is stale" in item
for item
in export_findings(fixture, EXPORTS, uv)):
688 failures.append(
"mutated project passed lock freshness check")
692def selftest() -> int:
693 """Prove every lock-policy boundary detects valid and invalid fixtures."""
694 with tempfile.TemporaryDirectory(prefix=
"ra8-python-policy-test-")
as raw:
696 project = root /
"pyproject.toml"
697 failures: list[str] = []
698 entries = [f
"package-{index}==1.0.0" for index
in range(MIN_DIRECT_DEPENDENCIES)]
700 "[dependency-groups]\ndev = [" +
",".join(repr(item)
for item
in entries) +
"]\n",
703 pins, owners = direct_declarations(project)
704 if len(pins) != MIN_DIRECT_DEPENDENCIES
or set(owners.values()) != {
"dev"}:
705 failures.append(
"valid direct pins failed")
706 for extra
in (entries[0],
"package-0==2.0.0",
"loose>=1"):
708 "[dependency-groups]\ndev = ["
709 +
",".join(repr(item)
for item
in [*entries, extra])
718 failures.append(f
"invalid direct pin passed: {extra}")
719 manifest = json.loads(MANIFEST.read_text(encoding=
"ascii"))
720 fixture = root /
"uv.json"
721 fixture.write_text(json.dumps(manifest), encoding=
"ascii")
722 if check_manifest(fixture):
723 failures.append(
"valid uv manifest failed")
724 manifest[
"assets"].pop(next(iter(manifest[
"assets"])))
725 fixture.write_text(json.dumps(manifest), encoding=
"ascii")
726 if not check_manifest(fixture):
727 failures.append(
"incomplete uv matrix passed")
728 failures.extend(consumer_selftest(root /
"consumers"))
729 failures.extend(cli_consumer_selftest(root /
"cli-consumers"))
730 failures.extend(authority_selftest(root /
"authorities"))
731 failures.extend(unsafe_installer_selftest(root /
"installers"))
732 failures.extend(scanner_selection_selftest(root /
"selection"))
733 failures.extend(cache_routing_selftest(root))
734 failures.extend(uv_cache_policy_selftest(ROOT))
735 failures.extend(uv_execution_policy_selftest(ROOT))
736 failures.extend(hil_preflight_selftest(ROOT))
737 live_manifest = json.loads(MANIFEST.read_text(encoding=
"ascii"))
738 version = live_manifest.get(
"version")
739 if not isinstance(version, str):
740 failures.append(
"live uv manifest has no version")
742 uv = find_uv(ROOT, version, MANIFEST, uv_cache_roots(ROOT))
743 failures.extend(export_freshness_selftest(uv))
744 failures.extend(execution_attack_selftest(BOOTSTRAP, EXPORTS))
746 print(
"selftest: " +
"; ".join(failures), file=sys.stderr)
748 print(
"check_python_lock_policy.py --selftest: PASS")
753 """Run the offline policy or its synthetic selftest."""
754 parser = argparse.ArgumentParser(description=__doc__)
755 parser.add_argument(
"--selftest", action=
"store_true")
756 args = parser.parse_args()
760 pins, owners = direct_declarations(PYPROJECT)
761 manifest = json.loads(MANIFEST.read_text(encoding=
"ascii"))
762 version = manifest.get(
"version")
763 if not isinstance(version, str):
764 return fatal(
"uv manifest version is malformed")
765 uv = find_uv(ROOT, version, MANIFEST, uv_cache_roots(ROOT))
767 *check_consumers(ROOT, pins, owners),
768 *check_manifest(MANIFEST),
769 *requirement_findings(ROOT),
770 *unsafe_install_findings(ROOT),
771 *export_findings(ROOT, EXPORTS, uv),
772 *hil_preflight_findings(load_hil_tasks(ROOT)),
773 *uv_cache_policy_findings(ROOT),
774 *uv_execution_policy_findings(ROOT),
780 json.JSONDecodeError,
782 subprocess.SubprocessError,
784 print(f
"check_python_lock_policy.py: FATAL: {error}", file=sys.stderr)
787 print(
"\n".join(findings), file=sys.stderr)
789 print(
"Python dependencies, uv bootstrap, and managed exports match one lock")
793def fatal(message: str) -> int:
794 """Report a fatal policy-input error."""
795 print(f
"check_python_lock_policy.py: FATAL: {message}", file=sys.stderr)
799if __name__ ==
"__main__":
800 raise SystemExit(
main())
void main(void)
The application entry point Reset_Handler hands control to.