[verified] feat: harden llama.cpp provenance workspace
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
"""Offline guards for DGR-004's pinned llama.cpp dependency boundary."""
|
||||
"""Offline guards for DGR-027's pinned llama.cpp dependency boundary."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
import pathlib
|
||||
import subprocess
|
||||
@@ -33,6 +34,10 @@ def test_lock_and_patch_manifest_are_self_consistent_and_exact() -> None:
|
||||
|
||||
assert commit == lock["commit"]
|
||||
assert len(commit) == 40
|
||||
assert lock["retrieval"]["method"] == "git-clone-detached-commit"
|
||||
assert lock["retrieval"]["workspace"] == "build/llama.cpp"
|
||||
assert lock["expected_source"]["git_tree"] == lock["commit_tree"]
|
||||
assert lock["upstream_license"] == "MIT"
|
||||
assert patches == lock["patch_series"]
|
||||
assert patches == sorted(patches)
|
||||
assert patches
|
||||
@@ -42,6 +47,188 @@ def test_lock_and_patch_manifest_are_self_consistent_and_exact() -> None:
|
||||
assert "Subject: [PATCH" in patch.read_text()
|
||||
|
||||
|
||||
def test_fetch_refuses_a_workspace_outside_the_ignored_build_root(tmp_path: pathlib.Path) -> None:
|
||||
completed = subprocess.run(
|
||||
[sys.executable, str(SCRIPT), "fetch", "--workspace", str(tmp_path / "llama.cpp")],
|
||||
cwd=ROOT,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
|
||||
assert completed.returncode == 2
|
||||
assert "--workspace must equal" in completed.stderr
|
||||
|
||||
|
||||
def test_workspace_refuses_a_symlinked_build_ancestor(tmp_path: pathlib.Path, monkeypatch) -> None:
|
||||
spec = importlib.util.spec_from_file_location("llama_cpp_dependency_symlink", SCRIPT)
|
||||
assert spec and spec.loader
|
||||
dependency = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(dependency)
|
||||
root = tmp_path / "repo"
|
||||
outside = tmp_path / "outside"
|
||||
root.mkdir()
|
||||
outside.mkdir()
|
||||
(root / "build").symlink_to(outside, target_is_directory=True)
|
||||
monkeypatch.setattr(dependency, "ROOT", root)
|
||||
|
||||
try:
|
||||
dependency._workspace_source(
|
||||
root / "build/llama.cpp",
|
||||
{"retrieval": {"workspace": "build/llama.cpp"}},
|
||||
)
|
||||
except dependency.DependencyError as error:
|
||||
assert "may not traverse a symlink" in str(error)
|
||||
else:
|
||||
raise AssertionError("symlinked build ancestor must be refused")
|
||||
|
||||
(root / "build").unlink()
|
||||
workspace = root / "build/llama.cpp"
|
||||
workspace.mkdir(parents=True)
|
||||
(workspace / "source").symlink_to(outside, target_is_directory=True)
|
||||
try:
|
||||
dependency._workspace_source(
|
||||
workspace,
|
||||
{"retrieval": {"workspace": "build/llama.cpp"}},
|
||||
)
|
||||
except dependency.DependencyError as error:
|
||||
assert "source checkout may not be a symlink" in str(error)
|
||||
else:
|
||||
raise AssertionError("symlinked source checkout must be refused")
|
||||
|
||||
|
||||
def test_fetch_refuses_a_branch_or_repository_override() -> None:
|
||||
completed = subprocess.run(
|
||||
[sys.executable, str(SCRIPT), "fetch", "--source-repository", "main"],
|
||||
cwd=ROOT,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
|
||||
assert completed.returncode == 2
|
||||
assert "unrecognized arguments" in completed.stderr
|
||||
|
||||
|
||||
def test_fetch_reuses_only_a_verified_cached_tree_offline(
|
||||
tmp_path: pathlib.Path, monkeypatch
|
||||
) -> None:
|
||||
spec = importlib.util.spec_from_file_location("llama_cpp_dependency", SCRIPT)
|
||||
assert spec and spec.loader
|
||||
dependency = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(dependency)
|
||||
|
||||
root = tmp_path / "repo"
|
||||
source = root / "build/llama.cpp/source"
|
||||
upstream = tmp_path / "upstream"
|
||||
upstream.mkdir()
|
||||
subprocess.run(["git", "init", "-q", str(upstream)], check=True)
|
||||
subprocess.run(["git", "-C", str(upstream), "config", "user.email", "test@example.invalid"], check=True)
|
||||
subprocess.run(["git", "-C", str(upstream), "config", "user.name", "test"], check=True)
|
||||
(upstream / "CMakeLists.txt").write_text("cmake_minimum_required(VERSION 3.14)\n")
|
||||
(upstream / "LICENSE").write_text("MIT\n")
|
||||
(upstream / "tool.sh").write_text("#!/bin/sh\nexit 0\n")
|
||||
(upstream / "tool.sh").chmod(0o755)
|
||||
subprocess.run(["git", "-C", str(upstream), "add", "."], check=True)
|
||||
subprocess.run(["git", "-C", str(upstream), "commit", "-qm", "fixture"], check=True)
|
||||
commit = subprocess.run(
|
||||
["git", "-C", str(upstream), "rev-parse", "HEAD"], check=True, capture_output=True, text=True
|
||||
).stdout.strip()
|
||||
tree = subprocess.run(
|
||||
["git", "-C", str(upstream), "rev-parse", "HEAD^{tree}"], check=True, capture_output=True, text=True
|
||||
).stdout.strip()
|
||||
blob = subprocess.run(
|
||||
["git", "-C", str(upstream), "rev-parse", "HEAD:CMakeLists.txt"],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
).stdout.strip()
|
||||
source.parent.mkdir(parents=True)
|
||||
subprocess.run(["git", "clone", "-q", str(upstream), str(source)], check=True)
|
||||
|
||||
llama_dir = root / "packages/node/native/llama"
|
||||
patch_dir = llama_dir / "patches"
|
||||
patch_dir.mkdir(parents=True)
|
||||
(llama_dir / "UPSTREAM_COMMIT").write_text(f"{commit}\n")
|
||||
(patch_dir / "series").write_text("0001-fixture.patch\n")
|
||||
patch = patch_dir / "0001-fixture.patch"
|
||||
patch.write_text("fixture patch\n")
|
||||
(patch_dir / "SHA256SUMS").write_text(f"{_sha256(patch)} {patch.name}\n")
|
||||
(llama_dir / "UPSTREAM_LOCK.json").write_text(json.dumps({
|
||||
"upstream": str(upstream),
|
||||
"commit": commit,
|
||||
"commit_tree": tree,
|
||||
"expected_source": {"git_tree": tree},
|
||||
"retrieval": {"method": "git-clone-detached-commit", "workspace": "build/llama.cpp"},
|
||||
"patched_tree": tree,
|
||||
"patch_series": [patch.name],
|
||||
"required_upstream_blobs": {"CMakeLists.txt": blob},
|
||||
"patched_paths": [],
|
||||
"build": {},
|
||||
"upstream_license": "MIT",
|
||||
}))
|
||||
monkeypatch.setattr(dependency, "ROOT", root)
|
||||
monkeypatch.setattr(dependency, "LLAMA_DIR", llama_dir)
|
||||
monkeypatch.setattr(dependency, "LOCK_PATH", llama_dir / "UPSTREAM_LOCK.json")
|
||||
monkeypatch.setattr(dependency, "PATCH_DIR", patch_dir)
|
||||
|
||||
try:
|
||||
dependency.fetch(root / "build/llama.cpp")
|
||||
except dependency.DependencyError as error:
|
||||
assert "detached HEAD" in str(error)
|
||||
else:
|
||||
raise AssertionError("attached branch cache must be refused")
|
||||
subprocess.run(["git", "-C", str(source), "checkout", "--detach", "-q", commit], check=True)
|
||||
assert dependency.fetch(root / "build/llama.cpp") == source
|
||||
|
||||
tracked_path = source / "CMakeLists.txt"
|
||||
for flag, clear_flag in (
|
||||
("--assume-unchanged", "--no-assume-unchanged"),
|
||||
("--skip-worktree", "--no-skip-worktree"),
|
||||
):
|
||||
subprocess.run(["git", "-C", str(source), "update-index", flag, "CMakeLists.txt"], check=True)
|
||||
tracked_path.write_text("injected tracked build input\n")
|
||||
try:
|
||||
dependency.fetch(root / "build/llama.cpp")
|
||||
except dependency.DependencyError as error:
|
||||
assert "tracked source content differs" in str(error)
|
||||
else:
|
||||
raise AssertionError(f"tracked cache injection hidden by {flag} must be refused")
|
||||
subprocess.run(["git", "-C", str(source), "update-index", clear_flag, "CMakeLists.txt"], check=True)
|
||||
subprocess.run(["git", "-C", str(source), "checkout", "--", "CMakeLists.txt"], check=True)
|
||||
|
||||
executable_path = source / "tool.sh"
|
||||
for flag, clear_flag in (
|
||||
("--assume-unchanged", "--no-assume-unchanged"),
|
||||
("--skip-worktree", "--no-skip-worktree"),
|
||||
):
|
||||
subprocess.run(["git", "-C", str(source), "update-index", flag, "tool.sh"], check=True)
|
||||
executable_path.chmod(0o644)
|
||||
try:
|
||||
dependency.fetch(root / "build/llama.cpp")
|
||||
except dependency.DependencyError as error:
|
||||
assert "executable mode differs" in str(error)
|
||||
else:
|
||||
raise AssertionError(f"tracked mode change hidden by {flag} must be refused")
|
||||
subprocess.run(["git", "-C", str(source), "update-index", clear_flag, "tool.sh"], check=True)
|
||||
subprocess.run(["git", "-C", str(source), "checkout", "--", "tool.sh"], check=True)
|
||||
|
||||
(source / "untracked.txt").write_text("edited\n")
|
||||
try:
|
||||
dependency.fetch(root / "build/llama.cpp")
|
||||
except dependency.DependencyError as error:
|
||||
assert "local edits" in str(error)
|
||||
else:
|
||||
raise AssertionError("dirty cached source must be refused")
|
||||
(source / "untracked.txt").unlink()
|
||||
(source / ".git/info/exclude").write_text("injected.cmake\n")
|
||||
(source / "injected.cmake").write_text("unmanifested input\n")
|
||||
try:
|
||||
dependency.fetch(root / "build/llama.cpp")
|
||||
except dependency.DependencyError as error:
|
||||
assert "unmanifested files" in str(error)
|
||||
else:
|
||||
raise AssertionError("ignored cached source input must be refused")
|
||||
|
||||
|
||||
def test_dependency_script_reports_the_locked_boundary_without_network() -> None:
|
||||
completed = subprocess.run(
|
||||
[sys.executable, str(SCRIPT), "inspect"],
|
||||
|
||||
Reference in New Issue
Block a user