Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

88 changes: 66 additions & 22 deletions scripts/validate_sdk_pin.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,71 @@
#!/usr/bin/env python3
"""Fail closed unless Gate_SDK pin matches the immutable constellation SHA."""
"""Fail closed unless Gate_SDK is pinned to the moving major tag.

Policy (CEG#266 / PR #263): constellation-node-sdk tracks ``Quantum-L9/Gate_SDK@v1``.
Manifests name the major tag. poetry.lock records that tag as ``reference`` and
the resolved object as ``resolved_reference``.
"""

from __future__ import annotations

import re
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
PIN = "69c6c67060b08440734a61473c03663423709964"
errors: list[str] = []

for rel in ["pyproject.toml", "requirements.txt", "poetry.lock"]:
path = ROOT / rel
if not path.exists():
continue
text = path.read_text()
if "Quantum-L9/Gate_SDK" not in text:
errors.append(f"{rel}: missing Quantum-L9")
if PIN not in text:
errors.append(f"{rel}: missing pin")
if "cryptoxdog/Gate_SDK" in text:
errors.append(f"{rel}: cryptoxdog remains")

if errors:
print("FAIL")
print("\n".join(errors))
raise SystemExit(1)

print("PASS CEG pin", PIN)
MAJOR_TAG = "v1"
CANONICAL_REPO = "Quantum-L9/Gate_SDK"
FORBIDDEN_FORK = "cryptoxdog/Gate_SDK"
SHA_RE = re.compile(r"\b[0-9a-f]{40}\b")
LOCK_REFERENCE_RE = re.compile(
r'name = "constellation-node-sdk".*?\[package\.source\].*?'
r'reference = "([^"]+)".*?resolved_reference = "([0-9a-f]{40})"',
re.DOTALL,
)


def check_text(rel: str, text: str) -> list[str]:

Check failure on line 26 in scripts/validate_sdk_pin.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this function to reduce its Cognitive Complexity from 17 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=Quantum-L9_Cognitive.Engine.Graphs&issues=AaC6DD88TpzexTo1TS9S&open=AaC6DD88TpzexTo1TS9S&pullRequest=282
errors: list[str] = []
if CANONICAL_REPO not in text:
errors.append(f"{rel}: missing {CANONICAL_REPO}")
if FORBIDDEN_FORK in text:
errors.append(f"{rel}: {FORBIDDEN_FORK} remains")
if rel == "poetry.lock":
match = LOCK_REFERENCE_RE.search(text)
if match is None:
errors.append(f"{rel}: constellation-node-sdk source block missing")
else:
reference, resolved = match.group(1), match.group(2)
if reference != MAJOR_TAG:
errors.append(f"{rel}: reference={reference!r} (want {MAJOR_TAG!r})")
if not SHA_RE.fullmatch(resolved):
errors.append(f"{rel}: resolved_reference is not a SHA")
Comment on lines +19 to +41
else:
if MAJOR_TAG not in text:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Compare the SDK tag exactly in each manifest

When either manifest uses a revision such as v10 or v1-malicious, this substring check still finds v1 and returns no error, so the repository-tree test approves a dependency that violates the required @v1 policy. Parse the constellation-node-sdk declaration and compare its revision exactly instead of searching the whole file.

Useful? React with 👍 / 👎.

errors.append(f"{rel}: missing moving major tag {MAJOR_TAG}")
if SHA_RE.search(text):
errors.append(f"{rel}: immutable SHA pin leftover")
return errors


def check_tree(root: Path) -> list[str]:
errors: list[str] = []
for rel in ("pyproject.toml", "requirements.txt", "poetry.lock"):
path = root / rel
if not path.exists():
continue
errors.extend(check_text(rel, path.read_text(encoding="utf-8")))
return errors


def main() -> int:
errors = check_tree(ROOT)
if errors:
print("FAIL")
print("\n".join(errors))
return 1
print(f"PASS CEG pin {CANONICAL_REPO}@{MAJOR_TAG}")
return 0


if __name__ == "__main__":
raise SystemExit(main())
2 changes: 1 addition & 1 deletion tests/unit/test_node_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ def test_max_attachments_without_schemes_is_rejected() -> None:


def test_sdk_default_attachment_caps_construct() -> None:
"""Pinned SDK (69c6c67 = main a0827f2 + verifying-keys env fix) ships mutually valid default attachment/packet caps.
"""Pinned SDK (@v1 / 1.1.0) ships mutually valid default attachment/packet caps.

Earlier pins (a770e853) defaulted max_attachment_size_bytes above
max_packet_bytes and failed closed on a bare construct. The current pin
Expand Down
64 changes: 64 additions & 0 deletions tests/unit/test_validate_sdk_pin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"""Unit tests — moving-major Gate_SDK pin validator (CEG#266)."""

from __future__ import annotations

import importlib.util
from pathlib import Path

import pytest

_ROOT = Path(__file__).resolve().parents[2]
_SPEC = importlib.util.spec_from_file_location(
"validate_sdk_pin",
_ROOT / "scripts" / "validate_sdk_pin.py",
)
if _SPEC is None:
raise RuntimeError("validate_sdk_pin.py did not load")
if _SPEC.loader is None:
raise RuntimeError("validate_sdk_pin.py has no loader")
_mod = importlib.util.module_from_spec(_SPEC)
_SPEC.loader.exec_module(_mod)
MAJOR_TAG = _mod.MAJOR_TAG
check_text = _mod.check_text
check_tree = _mod.check_tree


@pytest.mark.unit
def test_manifests_accept_major_tag() -> None:
pyproject = 'constellation-node-sdk = {git = "https://github.com/Quantum-L9/Gate_SDK.git", rev = "v1"}\n'
requirements = "constellation-node-sdk @ git+https://github.com/Quantum-L9/Gate_SDK.git@v1\n"
assert check_text("pyproject.toml", pyproject) == []
assert check_text("requirements.txt", requirements) == []


@pytest.mark.unit
def test_manifests_reject_sha_and_fork() -> None:
sha = "69c6c67060b08440734a61473c03663423709964"
text = f'constellation-node-sdk = {{git = "https://github.com/cryptoxdog/Gate_SDK.git", rev = "{sha}"}}\n'
errors = check_text("pyproject.toml", text)
assert any("cryptoxdog" in item for item in errors)
assert any("SHA" in item for item in errors)
assert any("Quantum-L9" in item for item in errors)


@pytest.mark.unit
def test_lock_requires_tag_reference_and_resolved_sha() -> None:
lock = (
'name = "constellation-node-sdk"\n'
'version = "1.1.0"\n'
"[package.source]\n"
'type = "git"\n'
'url = "https://github.com/Quantum-L9/Gate_SDK.git"\n'
'reference = "v1"\n'
'resolved_reference = "e9f829f982110be13752da8f18c7a9692e8ed908"\n'
)
assert check_text("poetry.lock", lock) == []
stale = lock.replace('reference = "v1"', 'reference = "69c6c67060b08440734a61473c03663423709964"')
assert check_text("poetry.lock", stale)


@pytest.mark.unit
def test_repo_tree_matches_v1_policy() -> None:
errors = check_tree(_ROOT)
assert errors == [], errors
assert MAJOR_TAG == "v1"
Loading