Skip to content
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<!-- CWL-ENTRY -->
> **Agents: read the master context FIRST.** Before any work, read [`docs/CWL-MASTER-CONTEXT.md`](docs/CWL-MASTER-CONTEXT.md) (mission · naruon-as-platform + inter-component UML · cross-cutting disciplines · conventions · roadmap · current state), the live **GitHub Project #1** <https://github.com/orgs/ContextualWisdomLab/projects/1> (work/roadmap source of truth), the full spec **ContextualWisdomLab/naruon#974**, and operate the Project per [`docs/agent-github-project-protocol.md`](docs/agent-github-project-protocol.md). The repo/Project — not any private agent memory — is the source of truth.

Materialize accepts only exact SHA-256 pins or a bounded relative `-r` include (no `.`/`..`); a lone `--require-hashes` directive is not trust evidence. See [`docs/doctoring/hourly-nvidia-nim-autofix.md`](docs/doctoring/hourly-nvidia-nim-autofix.md).
Materialize syntax may recognize a bounded relative `-r` include (no `.`/`..`); flat publication admits only standalone exact SHA-256 pins. A lone `--require-hashes` directive is not trust evidence. See [`docs/doctoring/trusted-uv-flat-include-isolation.md`](docs/doctoring/trusted-uv-flat-include-isolation.md).
Conflict-scope roots fail closed when the immediate parent directory is a symbolic link.
OriginWeave hourly NVIDIA NIM repair is a thin caller at minute 10. See [`docs/doctoring/originweave-hourly-review-caller.md`](docs/doctoring/originweave-hourly-review-caller.md).
nonnest2 hourly NVIDIA NIM repair is a thin caller at minute 16. See [`docs/doctoring/nonnest2-hourly-review-caller.md`](docs/doctoring/nonnest2-hourly-review-caller.md).
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,4 @@ Semantic Versioning where the repository publishes a release.
- Added fast-mlsirm operational documentation for the hourly RCA loop, psychometric scientific gates, Rust ownership, bounded retry cadence, credential isolation, modular reuse, rollback, and APA 7 references.
- Documented the ordinary and conflict repair write-scope parity, ignored-path and symlink inventory, Git-control-file denial, hook suppression, explicit push destination, RED/GREEN evidence, operator response, and local-versus-protected evidence boundary.
- Documented the review-authentication boundary that excludes autonomous writer control-plane paths from review-derived file authority, its test-first Strix security evidence, exact-head coverage contract, and rollback prohibition.
- Documented why pip-relative include syntax cannot cross the generated flat-lock publication boundary and the exact-head regression evidence required before the policy can change.
13 changes: 9 additions & 4 deletions scripts/ci/materialize_base_python_requirements.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
}
)
TRUSTED_UV_FINAL_HOSTS = frozenset({TRUSTED_UV_RELEASE_HOST, *TRUSTED_UV_ASSET_HOSTS})
TRUSTED_UV_DOWNLOAD_USER_AGENT = "cwl-trusted-uv-materializer/1"
TRUSTED_UV_ARCHIVE_SHA256 = (
"90b2f223fb69d19db49e117da601f64978593417988530aa733d456141b4bcbb"
)
Expand Down Expand Up @@ -302,12 +303,16 @@ def _download_trusted_uv_archive() -> bytes:
"""Download the fixed uv release archive through one HTTPS trust boundary."""
_install_trusted_uv_url_opener()
try:
# Keep the audited URL literal at the network sink so static analysis can
# prove that neither user data nor repository content selects a scheme,
# host, path, query, fragment, method, or request header.
with urllib.request.urlopen( # nosemgrep: python.lang.security.audit.dynamic-urllib-use-detected.dynamic-urllib-use-detected # nosec B310
# Keep the audited URL literal and static request header in this trusted
# function so neither user data nor repository content selects the
# scheme, host, path, query, fragment, method, or request header.
request = urllib.request.Request(
"https://github.com/astral-sh/uv/releases/download/0.12.1/"
"uv-x86_64-unknown-linux-gnu.tar.gz",
headers={"User-Agent": TRUSTED_UV_DOWNLOAD_USER_AGENT},
)
with urllib.request.urlopen( # nosemgrep: python.lang.security.audit.dynamic-urllib-use-detected.dynamic-urllib-use-detected # nosec B310
request,
timeout=TRUSTED_UV_DOWNLOAD_TIMEOUT_SECONDS,
) as response:
if not _is_trusted_uv_final_origin(response.geturl()):
Expand Down
45 changes: 30 additions & 15 deletions tests/test_trusted_uv_download_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,34 +53,49 @@ def _urlopen_calls() -> list[ast.Call]:
]


def test_urlopen_receives_one_literal_https_release_url() -> None:
"""Static analysis can prove repository or user data never selects the URL."""
def test_urlopen_receives_one_static_release_request() -> None:
"""Static analysis can prove repository data never selects the request."""
calls = _urlopen_calls()

assert len(calls) == 1
assert len(calls[0].args) == 1
url_argument = calls[0].args[0]
assert isinstance(url_argument, ast.Constant)
assert isinstance(url_argument.value, str)
assert url_argument.value == _EXPECTED_URL


def test_literal_network_sink_matches_the_documented_release_constant() -> None:
"""The scanner-friendly sink literal cannot drift from the release identity."""
assert _assigned_literal("TRUSTED_UV_ARCHIVE_URL") == _EXPECTED_URL

