diff --git a/CHANGELOG.md b/CHANGELOG.md index 872968b36..7bf8ad766 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ Semantic Versioning where the repository publishes a release. - Parsed `opencode.jsonc` as JSONC (stripping `//` and `/* */` comments outside string literals) in the reasoning-effort guard and its contract tests, instead of raw `json.loads`, which rejected the file the moment it carried its first explanatory comment (added for the `contextual-orchestrator` provider block) with `Expecting property name enclosed in double quotes`. Comment markers inside string values, such as the `$schema` URL, are left untouched. - Download the pinned `uv` 0.12.1 exporter from the official GitHub Releases URL instead of `releases.astral.sh`, which now returns HTTP 403 and blocks org-wide OpenCode `coverage-evidence`. The SHA-256 pin is unchanged. The opener may follow one hop onto `release-assets.githubusercontent.com` or `objects.githubusercontent.com` and still rejects every other host, userinfo, non-HTTPS scheme, and nondefault port (ContextualWisdomLab/.github#1109). +- Compared the trusted `uv` executable's post-install `--version` output against the real GitHub Releases build's full string, `uv 0.12.1 (x86_64-unknown-linux-gnu)`, instead of the bare `uv 0.12.1` the prior check required; the genuine release binary always prints the target triple, so every installation was failing the pin check immediately after the archive download itself was fixed (ContextualWisdomLab/.github#1109). - Excluded relative `-r` and `--requirement` referrers from generated flat base-lock publication while retaining bounded include syntax diagnostics and discovering independently complete direct `.txt` children of `requirements` directories. - Refused a conflict-scope repository root whose immediate parent is a symbolic link, so a swapped parent cannot redirect the canonical worktree after the last-component check (CWE-367). - Bounded the Strix quality self-test's deterministic timeout fixtures to 3-second process and 5-second fake-sleep budgets so exact-head policy evidence completes inside the existing job limit without changing production Strix scanner timeouts, providers, credentials, or review semantics. diff --git a/scripts/ci/materialize_base_python_requirements.py b/scripts/ci/materialize_base_python_requirements.py index 4249f16be..b16d4c745 100755 --- a/scripts/ci/materialize_base_python_requirements.py +++ b/scripts/ci/materialize_base_python_requirements.py @@ -38,6 +38,8 @@ UV_SHA256_HASH_RE = re.compile(r"--hash=sha256:[0-9a-fA-F]{64}") UV_EXPORT_TIMEOUT_SECONDS = 120 TRUSTED_UV_VERSION = "0.12.1" +TRUSTED_UV_TARGET_TRIPLE = "x86_64-unknown-linux-gnu" +TRUSTED_UV_VERSION_OUTPUT = f"uv {TRUSTED_UV_VERSION} ({TRUSTED_UV_TARGET_TRIPLE})" TRUSTED_UV_ARCHIVE_URL = ( "https://github.com/astral-sh/uv/releases/download/0.12.1/" "uv-x86_64-unknown-linux-gnu.tar.gz" @@ -381,7 +383,7 @@ def _install_trusted_uv() -> str: f"trusted uv executable verification failed: {type(exc).__name__}" ) from exc observed = completed.stdout.decode("utf-8", errors="replace").strip() - if completed.returncode != 0 or observed != f"uv {TRUSTED_UV_VERSION}": + if completed.returncode != 0 or observed != TRUSTED_UV_VERSION_OUTPUT: raise RuntimeError( "trusted uv executable reported an unexpected version or exit status" ) diff --git a/tests/test_materialize_base_python_requirements.py b/tests/test_materialize_base_python_requirements.py index cc457748b..5bc56ed8f 100644 --- a/tests/test_materialize_base_python_requirements.py +++ b/tests/test_materialize_base_python_requirements.py @@ -724,7 +724,9 @@ def test_install_trusted_uv_verifies_version_and_caches_path( def verify(*_args: object, **_kwargs: object) -> subprocess.CompletedProcess[bytes]: nonlocal calls calls += 1 - return subprocess.CompletedProcess([], 0, b"uv 0.12.1\n", b"") + return subprocess.CompletedProcess( + [], 0, b"uv 0.12.1 (x86_64-unknown-linux-gnu)\n", b"" + ) monkeypatch.setattr(materializer.subprocess, "run", verify) @@ -773,8 +775,16 @@ def fail(*_args: object, **_kwargs: object) -> None: @pytest.mark.parametrize( "completed", [ - subprocess.CompletedProcess([], 0, b"uv 0.12.0\n", b""), - subprocess.CompletedProcess([], 1, b"uv 0.12.1\n", b"failed"), + subprocess.CompletedProcess( + [], 0, b"uv 0.12.0 (x86_64-unknown-linux-gnu)\n", b"" + ), + subprocess.CompletedProcess( + [], 1, b"uv 0.12.1 (x86_64-unknown-linux-gnu)\n", b"failed" + ), + subprocess.CompletedProcess([], 0, b"uv 0.12.1\n", b""), + subprocess.CompletedProcess( + [], 0, b"uv 0.12.1 (aarch64-unknown-linux-gnu)\n", b"" + ), ], ) def test_install_trusted_uv_rejects_wrong_version_or_exit_status(