Publish curated ITWorx_MCP_Hub source from ce7b7c333c5b287456ad4a19c90a4e9b4ee02dcf

This commit is contained in:
Public Source Publisher committed 2026-10-14 05:50:26 +00:00
1 parent ad97836d49
commit 020282a4b5
6 files changed
+94 -24

No files matched your search

+1 -1
View File
@@ -1,3 +1,3 @@
# Public source export # Public source export
This source snapshot was generated from the private canonical repository at revision `d53d0423bb4ff61be689fc6088ee05ecbb69d8f6`. It contains no private Git history or operational evidence. Changes are published from the canonical repository. This source snapshot was generated from the private canonical repository at revision `ce7b7c333c5b287456ad4a19c90a4e9b4ee02dcf`. It contains no private Git history or operational evidence. Changes are published from the canonical repository.
+8 -8
View File
@@ -1,6 +1,6 @@
{ {
"schemaVersion": 1, "schemaVersion": 1,
"sourceRevision": "d53d0423bb4ff61be689fc6088ee05ecbb69d8f6", "sourceRevision": "ce7b7c333c5b287456ad4a19c90a4e9b4ee02dcf",
"files": [ "files": [
{ {
"path": ".dockerignore", "path": ".dockerignore",
@@ -2044,13 +2044,13 @@
}, },
{ {
"path": "infrastructure/images/contextforge/candidate/locks.json", "path": "infrastructure/images/contextforge/candidate/locks.json",
"sha256": "28029214650a4d864ff1f6cfdecf4f2c2e1f8438e3f792b35ce52fda90d2d896", "sha256": "75b7f31fdf84cf390095c4c13123b64a5270b25a5d7eb6018077544101e0b697",
"bytes": 3132 "bytes": 3132
}, },
{ {
"path": "infrastructure/images/contextforge/candidate/production-requirements.lock", "path": "infrastructure/images/contextforge/candidate/production-requirements.lock",
"sha256": "daaa815ef1ce2e58c60d9bac840f5754a12eab4b18642713e197d3f5f9467c30", "sha256": "3a1b599d2487bd9f1aaf6f2be0f65b6db17da5847a123e905c5e5337a3e87f76",
"bytes": 131433 "bytes": 131299
}, },
{ {
"path": "infrastructure/images/contextforge/compat-image.env", "path": "infrastructure/images/contextforge/compat-image.env",
@@ -2444,8 +2444,8 @@
}, },
{ {
"path": "scripts/contextforge_candidate_recipe.py", "path": "scripts/contextforge_candidate_recipe.py",
"sha256": "d33f5c11d10ab2987128adc264a20ef4dc9913b80c9e55563a1908b2c7154962", "sha256": "4faf2c30223e8e1b5015474da46044e72d6edeb3653c57679d75aa504b2e2a2d",
"bytes": 21090 "bytes": 22518
}, },
{ {
"path": "scripts/contextforge_runtime_contract.py", "path": "scripts/contextforge_runtime_contract.py",
@@ -3129,8 +3129,8 @@
}, },
{ {
"path": "tests/test_contextforge_candidate_recipe.py", "path": "tests/test_contextforge_candidate_recipe.py",
"sha256": "379a240d4ca41dcd04e514fa721c692cd5b6cf23d0d5945f99039b24e2ef3474", "sha256": "f96a0b665c2ffb507da80f26d44b04f5fa6e7384dfe9639b8549f8a866e3da1b",
"bytes": 17265 "bytes": 19894
}, },
{ {
"path": "tests/test_contextforge_compat_image_contract.py", "path": "tests/test_contextforge_compat_image_contract.py",
@@ -52,7 +52,7 @@
"python": "3.12", "python": "3.12",
"requirements": { "requirements": {
"build-tools.lock": "4ba5f91f6473fc4fc9971b2353629203099d9409f537895972e60a65890af02f", "build-tools.lock": "4ba5f91f6473fc4fc9971b2353629203099d9409f537895972e60a65890af02f",
"production-requirements.lock": "daaa815ef1ce2e58c60d9bac840f5754a12eab4b18642713e197d3f5f9467c30" "production-requirements.lock": "3a1b599d2487bd9f1aaf6f2be0f65b6db17da5847a123e905c5e5337a3e87f76"
}, },
"schema": "itworx.contextforge-candidate-locks/v1", "schema": "itworx.contextforge-candidate-locks/v1",
"upstreamCommit": "1e58a0434a78bbdbe1e975abeb0bed1043ff14c1", "upstreamCommit": "1e58a0434a78bbdbe1e975abeb0bed1043ff14c1",
@@ -896,8 +896,6 @@ psycopg-binary==3.3.4 ; implementation_name != 'pypy' \
--hash=sha256:eb05ee1c2b817d27c537333224c9e83c7afb86fe7296ba970990068baf819b16 \ --hash=sha256:eb05ee1c2b817d27c537333224c9e83c7afb86fe7296ba970990068baf819b16 \
--hash=sha256:ee17a2cf4943cde261adfad1bbc5bf38d6b3776d7afff74c7cabcbeaeb08c260 \ --hash=sha256:ee17a2cf4943cde261adfad1bbc5bf38d6b3776d7afff74c7cabcbeaeb08c260 \
--hash=sha256:fbd1d4ed566895ad2d3bf4ddfd8bae90026930ddf29df3b9d91d32c8c47866a7 --hash=sha256:fbd1d4ed566895ad2d3bf4ddfd8bae90026930ddf29df3b9d91d32c8c47866a7
psycopg-c==3.3.4 ; implementation_name != 'pypy' \
--hash=sha256:ed8106128b2d04359c185fc9641b4409abfce4d0b6fb1d1ff6800646e27f1a22
pycparser==3.0 ; implementation_name != 'PyPy' \ pycparser==3.0 ; implementation_name != 'PyPy' \
--hash=sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29 \ --hash=sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29 \
--hash=sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992 --hash=sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992
+24 -3
View File
@@ -113,6 +113,18 @@ def _table_range(text: str, table: str) -> tuple[int, int, str]:
return start, end, text[start:end] return start, end, text[start:end]
def binary_postgres_pyproject(source_text: str) -> str:
"""Select the pinned binary adapter without requesting a source-only C build."""
import tomllib
source = tomllib.loads(source_text)
postgres = source.get("project", {}).get("optional-dependencies", {}).get("postgres")
original = '"psycopg[c,binary]>=3.3.4"'
if postgres != ["psycopg[c,binary]>=3.3.4"] or source_text.count(original) != 1:
raise CandidateRecipeError("upstream PostgreSQL adapter contract changed")
return source_text.replace(original, '"psycopg[binary]>=3.3.4"', 1)
def candidate_pyproject(source_text: str) -> str: def candidate_pyproject(source_text: str) -> str:
"""Apply the narrowly scoped candidate-only dependency resolution policy.""" """Apply the narrowly scoped candidate-only dependency resolution policy."""
try: try:
@@ -137,7 +149,7 @@ def candidate_pyproject(source_text: str) -> str:
}: }:
raise CandidateRecipeError("upstream uv source override shape changed") raise CandidateRecipeError("upstream uv source override shape changed")
text = source_text.replace("\r\n", "\n") text = binary_postgres_pyproject(source_text).replace("\r\n", "\n")
source_start, source_end, source_table = _table_range(text, "tool.uv.sources") source_start, source_end, source_table = _table_range(text, "tool.uv.sources")
source_lines = source_table.strip().splitlines() source_lines = source_table.strip().splitlines()
expected_source_lines = [ expected_source_lines = [
@@ -319,6 +331,8 @@ def _read_lock_manifest() -> dict[str, Any]:
payload = json.loads(_require_file(LOCK_MANIFEST).decode("utf-8")) payload = json.loads(_require_file(LOCK_MANIFEST).decode("utf-8"))
except (json.JSONDecodeError, UnicodeDecodeError) as exc: except (json.JSONDecodeError, UnicodeDecodeError) as exc:
raise CandidateRecipeError("candidate lock manifest is invalid JSON") from exc raise CandidateRecipeError("candidate lock manifest is invalid JSON") from exc
if not isinstance(payload, dict):
raise CandidateRecipeError("candidate lock manifest is not an object")
expected = _make_manifest( expected = _make_manifest(
source_hashes=SOURCE_HASHES, source_hashes=SOURCE_HASHES,
production_hash=str( production_hash=str(
@@ -337,6 +351,11 @@ def _read_lock_manifest() -> dict[str, Any]:
def verify_lock_contents(manifest: dict[str, Any]) -> None: def verify_lock_contents(manifest: dict[str, Any]) -> None:
production = _require_file(LOCK_DIR / "production-requirements.lock").decode("utf-8") production = _require_file(LOCK_DIR / "production-requirements.lock").decode("utf-8")
build_tools = _require_file(LOCK_DIR / "build-tools.lock").decode("utf-8") build_tools = _require_file(LOCK_DIR / "build-tools.lock").decode("utf-8")
if re.search(r"(?im)^psycopg-c==", production):
raise CandidateRecipeError("candidate lock contains a source-only PostgreSQL adapter")
for name in ("psycopg", "psycopg-binary"):
if not re.search(rf"(?im)^{name}==3\.3\.4(?:[ ;\\]|$)", production):
raise CandidateRecipeError("candidate PostgreSQL binary adapter pin changed")
for requirement in CONSTRAINTS: for requirement in CONSTRAINTS:
name, version = requirement.split("==", 1) name, version = requirement.split("==", 1)
match = re.search(rf"(?im)^{re.escape(name)}==([^ ;\\]+)", production) match = re.search(rf"(?im)^{re.escape(name)}==([^ ;\\]+)", production)
@@ -404,7 +423,7 @@ def transform_containerfile(containerfile: bytes, expected_hash: str | None = No
raise CandidateRecipeError("upstream dependency-copy anchor count changed") raise CandidateRecipeError("upstream dependency-copy anchor count changed")
text = text.replace( text = text.replace(
LOCK_COPY_ANCHOR, LOCK_COPY_ANCHOR,
LOCK_COPY_ANCHOR "COPY pyproject.itworx-candidate.toml /app/pyproject.toml\n"
+ "COPY contextforge-candidate-production-requirements.txt /tmp/contextforge-production-requirements.txt\n" + "COPY contextforge-candidate-production-requirements.txt /tmp/contextforge-production-requirements.txt\n"
+ "COPY contextforge-candidate-build-tools.txt /tmp/contextforge-build-tools.txt\n", + "COPY contextforge-candidate-build-tools.txt /tmp/contextforge-build-tools.txt\n",
1, 1,
@@ -422,7 +441,7 @@ def transform_containerfile(containerfile: bytes, expected_hash: str | None = No
&& /app/.venv/bin/python -m pip install --disable-pip-version-check --no-cache-dir --require-hashes --only-binary=:all: -r /tmp/contextforge-production-requirements.txt \\ && /app/.venv/bin/python -m pip install --disable-pip-version-check --no-cache-dir --require-hashes --only-binary=:all: -r /tmp/contextforge-production-requirements.txt \\
&& /app/.venv/bin/python -m pip install --disable-pip-version-check --no-cache-dir --no-deps --no-build-isolation ".[redis,postgres,observability,granian,plugins,llmchat]" \\ && /app/.venv/bin/python -m pip install --disable-pip-version-check --no-cache-dir --no-deps --no-build-isolation ".[redis,postgres,observability,granian,plugins,llmchat]" \\
&& /app/.venv/bin/python -m pip check \\ && /app/.venv/bin/python -m pip check \\
&& /app/.venv/bin/python -c "import importlib.metadata as md; assert md.version('mcp') == '1.30.0'; assert md.version('PyJWT') == '2.15.0'; assert md.version('urllib3') == '2.8.0'" \\ && /app/.venv/bin/python -c "import importlib.metadata as md; import psycopg; assert psycopg.pq.__impl__ == 'binary'; assert md.version('psycopg') == md.version('psycopg-binary') == '3.3.4'; assert md.version('mcp') == '1.30.0'; assert md.version('PyJWT') == '2.15.0'; assert md.version('urllib3') == '2.8.0'" \\
&& /app/.venv/bin/python -m pip uninstall --yes pip setuptools wheel \\ && /app/.venv/bin/python -m pip uninstall --yes pip setuptools wheel \\
&& (find /app/.venv -name "*.dist-info" -type d \\ && (find /app/.venv -name "*.dist-info" -type d \\
\\( -name "pip-*" -o -name "setuptools-*" -o -name "wheel-*" \\) \\ \\( -name "pip-*" -o -name "setuptools-*" -o -name "wheel-*" \\) \\
@@ -440,10 +459,12 @@ def prepare_source(source_dir: Path) -> None:
manifest = _read_lock_manifest() manifest = _read_lock_manifest()
verify_lock_contents(manifest) verify_lock_contents(manifest)
transformed = transform_containerfile(source["Containerfile"]) transformed = transform_containerfile(source["Containerfile"])
project = binary_postgres_pyproject(source["pyproject.toml"].decode("utf-8"))
for source_name, target_name in LOCK_OUTPUT_NAMES.items(): for source_name, target_name in LOCK_OUTPUT_NAMES.items():
_write_atomic(source_dir / target_name, _require_file(LOCK_DIR / source_name)) _write_atomic(source_dir / target_name, _require_file(LOCK_DIR / source_name))
_write_atomic(source_dir / "Containerfile.itworx-candidate", transformed) _write_atomic(source_dir / "Containerfile.itworx-candidate", transformed)
_write_atomic(source_dir / "pyproject.itworx-candidate.toml", project.encode("utf-8"))
def print_build_args() -> None: def print_build_args() -> None:
+60 -9
View File
@@ -43,7 +43,7 @@ def _source_fixture(tmp_path: Path, containerfile: bytes) -> tuple[Path, dict[st
source.mkdir() source.mkdir()
contents = { contents = {
"Containerfile": containerfile, "Containerfile": containerfile,
"pyproject.toml": b"[project]\nname='fixture'\n", "pyproject.toml": b'[project]\nname="fixture"\n[project.optional-dependencies]\npostgres=["psycopg[c,binary]>=3.3.4"]\n',
"uv.lock": b"version = 1\n", "uv.lock": b"version = 1\n",
} }
expected = {name: _hash(value) for name, value in contents.items()} expected = {name: _hash(value) for name, value in contents.items()}
@@ -111,6 +111,9 @@ compliance-reference-server = { path = "mcp-servers/python/compliance_reference_
name = "contextforge" name = "contextforge"
dependencies = ["httpx>=0.27"] dependencies = ["httpx>=0.27"]
[project.optional-dependencies]
postgres = ["psycopg[c,binary]>=3.3.4"]
[dependency-groups] [dependency-groups]
dev = ["pytest>=8"] dev = ["pytest>=8"]
""" """
@@ -122,6 +125,7 @@ dev = ["pytest>=8"]
assert parsed["project"] == { assert parsed["project"] == {
"name": "contextforge", "name": "contextforge",
"dependencies": ["httpx>=0.27"], "dependencies": ["httpx>=0.27"],
"optional-dependencies": {"postgres": ["psycopg[binary]>=3.3.4"]},
} }
assert "sources" not in parsed["tool"]["uv"] assert "sources" not in parsed["tool"]["uv"]
assert parsed["tool"]["uv"]["exclude-newer"] == "2026-09-22T00:00:00Z" assert parsed["tool"]["uv"]["exclude-newer"] == "2026-09-22T00:00:00Z"
@@ -134,12 +138,36 @@ dev = ["pytest>=8"]
assert "dev" not in parsed["dependency-groups"] assert "dev" not in parsed["dependency-groups"]
def test_runtime_lock_rejects_source_only_postgres_adapter(monkeypatch) -> None:
manifest = recipe._read_lock_manifest()
original = recipe._require_file
def read(path):
data = original(path)
return data + b"\npsycopg-c==3.3.4\n" if path == recipe.PRODUCTION_LOCK else data
monkeypatch.setattr(recipe, "_require_file", read)
with pytest.raises(recipe.CandidateRecipeError, match="source-only PostgreSQL adapter"):
recipe.verify_lock_contents(manifest)
@pytest.mark.parametrize("value", ["psycopg[c]>=3.3.4", "psycopg[c,binary]>=3.3.5"])
def test_binary_adapter_policy_denies_unreviewed_upstream_drift(value) -> None:
source = f'[project.optional-dependencies]\npostgres=["{value}"]\n'
with pytest.raises(
recipe.CandidateRecipeError, match="upstream PostgreSQL adapter contract changed"
):
recipe.binary_postgres_pyproject(source)
def test_candidate_transform_is_exact_and_uses_hash_locked_runtime_install() -> None: def test_candidate_transform_is_exact_and_uses_hash_locked_runtime_install() -> None:
original = _containerfile_fixture() original = _containerfile_fixture()
transformed = recipe.transform_containerfile(original, expected_hash=_hash(original)).decode() transformed = recipe.transform_containerfile(original, expected_hash=_hash(original)).decode()
assert transformed.count("COPY contextforge-candidate-production-requirements.txt") == 1 assert transformed.count("COPY contextforge-candidate-production-requirements.txt") == 1
assert transformed.count("COPY contextforge-candidate-build-tools.txt") == 1 assert transformed.count("COPY contextforge-candidate-build-tools.txt") == 1
assert "COPY pyproject.itworx-candidate.toml /app/pyproject.toml" in transformed
assert "assert psycopg.pq.__impl__ == 'binary'" in transformed
assert ( assert (
"--require-hashes --only-binary=:all: -r /tmp/contextforge-production-requirements.txt" "--require-hashes --only-binary=:all: -r /tmp/contextforge-production-requirements.txt"
in transformed in transformed
@@ -213,6 +241,10 @@ def test_prepare_copies_verified_locks_and_fails_before_writing_on_missing_lock(
recipe.prepare_source(source) recipe.prepare_source(source)
assert (source / "Containerfile.itworx-candidate").exists() assert (source / "Containerfile.itworx-candidate").exists()
assert _hash((source / "pyproject.toml").read_bytes()) == source_hashes["pyproject.toml"]
derived = (source / "pyproject.itworx-candidate.toml").read_text()
assert '"psycopg[binary]>=3.3.4"' in derived
assert "psycopg[c,binary]" not in derived
for name, target in recipe.LOCK_OUTPUT_NAMES.items(): for name, target in recipe.LOCK_OUTPUT_NAMES.items():
assert (source / target).read_bytes() == (lock_dir / name).read_bytes() assert (source / target).read_bytes() == (lock_dir / name).read_bytes()
@@ -333,12 +365,14 @@ def test_frozen_base_evidence_matches_candidate_pins_and_repository_inputs() ->
assert evidence["status"] == "passed" assert evidence["status"] == "passed"
assert evidence["finalContextForgeCandidateBuilt"] is False assert evidence["finalContextForgeCandidateBuilt"] is False
assert evidence["sourceInputs"]["upstreamCommit"] == manifest["upstreamCommit"] assert evidence["sourceInputs"]["upstreamCommit"] == manifest["upstreamCommit"]
assert evidence["sourceInputs"]["ContainerfileSha256"] == manifest["upstreamFiles"][ assert (
"Containerfile" evidence["sourceInputs"]["ContainerfileSha256"]
] == manifest["upstreamFiles"]["Containerfile"]
assert evidence["sourceInputs"]["pyprojectTomlSha256"] == manifest["upstreamFiles"][ )
"pyproject.toml" assert (
] evidence["sourceInputs"]["pyprojectTomlSha256"]
== manifest["upstreamFiles"]["pyproject.toml"]
)
assert evidence["sourceInputs"]["uvLockSha256"] == manifest["upstreamFiles"]["uv.lock"] assert evidence["sourceInputs"]["uvLockSha256"] == manifest["upstreamFiles"]["uv.lock"]
assert set(evidence["hubInputsSha256"]) == { assert set(evidence["hubInputsSha256"]) == {
"scripts/contextforge_candidate_recipe.py", "scripts/contextforge_candidate_recipe.py",
@@ -350,9 +384,26 @@ def test_frozen_base_evidence_matches_candidate_pins_and_repository_inputs() ->
"infrastructure/images/contextforge/os-bases/Dockerfile.runtime", "infrastructure/images/contextforge/os-bases/Dockerfile.runtime",
"infrastructure/compose/docker-compose.autodeploy.yml", "infrastructure/compose/docker-compose.autodeploy.yml",
} }
assert evidence["hubInputsSha256"] == { # The published OS receipt is immutable historical evidence. A later,
name: _hash((ROOT / name).read_bytes()) for name in evidence["hubInputsSha256"] # explicit Python-only recipe delta binds its changed inputs separately.
delta = json.loads((ROOT / "evidence/WP-400/CF_POSTGRES_BINARY_RECIPE.json").read_text())
assert delta["schema"] == "itworx.contextforge-postgres-binary-recipe/v1"
assert delta["frozenBaseEvidenceSha256"] == _hash(evidence_path.read_bytes())
changed = {
"scripts/contextforge_candidate_recipe.py",
"infrastructure/images/contextforge/candidate/locks.json",
"infrastructure/images/contextforge/candidate/production-requirements.lock",
} }
assert set(delta["historicalInputsSha256"]) == changed
assert set(delta["candidateInputsSha256"]) == changed
assert delta["historicalInputsSha256"] == {
name: evidence["hubInputsSha256"][name] for name in changed
}
for name, historical_hash in evidence["hubInputsSha256"].items():
expected = delta["candidateInputsSha256"].get(name, historical_hash)
assert _hash((ROOT / name).read_bytes()) == expected
assert delta["finalCandidateBuilt"] is False
assert delta["policy"] == "psycopg[binary]==3.3.4; hash-locked wheels only"
for role, arg in (("builder", "UBI_BASE"), ("runtime", "UBI_MINIMAL")): for role, arg in (("builder", "UBI_BASE"), ("runtime", "UBI_MINIMAL")):
published = evidence["publishedBases"][role] published = evidence["publishedBases"][role]
locked = bases[arg] locked = bases[arg]