request_argument = calls[0].args[0]
assert isinstance(request_argument, ast.Name)
assert request_argument.id == "request"

def test_downloader_never_constructs_a_dynamic_request_object() -> None:
"""The audited downloader cannot hide a dynamic URL inside ``Request``."""
request_calls = [
node
for node in ast.walk(_download_function())
if isinstance(node, ast.Call)
and isinstance(node.func, ast.Attribute)
and node.func.attr == "Request"
]
assert len(request_calls) == 1
assert len(request_calls[0].args) == 1
url_argument = request_calls[0].args[0]
assert isinstance(url_argument, ast.Constant)
assert isinstance(url_argument.value, str)
assert url_argument.value == _EXPECTED_URL

headers = next(
keyword.value
for keyword in request_calls[0].keywords
if keyword.arg == "headers"
)
assert isinstance(headers, ast.Dict)
assert len(headers.keys) == 1
assert isinstance(headers.keys[0], ast.Constant)
assert headers.keys[0].value == "User-Agent"
assert isinstance(headers.values[0], ast.Name)
assert headers.values[0].id == "TRUSTED_UV_DOWNLOAD_USER_AGENT"
assert _assigned_literal("TRUSTED_UV_DOWNLOAD_USER_AGENT") == (
"cwl-trusted-uv-materializer/1"
)

assert request_calls == []

def test_literal_network_sink_matches_the_documented_release_constant() -> None:
"""The scanner-friendly sink literal cannot drift from the release identity."""
assert _assigned_literal("TRUSTED_UV_ARCHIVE_URL") == _EXPECTED_URL


def test_literal_urlopen_sink_has_one_scoped_semgrep_suppression() -> None:
Expand Down
90 changes: 89 additions & 1 deletion tests/test_uv_redirect_boundary.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
"""Behavioral contracts for the trusted uv download redirect boundary."""
"""Behavioral contracts for trusted uv download and flat-lock boundaries."""

from __future__ import annotations

import urllib.request
from collections.abc import Iterator
from pathlib import Path

import pytest

Expand Down Expand Up @@ -181,3 +182,90 @@ def fake_install_opener(opener: object) -> None:
assert isinstance(handlers[0], urllib.request.ProxyHandler)
assert handlers[0].proxies == {}
assert isinstance(handlers[1], materializer._TrustedUvReleaseAssetRedirects)


@pytest.mark.parametrize(
("content", "expected"),
[
(b"", False),
(b"--require-hashes\n", False),
(b"-r requirements-other.txt\n", False),
(b"--requirement requirements-other.txt\n", False),
(b"demo==1 --hash=sha256:" + (b"a" * 64) + b"\n", True),
],
)
def test_flat_lock_policy_requires_a_standalone_exact_hash_closure(
content: bytes,
expected: bool,
) -> None:
"""Generated flat lock names cannot preserve source-relative includes."""
assert materializer._is_flat_materializable_lock(content) is expected


def test_base_lock_discovery_excludes_relative_include_files(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""A relative include never crosses from the exact base into flat output."""
tree = (
b"100644 blob "
+ (b"0" * 40)
+ b"\trequirements-other.txt\0"
+ b"100644 blob "
+ (b"1" * 40)
+ b"\trequirements.txt\0"
)
pinned = b"demo==1 --hash=sha256:" + (b"a" * 64) + b"\n"

def fake_git(_repo_root: Path, *args: str) -> bytes:
if args[0] == "ls-tree":
return tree
if args[0] == "show" and args[-1].endswith(":requirements-other.txt"):
return pinned
if args[0] == "show" and args[-1].endswith(":requirements.txt"):
return b"-r requirements-other.txt\n"
raise AssertionError(args)

monkeypatch.setattr(materializer, "_git", fake_git)

assert materializer.base_hash_locks(tmp_path, "a" * 40) == [
("requirements-other.txt", pinned)
]


def test_base_lock_discovery_publishes_nested_requirements_directory_locks(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""Path-aware discovery still publishes standalone ``requirements/ci.txt``."""
tree = (
b"100644 blob "
+ (b"0" * 40)
+ b"\trequirements/ci.txt\0"
+ b"100644 blob "
+ (b"1" * 40)
+ b"\tservice/requirements/package.txt\0"
+ b"100644 blob "
+ (b"2" * 40)
+ b"\trequirements.txt\0"
)
ci_lock = b"ci-demo==1 --hash=sha256:" + (b"a" * 64) + b"\n"
package_lock = b"service-demo==1 --hash=sha256:" + (b"b" * 64) + b"\n"

def fake_git(_repo_root: Path, *args: str) -> bytes:
if args[0] == "ls-tree":
return tree
if args[0] == "show" and args[-1].endswith(":requirements/ci.txt"):
return ci_lock
if args[0] == "show" and args[-1].endswith(":service/requirements/package.txt"):
return package_lock
if args[0] == "show" and args[-1].endswith(":requirements.txt"):
return b"-r requirements/ci.txt\n"
raise AssertionError(args)

monkeypatch.setattr(materializer, "_git", fake_git)

assert materializer.base_hash_locks(tmp_path, "a" * 40) == [
("requirements/ci.txt", ci_lock),
("service/requirements/package.txt", package_lock),
]
Loading